【独学】はじめてのWebプログラミング – 8.1 Webページ開発 1-①(Windows)

いよいよWebページの開発に入ります。
ここでは、みなさんご存じのTwitterに似たWebページを開発していきます。

本章での完成イメージは以下になります。
左側のアイコンが縦に並んでいる場所を「サイドメニュー」、中央のホーム以下の場所を「メインメニュー」と呼びます。

完成イメージ

事前準備

必要なフォルダを作成します。
Visual Studio Codeを開いて下さい。HTDOCSフォルダ内に、Twitterフォルダをつくります。

VSCode

さらにその中に、Viewsフォルダをつくります。

VSCode

次に、こちらから素材となるファイルをダウンロードします。
sample.zipという名前のファイルがダウンロードできます。

その中の3つのフォルダをコピーし、「C:\xampp\htdocs\Twitter\Views」フォルダ内に貼り付けます。

フォルダ

Visual Studio Code上では、以下のように見えていればOKです。

VSCode

HTMLの作成

HTMLを作成していきます。
Viewsフォルダ内に、「home.php」ファイルを追加します。

home.phpファイルに、以下のように書きます。

htdocs/Twitter/Views/home.php

<!DOCTYPE html>
<html>
    <lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>Twitter</title>
    </head>
    <body>
        ホーム
    </body>
</html>

ブラウザで「http://localhost/Twitter/Views/home.php」にアクセスします。

ブラウザ

PHPファイルにHTMLの内容を記述していますが、ブラウザはファイル内の「<!DOCTYPE html>」を検知して、HTMLの内容を表示することができます。

これまで、フロントエンドでは「HTML(JavaScript/CSS)」、バックエンドでは「PHP」がそれぞれ動作すると解説してきました。
それではなぜ、バックエンドで動作するはずのPHPファイルに記述した内容がブラウザに表示されるのでしょうか。

理由は以下の流れになります。

PHPの説明

バックエンドのPHPでは、HTMLの内容を「文字列」として作成し、その文字列データをブラウザへ返しているのです。
ブラウザでは受け取った文字列データを、「<!DOCTYPE html>」があるためHTMLだと判断し、HTMLの内容を表示することができます。

Bootstrap

Bootstrapとは、最も使われているCSSの代表的なフレームワークです。フレームワークとは、頻繁に使う基本的な機能をまとめて提供してくれるものでしたね。
Bootstrapを使うことで、レスポンシブデザインの技術を簡単に利用できるようになります。

Bootstrapを覗いてみよう

ここがBootstrapの中身です。
中身はCSSだということが分かります。

例えば以下のような記述がありますね。

.nav-item {
  flex-basis: 0;
  flex-grow: 1;
  text-align: center;
}

これは、HTML内の要素に「nav-item」というクラスを書いてくれれば、「当該要素の装飾はBootstrap(内のCSS)が行う」という意味になります。エンジニアはBootstrap用のクラスをHTMLに書いてやるだけで、面倒な装飾はBootstrapがやってくれる、ということですね。

home.phpで読み込んでおきます。

htdocs/Twitter/Views/home.php

<!DOCTYPE html>
<html>
    <lang="ja">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
        <title>Twitter</title>
    </head>
    <body>
        ホーム
    </body>
</html>

サイドメニュー1

HTML

サイドメニューのHTMLを作成します。
home.phpを以下のように修正します。

htdocs/Twitter/Views/home.php

<!DOCTYPE html>
<html>
    <lang="ja">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
        <title>Twitter</title>
    </head>
    <body>
        <!-- ★変更箇所(ここから) -->
        <div class="container">
            <div class="side">
                <!-- ★この中に、サイド領域のHTMLを書いていく -->
            </div>

            <div class="main">
                <!-- ★この中に、メイン領域のHTMLを書いていく -->
            </div>
        </div>

        <!-- ★変更箇所(ここまで) -->
    </body>
</html>

bodyに要素を追加しました。
「container」クラスは、Bootstrapのためのクラスです。このdiv要素の中に作成したいHTMLを記述していきます。これは覚えるしかありません。

次に、Twitterのサイド領域とメイン領域に分けるために、「side」クラスをもつdiv要素と、「main」クラスをもつdiv要素に分けました。
サイド領域のHTMLは前者のdiv要素内に、メイン領域のHTMLは後者のdiv要素内に書いていきます。

続いて、home.phpを以下のように修正します。

htdocs/Twitter/Views/home.php

