いよいよWebページの開発に入ります。
ここでは、みなさんご存じのTwitterに似たWebページを開発していきます。
本章での完成イメージは以下になります。
左側のアイコンが縦に並んでいる場所を「サイドメニュー」、中央のホーム以下の場所を「メインメニュー」と呼びます。
事前準備
必要なフォルダを作成します。
Visual Studio Codeを開いて下さい。HTDOCSフォルダ内に、Twitterフォルダをつくります。
さらにその中に、Viewsフォルダをつくります。
次に、こちらから素材となるファイルをダウンロードします。
sample.zipという名前のファイルがダウンロードできます。
その中の3つのフォルダをコピーし、Finderの「アプリケーション>MAMP>htdocs>Twitter>Views」フォルダ内に貼り付けます。
Visual Studio Code上では、以下のように見えていればOKです。
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の内容を表示することができます。
Bootstrap
Bootstrapとは、最も使われているCSSの代表的なフレームワークです。フレームワークとは、頻繁に使う基本的な機能をまとめて提供してくれるものでしたね。
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」ファイルを作成します。
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要素の横幅、という意味になります。
続いて、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」で太字を指定しています。
本節の説明は以上になります。