<!DOCTYPE html>
<html>
    <lang="ja">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
        <title>Twitter</title>
    </head>
    <body>
        <div class="container">
            <div class="side">
                <!-- ★変更箇所(ここから) -->
                <div class="side-inner">
                    <ul class="nav flex-column">
                        <li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/1.svg" alt=""></a></li>
                        <li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/2.svg" alt=""></a></li>
                        <li class="nav-item"><a href="search.php" class="nav-link"><img src="../Views/img/3.svg" alt=""></a></li>
                        <li class="nav-item"><a href="notification.php" class="nav-link"><img src="../Views/img/4.svg" alt=""></a></li>
                        <li class="nav-item"><a href="profile.php" class="nav-link"><img src="../Views/img/5.svg" alt=""></a></li>
                        <li class="nav-item"><a href="post.php" class="nav-link"><img src="../Views/img/6.svg" alt=""></a></li>
                        <li class="nav-item"><img src="../Views/img_uploaded/user/sample.jpg" alt=""></li>
                    </ul>
                </div>
                <!-- ★変更箇所(ここまで) -->
            </div>
            <div class="main">
            </div>
        </div>
    </body>
</html>

まず「side-inner」クラスをもつdiv要素を設けています。これはul要素全体を装飾したい場合のために設けています。

その中にリスト要素である「ul」と「li」要素を配置しています。
ul要素に設けている「nav」クラスと「flex-column」クラスは、Bootstrapのためのクラスです。前者はレイアウト調整のため、後者はリスト要素を縦に並べるために設けています。これは覚えるしかありません。

li要素に設けている「nav-item」クラスは、Bootstrapのためのクラスです。レイアウト調整のために設けています。これは覚えるしかありません。

li要素内にはa要素を設けています。以前のカリキュラムで解説した通り、hrefに記載した場所に移動することができます。
a要素の中には、img要素を配置し、src属性にはimgフォルダ内の各画像ファイルを指定しています。
ここでの「<a><img></a>」の形、すなわちimg要素をa要素で囲むと、「画像をクリックすると、a要素のhrefの場所に移動する」という意味になります。このようにa要素で囲まれた要素(img要素に限らず)は、クリックするとa要素の場所に移動することができるのです。
移動先である「home.php」などはまだ存在しません。後ほど作成していきます。

「<img src=”img_uploaded/user/sample.jpg” alt=””>」の部分はa要素で囲まれていません。よって、この部分は画像をクリックしても何も起きません。

a要素の「nav-link」クラスは、Bootstrapのためのクラスです。レイアウト調整のために設けています。これは覚えるしかありません。

ブラウザで表示すると以下のようになります。

ブラウザ

CSSをまだ作成していないため、画像が重なったりしています。
画像の配置や大きさの調整などは、Bootstrapではなく自分で用意したCSSで行う必要があります。そこまでBootstrapに勝手にやられてしまったら、逆に不便ですからね。
次節でCSSを作成・適用していきます。

CSS

「Views」フォルダ内の「css」フォルダ内に、「style.css」ファイルを作成します。

VSCode

home.phpで読み込みます。

htdocs/Twitter/Views/home.php

<!DOCTYPE html>
<html>
    <lang="ja">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
        <!-- ★変更箇所(ここから) -->
        <link rel="stylesheet" href="../Views/css/style.css">
        <!-- ★変更箇所(ここまで) -->
        <title>Twitter</title>
    </head>
    <body>
        <div class="container">
            <div class="side">
                <div class="side-inner">
                    <ul class="nav flex-column">
                        <li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/1.svg" alt=""></a></li>
                        <li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/2.svg" alt=""></a></li>
                        <li class="nav-item"><a href="search.php" class="nav-link"><img src="../Views/img/3.svg" alt=""></a></li>
                        <li class="nav-item"><a href="notification.php" class="nav-link"><img src="../Views/img/4.svg" alt=""></a></li>
                        <li class="nav-item"><a href="profile.php" class="nav-link"><img src="../Views/img/5.svg" alt=""></a></li>
                        <li class="nav-item"><a href="post.php" class="nav-link"><img src="../Views/img/6.svg" alt=""></a></li>
                        <li class="nav-item"><img src="../Views/img_uploaded/user/sample.jpg" alt=""></li>
                    </ul>
                </div>
            </div>
            <div class="main">
            </div>
        </div>
    </body>
</html>

style.cssを以下のように書きます。

htdocs/Twitter/Views/css/style.css

.container {
    display: flex;
}

.side {
    width: 90px;
}

.main {
    width: calc(100% - 90px);
}
ブラウザ

containerクラスをもつdiv要素に「display: flex」を適用することで、子要素(sideクラスを持つdiv要素と、mainクラスを持つdiv要素)が横並びになります。
sideクラスをもつdiv要素に「width: 90px」を適用することで、同div要素の横幅が固定長の90pxになります。
mainクラスをもつdiv要素に「calc(100% – 90px)」を適用しています。calc()はCSSの関数で、文字通り「計算する(calculate)」という意味です。すなわち「100% – 90%」の計算をしています。「width: 100%」とは親要素の横幅で、ここではcontainerクラスをもつdiv要素を指します。containerクラスを持つdiv要素の横幅から、左側のsideクラスをもつdiv要素(横幅90px)を引いた残りの横幅が、mainクラスをもつdiv要素の横幅、という意味になります。

見やすさのため、上図では「<body>」「<div class=”container”>」「div class=”side”」各要素の基点・終点などをずらして描きましたが、正確にはこれらは下図のように一致しています(同じ場所にあります)。

「CSSでmarginやpadding、widthなどで場所や大きさを変更しない限り、親要素と子要素の場所・大きさは同じである」と覚えて下さい。

続いて、style.cssを以下のように修正します。

htdocs/Twitter/Views/css/style.css

/* 全体 */
.container {
    display: flex;
}

.side {
    width: 90px;
}

.main {
    width: calc(100% - 90px);
}

/* 変更箇所(ここから) */
/* サイド領域 */
.side .side-inner {
    text-align: center;
}

.side .side-inner img {
    width: 35%;
    margin-bottom: 15px;
}
/* 変更箇所(ここまで) */
ブラウザ

「.side .side-inner」は、sideクラスをもつ要素の、子要素のside-innerクラスをもつ要素という意味になります。「text-align: center」は、要素を「中央に揃える」という意味です。
「.side .side-inner img」は、sideクラスをもつ要素の、子要素のside-innerクラスをもつ要素の、さらに子要素であるimg要素という意味になります。
「width: 35%」は画像(img要素)の縮小を行っています。
img要素間の間隔が狭いため、「margin-bottom: 15px」を指定することで、img要素の下に間隔をあけています。

ここまでで、以下のようになっていればOKです。

ブラウザ

※数値を変えて、どのように表示が変わるかを試してみて下さい。

サイドメニュー2

HTML

home.phpを以下のように修正します。

htdocs/Twitter/Views/home.php

<!DOCTYPE html>
<html>
    <lang="ja">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
        <link rel="stylesheet" href="../Views/css/style.css">
        <title>Twitter</title>
    </head>
    <body>
        <div class="container">
            <div class="side">
                <div class="side-inner">
                    <ul class="nav flex-column">
                        <!-- ★変更箇所(ここから) -->
                        <li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/1.svg" alt="" class="icon"></a></li>
                        <li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/2.svg" alt=""></a></li>
                        <li class="nav-item"><a href="search.php" class="nav-link"><img src="../Views/img/3.svg" alt=""></a></li>
                        <li class="nav-item"><a href="notification.php" class="nav-link"><img src="../Views/img/4.svg" alt=""></a></li>
                        <li class="nav-item"><a href="profile.php" class="nav-link"><img src="../Views/img/5.svg" alt=""></a></li>
                        <li class="nav-item"><a href="post.php" class="nav-link"><img src="../Views/img/6.svg" alt="" class="icon"></a></li>
                        <li class="nav-item"><img src="../Views/img_uploaded/user/sample.jpg" alt="" class="my-icon"></li>
                        <!-- ★変更箇所(ここまで) -->
                    </ul>
                </div>
            </div>
            <div class="main">
            </div>
        </div>
    </body>
</html>

CSSで装飾をするため、「icon」クラス、「my-icon」クラスを追加しました。

CSS

style.cssを以下のように修正します。

htdocs/Twitter/Views/css/style.css

/* 全体 */
.container {
    display: flex;
}

.side {
    width: 90px;
}

.main {
    width: calc(100% - 90px);
}

/* サイド領域 */
.side .side-inner {
    position: sticky;
    height: 100vh;
    text-align: center;
}

.side .side-inner img {
    width: 35%;
    margin-bottom: 15px;
}

/* ★変更箇所(ここから)*/
.side .side-inner img.icon {
    width: 70%;
}
.side .side-inner img.my-icon {
    width: 70%;
    border-radius: 50%;
    border: 0.2px solid #aaa;
}
/* ★変更箇所(ここまで)*/

「.side .side-inner img.icon」の箇所に着目して下さい。「.side」と「.side-inner」、「.side-inner」と「img」の間にはスペースがありますが、「img」と「.icon」の間にはスペースがありません。これは、img要素の中のiconクラスだからです。当該要素の中のクラスを指定する場合はスペースを設けないでください。
これで、sideクラスをもつ要素の、子要素のside-innerクラスをもつ要素の、さらに子要素であるimg要素の中のiconクラス、という意味になります。

「.side .side-inner img.my-icon」も同様です。両者ともに「width: 70%」を指定して画像のサイズを調整しています。後者はさらに、「border-radius: 50%」と「border: 0.2px solid #aaa」を指定しています。「border-radius: 50%」は、文字通り「丸い角」という意味で、50%を指定することで真ん丸になります。「border: 0.2px solid #aaa」を指定することで、0.2pxの太さ、#aaaの色で、線の太さ・色を指定しています。

ここまでで、以下のようになっていればOKです。

ブラウザ

タイトルエリア

HTML

home.phpを以下のように修正します。

htdocs/Twitter/Views/home.php

<!DOCTYPE html>
<html>
    <lang="ja">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
        <link rel="stylesheet" href="../Views/css/style.css">
        <title>Twitter</title>
    </head>
    <body>
        <div class="container">
            <div class="side">
                <div class="side-inner">
                    <ul class="nav flex-column">
                        <li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/1.svg" alt="" class="icon"></a></li>
                        <li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/2.svg" alt=""></a></li>
                        <li class="nav-item"><a href="search.php" class="nav-link"><img src="../Views/img/3.svg" alt=""></a></li>
                        <li class="nav-item"><a href="notification.php" class="nav-link"><img src="../Views/img/4.svg" alt=""></a></li>
                        <li class="nav-item"><a href="profile.php" class="nav-link"><img src="../Views/img/5.svg" alt=""></a></li>
                        <li class="nav-item"><a href="post.php" class="nav-link"><img src="../Views/img/6.svg" alt="" class="icon"></a></li>
                        <li class="nav-item"><img src="../Views/img_uploaded/user/sample.jpg" alt="" class="my-icon"></li>
                    </ul>
                </div>
            </div>
            <div class="main">
                <!-- ★変更箇所(ここから) -->
                <div class="main-header">
                    <h1>ホーム</h1>
                </div>
                <!-- ★変更箇所(ここまで) -->
            </div>
        </div>
    </body>
</html>

見出しとなるh1要素を追加しています。
さらに、CSSで装飾をするため「main-header」クラスをもつdiv要素で囲っています。

CSS

style.cssを以下のように修正します。

htdocs/Twitter/Views/css/style.css

/* 全体 */
.container {
    display: flex;
}

.side {
    width: 90px;
}

.main {
    width: calc(100% - 90px);
    /* ★変更箇所1(ここから)*/
    border-left: 1px solid #eef;
    border-right: 1px solid #eef;
    max-width: 600px;
    /* ★変更箇所1(ここまで)*/
}

/* サイド領域 */
.side .side-inner {
    position: sticky;
    height: 100vh;
    text-align: center;
}

.side .side-inner img {
    width: 35%;
    margin-bottom: 15px;
}

.side .side-inner img.icon {
    width: 70%;
}
.side .side-inner img.my-icon {
    width: 70%;
    border-radius: 50%;
    border: 0.2px solid #aaa;
}

/* ★変更箇所2(ここから)*/
/* メイン領域 */
.main .main-header {
    padding: 20px;
    border-bottom: 1px solid #eef;
}

.main .main-header h1 {
    font-size: 20px;
    font-weight: bold;
}
/* ★変更箇所2(ここまで)*/
ブラウザ

変更箇所1について解説します。
「border-left: 1px solid #eef」により、mainクラスをもつdiv要素の左側にボーダー(線)を引いています。同様に「border-right: 1px solid #eef」により、右側にボーダーを引いています。
「max-width: 600px」により、mainクラスをもつdiv要素の横幅は最大600pxになります(=それ以上は広がらない)。ブラウザを最大化しても、600pxを超えては広がりません。

ブラウザ

最大値は600pxになりますが、最小値は指定していないので、ブラウザを縮めれば600px以下に狭まります。

ブラウザ

変更箇所2について解説します。
「.main .main-header」について、「padding: 20px」を適用すると、以下のようになります。

paddingの後に数字を1つ書くと、上下左右の余白を一括して指定できるのでしたね。

「border-bottom: 1px solid #eef」では「main-header」クラスをもつdiv要素に下線を引いています。
「.main .main-header h1」については、見出しであるh1要素に対して、「font-size: 20px」でフォントサイズを、「font-weight: bold」で太字を指定しています。

ブラウザ

本節の説明は以上になります。

トップページ <<前のカリキュラムへ戻る 次のカリキュラムへ進む>>

タイトルとURLをコピーしました