Webデザインの教科書
- Web制作 中級編 -
Scroll

実際に作ってみよう! GridとFlexboxで作るフレキシブルサイト

今回は少し本格的なWebページを作ってみましょう。

スマホ対応も含めたレスポンシブデザインのページを作成します。

制作時間はおよそ60分ほどで作成が出来るので、ぜひやってみて下さい。

実際に制作するページ

制作時間 60分
難易度
使用した
HTMLタグ
15種類
使用した
CSSプロパティ
31種類
対応表 パソコン
スマホ

上のような旅館風のトップページを作ってみます。

画像をクリックすると、実際に作るページを確認することが出来ます。

少しだけ難しいかも知れませんが、丁寧に解説するので安心してください。

実際に作ってみよう

それでは実際に作ってみましょう。

テキストエディターを起動して入力出来る状態まで準備してください。

まずは、HTMLファイルとCSSファイルを作るとこからいきます。

Webページの基本設定

  1. ファイル名:oshare-homepage.htmlで作成する。
    <!DOCTYPE html>
    <html lang="ja">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="css/oshare.css">
    <title>OSHARE HOMEPAGE</title>
    </head>
    <body>

    </body>
    </html>
  2. ファイル名:oshare.cssで作成する。
    @charset "UTF-8";
CSSファイルの作成場所
Web練習フォルダ/
 ├oshare-homepage.html
 └css/
  ├oshare.css

今回はCSSフォルダを作成して、その中にCSSファイル「oshare.css」を作成します。

ファイルの種類ごとにフォルダーにまとめることで、管理がしやすいというメリットがあります。

今回はCSSファイルは1つだけですが、CSSファイルが増えた時にファイルの整理がしやすくなります。

これで基本的な設定は完了です。

この後はWebページの構造を作っていきましょう。

Webページの構造

<!DOCTYPE html>
<html lang="ja">
<head>
...
</head>
<body>
<header></header>
<nav></nav>
<main></main>
<aside></aside>
<footer></footer>
</body>
</html>
HTML5の新しいタグ
<header></header>
<main></main>
<aside></aside>

前回の「Web制作-基本編」では「div」タグにクラスを付加して「ヘッダー」「メイン」「フッター」を分けて作成しました。

この書き方でも構わないのですが、長くてぱっと見てもわかりにくいです。

そこで、HTML5から新しいタグが登場しました。

<div class="header"></div>
<div class="main"></div>
<div class="footer"></div>
  • headerタグ

    画面の一番上にくる一番最初に表示される部分を構成するタグです。

    綺麗な画像やイラスト、インパクトのある見出しを入れるなど、いろんな使い方が出来ます。

    <header></header>
  • navタグ

    ページのリンクや目次など、ページに関する案内をする部分を構成するタグです。

    他のページに移動するリンクや、目次などのページ内リンクといったリンクをまとめるような使い方が出来ます。

    <nav></nav>
  • mainタグ

    Webページのメインになる記事の部分を構成するタグです。

    画像や動画などを含めながら記事を書いていくと見やすくてわかりやすい記事になります。

    <main></main>
  • asideタグ

    メインの内容の補足説明余談、メインの記事とは関係はないが載せておきたいことなどを構成するタグです。

    関連する記事を紹介したり、記事作成者のプロフィールや専門用語の補足説明など使い方は自由です。

    <aside></aside>
  • footerタグ

    ページの一番下にくる部分を構成するタグです。

    コピーライトロゴなど、著作権や権利を明記するために使われます。

    <footer></footer>

これでWebページの構造は完成です。

この作成した構造をベースにして、レイアウトを作っていきましょう。

レイアウトとCSS

@charset "UTF-8";
/* すべての要素に適用 */
* {
box-sizing: border-box;
}
/* ボディの設定 */
body {
position: relative;
margin: 0;
background: black;
display: grid;
grid-template-columns:
[left] 20px [main] 1fr [end] 20px [right];
grid-template-rows:
[header] auto [main] auto [aside] auto [footer] auto [bottom];
}
基本レイアウト
  • グリッドレイアウト

    CSSグリッドを使って、基本のレイアウトを作ります。

    「body」タグの中をグリッドで分割します。

    • グリッドの作成

      「body」タグの中にグリッドを作成します。

      display」の値を「grid」に指定します。

      後に「header」「main」「aside」「footer」をグリッドにはめていきます。

      body {
      display: grid;
      }
    • 横方向の間隔を決める

      グリッドの横方向の間隔を指定します。

      グリット間隔を左から「20px」「1fr」「20px」の間隔で分割します。

      さらに、分割した境目の線にそれぞれ「left」「main」「end」「right」と名前を付けます。

      body {
      grid-template-columns:
      [left] 20px [main] 1fr [end] 20px [right];
      }
    • 縦方向の間隔を決める

      グリッドの縦方向の間隔を指定します。

      グリット間隔をすべて「auto」に要素に合わせて調節されるように分割します。

      さらに、分割した境目の線に上から順に「header」「main」「aside」「footer」「bottom」と名前を付けます。

      body {
      grid-template-rows:
      [header] auto [main] auto [aside] auto [footer] auto [bottom];
      }
  • ポジションの設定

    bodyタグの中を自由に動けるように「relative」に指定します。

    あとで「nav」タグを配置するために指定しています。

    body {
    position: relative;
    }
デザインテクニック
  • margin
  • border
  • padding
  • contents

CSSでデザインする時に便利なプロパティを紹介します。

要素の大きさを指定する時に「box-sizing」というプロパティを使用することで、レイアウトの崩れを防ぐことが出来ます。

  • box-sizing
    • margin
    • border
    • padding
    • contents

    要素には「margin」「border」「padding」「contents」の4つの領域があるのを覚えていますか?

    「width」や「height」で要素の大きさを変える時、「contents」の領域の大きさが変わります。

    box-sizing」は要素の大きさを変える時に、「border」の領域を基準にすることが出来ます。

    • box-sizingを使わない時
      • margin
      • border
      • padding
      • contents

      例えば、「width」「padding」「border」を指定した時の要素の大きさを確認してみます。

      下記のように「width」の値を「100px」に指定した場合、「contents」の領域が広がります。

      その時の要素全体の大きさは「122px」になります。

      もし、要素全体の大きさを「100px」のつもりで指定した場合は、「22px」の誤差が出てしまいます。

      .box {
      width: 100px;
      padding: 0 10px
      border: solid 1px black;
      }
    • box-sizingを使う時
      • margin
      • border
      • padding
      • contents

      box-sizing」の値を「border-box」を設定した時の要素の大きさを確認してみます。

      「width」の値を「100px」に指定した場合、「contents」「padding」「border」を含めた大きさが指定されます。

      「contents」の領域は「78px」に自動調整され、要素全体の大きさは「100px」になります。

      .box {
      width: 100px;
      padding: 0 10px
      border: solid 1px black;
      box-sizing: border-box;
      }
  • すべての要素に適用する

    「box-sizing」を設定するには、すべての要素に適用しないと効果は発揮しません。

    すべての要素を適用するには、CSSのセレクタにアスタリスク「*」を指定します。

    つまり、「div」「h1」「h2」「p」「ul」「li」などのすべての要素に「box-sizing」を適用することが可能です。

    * {
    box-sizing: border-box;
    }
こんな時に便利
  • 要素を最大まで広げた時
    最大の横幅 + 44px

    「width」の値を「100%」にして最大まで広げた時に効果を発揮します。

    最大まで広げた時に「padding」と「border」を指定してしまうと、画面の外にはみ出てしまいます。

    下記の場合、「padding 」と「border」の大きさ「44px」が画面の外にはみ出ます。

    width: 100%;
    padding: 0 20px;
    border: solid 2px black;
  • 解決策
    最大の横幅(100%)

    「box-sizing」を設定している場合は、画面にぴったり収まるようになります。

    まず先に「padding」と「border」の大きさを計算して、残りが「contents」の大きさになります。

    「contents」「padding」「border」の合計の大きさが「100%」になるように計算されます。

    width: 100px;
    padding: 0 10px
    border: solid 1px black;
    box-sizing: border-box;

これで基本のレイアウトは完了です。

この後、作成したレイアウトに要素を当てはめてページを作っていきます。

まずはヘッダーを作成してましょう。

<!DOCTYPE html>
<html lang="ja">
<head>
...
</head>
<body>
<header>
<img src="image/oshare-bgimage.jpg" alt="トップイメージ">
<div class="top-title">
OSHARE<br>
DESIGN<br>
HOMEPAGE
</div>
</header>
<nav></nav>
<main></main>
<aside></aside>
<footer></footer>
</body>
</html>
@charset "UTF-8";
/* ここから追記 */
/* ヘッダー */
header {
position: relative;
grid-column-start: left;
grid-column-end: right;
grid-row-start: header;
grid-row-end: main;
margin-bottom: 100px;
}
header img {
display: block;
width: 100%;
max-height: 100vh;
}
.top-title {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%,50px);
width: 500px;
height: 500px;
background: rgba(255,255,255,.5);
font-size: 50px;
}
/* メディアクエリ */
@media (max-width: 1024px) {
.top-title {
width: 400px;
height: 400px;
font-size: 40px;
transform: translate(-50%,40px);
}
}
@media (max-width: 840px) {
.top-title {
width: 300px;
height: 300px;
font-size: 35px;
transform: translate(-50%,30px);
}
}
@media (max-width: 580px) {
header {
margin-bottom: 60px;
}
.top-title {
width: 250px;
height: 250px;
transform: translate(-50%,25px);
}
}
@media (max-width: 450px) {
.top-title {
width: 200px;
height: 200px;
font-size: 30px;
transform: translate(-50%,20px);
}
}
@media (max-width: 370px) {
.top-title {
width: 150px;
height: 150px;
font-size: 25px;
transform: translate(-50%,15px);
}
}
ヘッダーのデザイン
  • グリッドの配置

    グリッドレイアウトの中にヘッダーを配置します。

    グリッドの名前のついた境界線をそれぞれ指定して配置します。

    横方向は「left」と「right」を指定して、両端に配置します。

    縦方向は「header」と「main」を指定して、一番右上のグリッドに配置します。

    .header {
    grid-column-start: left;
    grid-column-end: right;
    grid-row-start: header;
    grid-row-end: main;
    }
  • ポジションの設定

    ヘッダーの中を自由に動けるように「relative」を指定します。

    さらに、ヘッダーの下に「100px」の余白を作成します。

    あとで「OSHARE DESIGN HOMEPAGE」のタイトル部分を配置するために設定しています。

    .header {
    position: relative;
    margin-bottom: 100px;
    }
  • ヘッダーの画像

    パソコンやスマホなどの端末でも綺麗に画像が表示されるように、レスポンシブ対応します。

    • 横幅いっぱいまで広げる

      「width」の値を「100%」にして、横幅の最大まで広げます。

      .header img {
      width: 100%;
      }
    • 「block」要素に上書きする

      「img」タグで画像を表示する時に、画像の下に謎の空白が出来ることがあります。

      その謎の空白を消去するために、「block」要素に上書きして修正しています。

      .header img {
      display: block;
      }
    • 最大の高さを決める

      画像の最大の高さを、画面(ブラウザ)の高さを超えないように調整します。

      max-height」プロパティとその値「100vh」を使います。

      1. max-heightを使う

        max-height」はどんなに高さを大きくしても、これ以上は大きくしないように設定が出来ます。

      2. 100vh

        「max-height」の値を「100vh」に指定します。

        100vh」は画面(ブラウザ)の高さと同じ高さになります。

        .header img {
        max-height: 100vh;
        }
      新しい単位 vh
      vh

      vh」という単位は「viewport height」の略で画面(ブラウザ)の縦の大きさを基準にした単位です。

      100vh」の時は、パソコンやスマホなどの画面の高さと同じ大きさを意味します。

      50vh」の時は、画面の半分の高さが指定されます。

      今回は、画像が画面下にはみ出ないように「max-height」の値を「100vh」にして、画面に収まるように調整しています。

      .header img {
      display: block;
      }
ヘッダーのタイトル
  • タイトルの中央寄せ
    OSHARE
    DESIGN
    HOMEPAGE
    OSHARE
    DESIGN
    HOMEPAGE

    タイトルの文字を要素の中央に配置します。

    文字の中央寄せはフレックスボックスを使います。

    • display: flex

      フレックスボックスを指定します。

      フレックスボックスの本来の使い方は横並びにする使い方ですが、今回は中央寄せをするために使います。

    • justify-content: center

      横方向に文字を中央寄せします。

    • align-item: center

      縦方向に文字を中央寄せにします。

    .top-title {
    display: flex;
    justify-content: center;
    align-items: center;
    }
  • タイトルの配置
    headerエリア
    OSHARE
    DESIGN
    HOMEPAGE
    • position: absolute

      「position: relative」が指定された「headerエリア」の範囲内で好きなところに配置できるようにします。

    • bottom: 0

      要素の一番下をheaderエリアの一番下に合わせます。

    • left: 50%

      要素の一番左をheaderエリアの横幅の50%(半分)の位置に配置します。

    • transform

      要素の大きさを基準に移動や回転、変形させたりできるプロパティです。

      今回は移動したいので「translate」というものを使います。

      • translate(X,Y)
      • 要素の大きさを基準に横(X軸)縦(Y軸)に移動します。
      OSHARE
      DESIGN
      HOMEPAGE
      1. 要素の50%(半分)の大きさ分をマイナス値を指定して左側に修正します。
      2. 要素を50pxの大きさで下に修正します。
      .top-title {
      position: absolute;
      bottom: 0;
      left: 50%;
      transform: translate(-50%,50px);
      }
  • メディアクエリ

    画面サイズが小さくなると、タイトルが大きすぎたり見栄えが悪くなってしまします。

    メディアクエリを使って、画面サイズに合わせて微調整します。

    • 横幅1024px以下

      ヘッダータイトルの要素の大きさを「400px」文字サイズを「40px」に変更して、さらに要素を「40px」下に調整します。

      .top-title {
      width: 400px;
      height: 400px;
      font-size: 40px;
      transform: translate(-50%,40px);
      }
    • 横幅840px以下

      ヘッダータイトルの要素の大きさを「300px」文字サイズを「35px」に変更して、さらに要素を「30px」下に調整します。

      .top-title {
      width: 300px;
      height: 300px;
      font-size: 35px;
      transform: translate(-50%,30px);
      }
    • 横幅580px以下

      ヘッダーの下の余白を「60px」に変更します。

      さらにヘッダータイトルの要素の大きさを「250px」に変更して、要素を「25px」下に調整します。

      .header {
      margin-bottom: 60px;
      }
      .top-title {
      width: 250px;
      height: 250px;
      transform: translate(-50%,25px);
      }
    • 横幅450px以下

      ヘッダータイトルの要素の大きさを「200px」文字サイズを「30px」に変更して、さらに要素を「20px」下に調整します。

      .top-title {
      width: 200px;
      height: 200px;
      font-size: 30px;
      transform: translate(-50%,20px);
      }
    • 横幅370px以下

      ヘッダータイトルの要素の大きさを「150px」文字サイズを「25px」に変更して、さらに要素を「15px」下に調整します。

      .top-title {
      width: 150px;
      height: 150px;
      font-size: 25px;
      transform: translate(-50%,15px);
      }

これでヘッダーが完成しました。

メディアクエリで細かく設定をして、レイアウトが崩れないようにします。

続いてはメニューを作成します。

<!DOCTYPE html>
<html lang="ja">
<head>
...
</head>
<body>
<header>...</header>
<nav>
<ul>
<li>About</li>
<li>Room</li>
<li>Plan</li>
<li>Access</li>
<li>Gallery</li>
</ul>
</nav>
<main></main>
<aside></aside>
<footer></footer>
</body>
</html>
@charset "UTF-8";
/* ここから追記 */
/* ナビゲーション */
nav {
position: absolute;
top: 0;
left: 0;
right: 0;
}
nav ul {
display: flex;
background: rgba(255,255,255,.7);
margin: 0;
list-style: none;
padding: 0;
font-size: 1.2rem;
}
nav li {
text-align: center;
padding: 10px 0;
width: 80px;
cursor: pointer;
transition: all 1s;
}
nav li:hover {
background: white;
}
メニューのデザイン
  • メニューの配置
    • position: absolute

      「nav」タグを好きなところに配置できるようにします。

      「body」タグに指定された「relative」があることで、自由に移動することが出来ます。

    • top: 0

      要素の一番上を一番上に合わせます。

    • left: 0

      要素の一番左を一番左に合わせます。

    • right: 0

      要素の一番右を一番右に合わせます。

    nav {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    }
    こんな書き方でもOK!!

    left: 0」と「right: 0」を指定した時は、左右が最大まで広がります。

    実は左右を広げる時に「width: 100%」でも同じように広がります。

    下記のような書き方でも大丈夫です。

    nav {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    }
  • メニューのデザイン

    フレックスボックスを使って、メニューのリストを横並びにします。

    さらに、メニューの文字サイズや中央寄せなどデザインを作っていきます。

    • 横並び

      フレックスボックスで、メニューを横並びにします。

      nav ul {
      display: flex;
      }
    • 文字サイズ

      メニューの文字サイズを少し大きくします。

      文字サイズを「1.2rem」に指定します。

      HTMLの初期の文字サイズ「16px」の1.2倍の大きさの「19.2px」が指定されます。

      nav ul {
      font-size: 1.2rem;
      }
    • 文字の中央寄せ

      メニューの文字を中央寄せします。

      さらに、上下に「10px」の余白を作成して整えます。

      nav li {
      text-align: center;
      padding: 10px 0;
      }
  • アニメーション

    メニューに色を変えるアニメーションを追加して、オシャレなデザインにします。

    アニメーションをすることで、クリックが出来ることを知らせる効果もあります。

    • アニメーション設定
      Touch Me!!
      Touch Me!!

      メニューにマウスカーソルを乗せた時のアニメーションを設定します。

      文字の色と背景の色を1秒かけてアニメーションするように設定します。

      上の「Touch Me!!」は、アニメーションを追加前と追加後の違いを比較することが出来ます。

      nav li {
      transition: all 1s;
      }
    • アニメーションの動作

      メニューにマウスカーソルを乗せた時に、どのように変化するか設定します。

      CSSで「:hover」を使って、文字の色と背景の色が変わるように設定します。

      nav li:hover {
      transition: all 1s;
      }
  • マウスの形を変える
    pointer

    メニューにマウスカーソルを乗せた時に、マウスの形を変えます。

    マウスの形を変えて、クリックが出来ることを知らせます。

    • ポインター

      マウスを乗せた時に、「」から「」に形を変えます。

      nav li {
      cursor: pointer;
      }

これでメニューの作成が完成しました、

ですが、スマホやタブレットではデザインが崩れてしまいます。

今度は、作成したメニューをモバイル対応してみましょう。

@charset "UTF-8";
/* ここから追記 */
/* メニューの表示 */
nav.open {
display: block;
}
/* メディアクエリ */
@media (max-width:840px) {
nav {
position: fixed;
display: none;
}
nav ul {
flex-direction: column;
height: 100vh;
padding-top: 40px;
background: rgba(255,255,255,.9);
}
nav li {
width: 100%;
padding: 20px;
}
}
メニューのモバイル対応
  • メニューのモバイル対応

    スマホやタブレットでもメニューが見やすいようにCSSでモバイル対応をします。

    メディアクエリを使って上部にあったメニューのデザインを変更します。

    • リストを縦並びに戻す

      フレックスボックスを使って横並びにしていたものを縦並びに戻します。

      画面サイズが840px以下の時は、メニューを縦並びのデザインにします。

      nav ul {
      display: flex;
      }
      /* 840px以下の時 */
      @media (max-width:840px) {
      nav ul {
      flex-direction: column;
      }
      }
      並べる向きを変える
      1
      2
      3
      4
      2
      3
      4

      フレックスボックスを使って、要素を横並び縦並びに変更する時はこのようにCSSを書きます。

      要素の並ぶ方向を変更する時は、「flex-direction」プロパティを使用します。

      • 縦並び

        フレックスボックスで横並びにしていたものを、縦並びに戻す時は「flex-direction」の値を「column」に指定します。

        nav ul {
        flex-direction: column;
        }
      • 横並び

        フレックスボックスで横並びにする時は、「flex-direction」の値を「row」に指定します。

        ですが、フレックスボックスは初期値で「row」に設定されています。

        例えば「column」で縦並びにしていたものを、横並びに戻す時に設定します。

        nav ul {
        flex-direction: row;
        }
    • 画面いっぱいまで広げる

      メニューを画面全体を覆うように広げたデザインに変更します。

      メニューの高さを「100vh」にして画面の大きさと同じ高さに設定します。

      nav ul{
      display: flex;
      }
      /* 840px以下の時 */
      @media (max-width:840px) {
      nav ul{
      flex-direction: column;
      height: 100vh;
      }
      }
    • 画面に付いてくるようにする

      スクロールしてもナビゲーションが付いてくるようにします。

      positionを「absolute」から「fixed」に上書きして、画面についてくるようにします。

      nav {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      }
      /* 840px以下の時 */
      @media (max-width:840px) {
      nav {
      position: fixed;
      }
      }
    • メニューを非表示にする

      モバイル版のメニューの時は、画面全体に被せるように変更しました。

      なので、メニューを利用しない時は非表示にします。

      /* 840px以下の時 */
      @media (max-width:840px) {
      nav {
      display: none;
      }
      }
      /* メニュー表示 */
      nav.open {
      display: block;
      }

これでモバイル版のメニューは完了です。

モバイル版は使わない時は邪魔なので、非表示にしています。

次はメニューを表示するボタンを作成します。

<!DOCTYPE html>
<html lang="ja">
<head>
...
</head>
<body>
<header>...</header>
<nav>...</nav>
<!--メニューボタン-->
<div class="menubutton" onclick="menu()">
<i></i>
<i></i>
<i></i>
</div>
<main></main>
<aside></aside>
<footer></footer>
</body>
</html>
@charset "UTF-8";
/* ここから追記 */
/* メニューボタン */
.menubutton {
position: fixed;
top: 0;
left: 0;
cursor: pointer;
z-index: 100;
width: 40px;
height: 40px;
padding: 5px;
background: black;
display: none;
}
.menubutton i {
display: block;
width: 30px;
height: 5px;
background: white;
margin-bottom: 7.5px;
}
.menubutton i:last-child {
margin-bottom: 0;
}
/* メディアクエリ */
@media (max-width:840px) {
.menubutton {
display: block;
}
}
メニューボタンの作成
  • メニューボタンのアイコン作成
    1. 黒の正方形を作る

      「40px」の黒の正方形を作ります。

      .menubutton {
      width: 40px;
      height: 40px;
      background: black;
      }
    2. 正方形の中にスペースを作る

      正方形の内側に5pxのスペースを作ります。

      .menubutton {
      padding: 5px;
      }
    3. 3本の白い長方形を作る

      「iタグ」を使って白い3本のバーを作ります。

      横幅「30px」高さ「5px」の白い長方形を作成します。

      <i></i>
      <i></i>
      <i></i>
      .menubutton i {
      display: block;
      width: 30px;
      height: 5px;
      background: white;
      }
      「iタグ」について
      1. 本来は斜め文字に装飾するタグ
        iタグの本来の使い方は「Naname Letter」のように斜め文字にしたい時に使用するタグですが、今回のようにアイコン用のためにiタグを使用します。
        斜め文字はCSSでも出来るのでiタグは使われなくなりました。そのため、よくアイコン用に使われるようになりました。
      2. displayプロパティの上書き
        iタグのdisplayプロパティの初期値は「inline」という値で、大きさを変えられません。なので、大きさを変えられるように「block」に上書きします。
        デザインの都合上必要な上書きという認識で大丈夫です。
        display: block;
    4. 3本の長方形の下に間隔を作る

      作成した3本の白いバーの間隔を空けます。

      「iタグ」の下にスペースを「7.5px」の空白を作ります。

      .menubutton i {
      margin-bottom: 7.5px;
      }
      最後のiタグだけスペースなし

      最後(3つ目)の「iタグ」の下のスペースは必要ないので、最後の「iタグ」のみ、CSSを上書きしてスペースをなくします。

      .menubutton i:last-child {
      margin-bottom: 0;
      }
メニューボタンを配置する
  • メニューボタンの配置
    • position: fixed

      メニューボタンを画面に固定して、スクロールしても付いてくるようにします。

    • top: 0

      画面の上部に固定して配置します。

    • left: 0

      画面の左側に固定して配置します。

    • cursor: pointer

      マウスを載せたの時にマウスカーソルの形をポインターに変えます。

    • z-index: 100

      「position」で要素同士が重なるデザインの時に、要素が重なる順番を設定します。

      z-index」プロパティの値を「100」に指定して、一番上に重なるようにします。

      .menubutton {
      position: fixed;
      top: 0;
      left:0;
      cursor: pointer
      z-index: 100;
      }
      z-indexの値
      100
      50
      20

      「z-index」の値は、数値が大きいほど画面の手前に表示されます。

      反対に背景画像など奥に表示させたい時は「-1」のようにマイナス値を指定することも出来ます。

      「z-index」が指定されていない要素は、初期値の「0」が基準になります。

  • メニューボタンの表示・非表示
    • 表示・非表示の切り替え

      画面の大きさでメニューボタンの表示・非表示を切り替えます。

      画面の大きさが840px以下の時に、モバイル版のメニューに切り替わります。

      メニューボタンも840px以下の時は表示して、それ以外の時は非表示にします。

      .menubutton {
      display: none;
      }
      /* 840px以下の時 */
      @media (max-width:840px) {
      .menubutton {
      display: block;
      }
      }

メニューボタンの作成が完了しました。

ですが、まだメニューボタンとしての機能はありません。

これから表示の機能を追加します。

<!DOCTYPE html>
<html lang="ja">
<head>
...
</head>
<body>
<header>...</header>
<nav>...</nav>
<!--メニューボタン-->
<div class="menubutton" onclick="menu()">
...
</div>
<main></main>
<aside></aside>
<footer></footer>
<!--ボタンをクリック-->
<script>
function menu() {
document.querySelector('nav').classList.toggle('open');
}
</script>
</body>
</html>
メニューボタンの機能を追加する
  • メニューボタンの開閉の仕組み
    <navclass="open">
    ...
    </nav>
    <!--メニューボタン-->
    <div class="menubutton" onclick="menu()" >
    ...
    </div>
    <!--ボタンをクリック-->
    <script>
    function menu() {
    document.querySelector('nav').classList.toggle('open');
    }
    </script>
    @media (max-width:840px) {
    nav {
    display:none;
    }
    }
    nav.open {
    display:block;
    }
    • クリックを検知する

      HTMLに記述した「onclick="menu()"」がクリックしたことを検知してくれます。

      • onclick

        クリックされた時に処理を開始します。
        今回はメソッドと呼ばれる「menu()」を呼び出す処理をします。

        「menu()」はJavaScriptで処理内容を別で書いています。

      <div class="menubutton" onclick="menu()">
      ・・・
      </div>
    • クラスの追加・消去

      JavaScriptを使って「open」クラスを付けたり消したりしてメニューの表示を切り替えます。

      onclickで呼ばれたmenu()の処理内容をHTMLの中に書いていきます。

      • function menu()

        メソッド名「menu」で処理内容を設定します。

      • document.querySelector('nav')

        navタグを操作対象にします。

      • classList

        クラスを操作します。

      • toggle('open')

        「open」クラスがない時はクラスを付加、「open」クラスがある時はクラスを消去します。

      <script>
      function menu() {
      document.querySelector('nav').classList.toggle('open');
      }
      メソッド名:menu {
      'nav'タグにトグルで'open'クラスを付加または消去する;
      }
      </script>
    • メニュー表示・非表示

      JavaScriptで「open」クラスの付加・消去に応じて、CSSでメニューの表示・非表示を切り替えます。

      「open」クラスがない時はメニューは非表示、「open」クラスがある時はメニューを表示するようにします。

      /* 非表示 */
      nav {
      display: none;
      }
      /* 表示 */
      nav.open {
      display: block;
      }

これでメニューのモバイル対応は完了です。

ここまでが長い道のりでした...。

今度はメインの記事を作成していきます。

メイン記事の作成

<!DOCTYPE html>
<html lang="ja">
<head>
...
</head>
<body>
<header>...</header>
<main>
<h1>オシャレな旅館のホームページ</h1>
<div class="plan">
<img src="image/oshare-bar.jpg" alt="バーの写真">
<div class="comments">
<h2>木で統一された雰囲気のあるBAR</h2>
<p>
宿泊される方が集まるBAR。海外から訪れる方が多く国際交流ができる場になっています。150種類以上のお酒がお楽しみいただけます。
</p>
<div>※20歳以上の方のみご利用出来ます。</div>
</div>
</div>
<div class="plan">
<img src="image/oshare-room.jpg" alt="部屋の写真">
<div class="comments">
<h2>日本らしい古風のお部屋</h2>
<p>
昔ながらの日本の雰囲気でゆっくりくつろげる空間。お部屋ごとに露天風呂をご用意しております。いつでもご利用下さいませ。
</p>
</div>
</div>
</main>
<aside></aside>
<footer></footer> </body>
</html>
@charset "UTF-8";
/* ここから追記 */
/* メイン */
main {
grid-column-start: main;
grid-column-end: end;
grid-row-start: main;
grid-row-end: aside;
margin-bottom: 100px;
}
h1,h2 {
color: white;
text-align: center;
}
.plan {
display: flex;
width: 100%;
max-width: 800px;
margin: 2em auto;
}
.plan img {
display: block;
height: 200px;
}
.plan h2 {
font-size: 20px;
color: black;
}
.plan .comments {
width: 100%;
padding: 0 20px;
background: #cccccc;
}
@media (max-width: 700px) {
.plan {
flex-direction: column;
}
.plan img {
width: 100%;
height: auto;
}
.plan .comments {
padding: 20px;
}
}
メインのデザイン
  • グリッドの配置

    グリッドレイアウトの中にメインを配置します。

    横方向は「main」と「end」を指定して、中央に配置します。

    縦方向は「main」と「aside」を指定して、上から2番目のグリッドに配置します。

    main {
    grid-column-start: main;
    grid-column-end: end;
    grid-row-start: main;
    grid-row-end: aside;
    }
  • 見出しのデザイン

    「h1」と「h2」の見出しのデザインをします。

    「h1」と「h2」のデザインは共通なので、一緒にデザインします。

    • 文字の色

      見出しの文字の色を白に変更します。

      背景が黒なので、文字の色を白にしてはっきり見えるようにします。

    • 文字の中央寄せ

      見出しがページの中央に来るように寄せます。

    h1 , h2 {
    color: white;
    text-align: center;
    }
  • 旅館の紹介

    旅館のサービスや部屋に関する項目をデザインします。

    • 全体レイアウト

      画像と詳細を横並びに配置します。

      さらに、横に広がる大きさを最大800pxに制限します。

      もし「800px」以下になる時は、親要素に合わせて縮んでいきます。

      .plan {
      display: flex;
      width: 100%;
      max-width: 800px;
      }
    • 画像

      画像の高さを「200px」に固定します

      さらに、画像を「block」要素に変更します。

      画像の下に出来る謎の空白を消去するために、「block」要素に上書きして修正します。

      .plan img {
      display: block;
      height: 200px;
      }
    • 見出し

      「h2」タグの見出しのデザインを変更します。

      文字サイズを「20px」変更して、さらに文字の色を黒に変更します。

      .plan h2 {
      font-size; 20px;
      color: black;
      }
  • レスポンシブ対応

    旅館のサービスや部屋に関する項目を、レスポンシブ対応します。

    メディアクエリで画面の大きさが「770px」以下の時は、要素を縦並びにします。

    • 縦並び

      横並びにしていた画像と詳細を、縦並びに変更します。

      @media (max-width: 700px) {
      .plan {
      flex-direction: column;
      }
      }
    • 画像の大きさ

      要素を縦並びにしている時は、画像の横幅を最大まで広げるように変更します。

      さらに、画像の高さを「200px」から「auto」に上書きします。

      高さを「auto」にすることで、画像の高さを自動で調節するようにします。

      @media (max-width: 700px) {
      .plan img {
      width: 100%;
      height: auto;
      }
      }
    • 詳細のデザイン

      要素を縦並びにした時に、画像と詳細の文章との間が近くなってしまいます。

      文章が読みやすくなるように、上下左右に余白を作って整えます。

      @media (max-width: 700px) {
      .plan .comments {
      padding: 20px;
      }
      }

これでメインの記事は完了です。

完成まであともう少しですよ!!

次は、最新情報をお知らせするサイド記事を作成します。

サイド記事の作成

<!DOCTYPE html>
<html lang="ja">
<head>
...
</head>
<body>
<header>...</header>
<main>...</main>
<aside>
<h2>News</h2>
<div class="news">
<div class="topic">
<div class="time">2019/10/01</div>
<div>消費税の増税に伴う料金の変更のお知らせ 増税後ver</div>
</div>
<div class="topic">
<div class="time">2019/09/23</div>
<div>台風に関する営業時間の変更のお知らせ</div>
</div>
<div class="topic">
<div class="time">2019/08/10</div>
<div>消費税の増税に伴う料金のお知らせ</div>
</div>
<div class="topic">
<div class="time">2019/07/04</div>
<div>公式instagramがオープン</div>
</div>
<div class="topic">
<div class="time">2019/07/03</div>
<div>公式Twitterがオープン</div>
</div>
<div class="topic">
<div class="time">2019/06/20</div>
<div>お部屋をリニューアルしました</div>
</div>
</div>
</aside>
<footer></footer>
</body>
</html>
/* ここから追記 */
/* サイド */
aside {
grid-column-start: main;
grid-column-end: end;
grid-row-start: aside;
grid-row-end: footer;
}
.news {
max-width: 1000px;
border-top: dashed 1px #cccccc;
border-bottom: dashed 1px #cccccc;
margin: 2em auto;
padding: 1em 20px;
color: white;
}
.news .topic {
display: flex;
align-items: center;
padding: 10px;
margin: 1em 0;
border-left: solid 10px #cccccc;
}
.news .time {
margin-right: 1em;
}
@media (max-width: 450px) {
.news .topic {
flex-direction: column;
align-items: flex-start;
}
}
サイドのデザイン
  • グリッドの配置

    グリッドレイアウトの中にお知らせ一覧の項目を配置します。

    横方向は「main」と「end」を指定して、中央に配置します。

    縦方向は「aside」と「footer」を指定して、上から3番目のグリッドに配置します。

    aside {
    grid-column-start: main;
    grid-column-end: end;
    grid-row-start: aside;
    grid-row-end: footer;
    }
  • 全体デザイン
    2019/10/01
    最新情報
    2019/09/23
    最新情報

    最新情報をまとめる項目をデザインします。

    • 横幅の制限

      横幅の広がる大きさを最大1000pxに制限します。

      もし「1000px」以下になる時は、親要素に合わせて縮んでいきます。

      .news {
      max-width: 1000px;
      }
    • 中央寄せ

      横幅を「1000px」に制限したので、画面が大きい時は要素が左に寄ってしまいます。

      要素を中央寄せして、さらに上下に「2em」の余白を作ります。

      「2em」はHTMLの初期値の文字サイズ「16px」の2倍大きさ「32px」になります。

      .news {
      margin: 2em auto;
      }
    • 上下に破線

      最新情報をまとめる項目の上下にグレーの破線を作成します。

      上の線「border-top」と下の線「border-bottom」で、破線(dashed)を作成します。

      .news {
      border-top: dashed 1px #cccccc;
      border-bottom: dashed 1px #cccccc;
      }
  • 情報一覧のデザイン
    2019/10/01
    最新情報のお知らせ

    一つ一つの情報のレイアウトとデザインを設定します。

    • レイアウト
      Time
      New Info

      更新日と詳細を横並びにします。

      その時「align-items」の値を「center」にして、上下方向の中央寄せをします。

      さらに更新日と詳細の間隔を空けるために、「time」クラスの右側に「1em」の余白を作ります。

      .news .topic {
      display: flex;
      align-items: center;
      }
      .news .time {
      margin-right: 1em;
      }
    • デザイン

      一つ一つの情報が見えやすいように、左側に縦の太い線を引きます。

      border-left」の値を「10px」に指定して、左側に太い線を作成します。

      .news .topic {
      border-left: 10px;
      }
  • レスポンシブ対応
    Time
    New Info

    お知らせ一覧の項目を、レスポンシブ対応します。

    メディアクエリで画面の大きさが「450px」以下の時は、要素を縦並びにします。

    • 縦並び

      横並びにしていた更新日と詳細を、縦並びに変更します。

      @media (max-width: 450px) {
      .plan .topic {
      flex-direction: column;
      }
      }
    • 左寄せ

      縦並びにした時に、「align-items」の値が「center」のままだと中央寄せされます。

      「align-items」の値が「flex-start」に変更して、左寄せします。

      @media (max-width: 450px) {
      .plan .topic {
      align-items: flex-start;
      }
      }
    縦並びにした時の注意

    フレックスボックスを使って横並び縦並びを切り替える時に注意しなければいけないことがあります。

    フレックスボックスの「justify-content」と「align-items」で子要素を揃えていましたが、横並び縦並びでは機能が反対になります。

    • 横並びの時
      1
      2
      3
      justify-content
      align-items

      子要素を横並びにしている時は「justify-content」は左右の間隔を揃えます。

      それに対して「align-items」は上下の間隔を揃えます。

      .plan .topic {
      display: flex;
      justify-content: center;
      align-items: center;
      }
    • 縦並びの時
      1
      2
      3
      align-items
      justify-content

      子要素を縦並びにしている時は「align-items」が左右の間隔を揃えます。

      それに対して「justify-content」は上下の間隔を揃えます。

      flex-direction」で縦並びの「column」を指定している時は、反対の効果になります。

      .plan .topic {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      }

サイド記事の作成が完了しました。

残すところはフッターのみです。

がんばっていきましょう。

<!DOCTYPE html>
<html lang="ja">
<head>
...
</head>
<body>
<header>...</header>
<main>...</main>
<aside>...</aside>
<footer>
&copy; 2019 OSHARE HOMEPAGE
</footer>
</body>
</html>
/* ここから追記 */
/* フッター */
footer {
grid-column-start: left;
grid-column-end: right;
grid-row-start: footer;
grid-row-end: bottom;
text-align: center;
background: white;
padding: 10px 0;
}
footer
  • グリッドの配置

    グリッドレイアウトの中にヘッダーを配置します。

    横方向は「left」と「right」を指定して、両端に配置します。

    縦方向は「footer」と「bottom」を指定して、一番下のグリッドに配置します。

    footer {
    grid-column-start: left;
    grid-column-end: right;
    grid-row-start: footer;
    grid-row-end: bottom;
    }
  • コピーライト

    フッターの中に、コピーライトを作成します。

    • コピーライトとは?

      コピーライトとは、一番下の「© 2019 OSHARE HOMEPAGE」の部分です。

      これはこのサイトで作成された記事や画像、動画などすべてのコンテンツに著作権がありますとわかりやすく明記するためによく書かれます。

    • 書き方
      1. コピーライトマーク
      2. 発行年

        ここには公開した年を書きます。本サイトは2019年に公開したので「2019」と書きます。

      3. 会社名・名前

        ここはなんでもいいのですが、会社でサイトを公開するのなら「会社名」、個人で公開するなら「ご自身の名前」など著作権を持つ会社・名前を書くといいと思います。

      &copy; 2019 OSHARE HOMEPAGE
      コピーライトは必要?

      実際は、コピーライトを記述しなくても自動的に著作権は発生します。

      正直あっても無くても変わりません。

      昔からの習慣・風習のような理由で明記してるサイトがほとんどなので、そんな細かく考えることはしなくて大丈夫です。

      参考サイト : LIC

以上でWeb制作中級編は終了です。

お疲れ様でした。

このように「grid」と「flexbox」でレイアウトを作っていきます。

さらに、メディアクエリでスマホ対応することで本格的なページの完成です。

Webページの完成

すべてのHTMLとCSSのコードが下にあります。

このように作成出来ていれば正解です。

確認程度によかったら確認してみて下さい。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="css/oshare.css"> <title>OSHARE HOMEPAGE</title>
</head>
<body>
<header>
<img src="image/oshare-bgimage.jpg" alt="トップイメージ">
<div class="top-title">
OSHARE<br>
DESIGN<br>
HOMEPAGE
</div>
</header>>
<main>
<h1>オシャレな旅館のホームページ</h1>
<div class="plan">
<img src="image/oshare-bar.jpg" alt="バーの写真">
<div class="comments">
<h2>木で統一された雰囲気のあるBAR</h2>
<p>
宿泊される方が集まるBAR。海外から訪れる方が多く国際交流ができる場になっています。150種類以上のお酒がお楽しみいただけます。
</p>
<div>※20歳以上の方のみご利用出来ます。</div>
</div>
</div>
<div class="plan">
<img src="image/oshare-room.jpg" alt="部屋の写真">
<div class="comments">
<h2>日本らしい古風のお部屋</h2>
<p>
昔ながらの日本の雰囲気でゆっくりくつろげる空間。お部屋ごとに露天風呂をご用意しております。いつでもご利用下さいませ。
</p>
</div>
</div>
</main>
<aside>
<h2>News</h2>
<div class="news">
<div class="topic">
<div class="time">2019/10/01</div>
<div>消費税の増税に伴う料金の変更のお知らせ 増税後ver</div>
</div>
<div class="topic">
<div class="time">2019/09/23</div>
<div>台風に関する営業時間の変更のお知らせ</div>
</div>
<div class="topic">
<div class="time">2019/08/10</div>
<div>消費税の増税に伴う料金のお知らせ</div>
</div>
<div class="topic">
<div class="time">2019/07/04</div>
<div>公式instagramがオープン</div>
</div>
<div class="topic">
<div class="time">2019/07/03</div>
<div>公式Twitterがオープン</div>
</div>
<div class="topic">
<div class="time">2019/06/20</div>
<div>お部屋をリニューアルしました</div>
</div>
</div>
</aside>
</body>
</html>
@charset "UTF-8";
/* すべての要素に適用 */
* {
box-sizing: border-box;
}
/* ボディの設定 */
body {
position: relative;
margin: 0;
background: black;
display: grid;
grid-template-columns:
[left] 20px [main] 1fr [end] 20px [right];
grid-template-rows:
[header] auto [main] auto [aside] auto [footer] auto [bottom];
}
/* ヘッダー */
header {
position: relative;
grid-column-start: left;
grid-column-end: right;
grid-row-start: header;
grid-row-end: main;
margin-bottom: 100px;
}
header img {
display: block;
width: 100%;
max-height: 100vh;
}
.top-title {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%,50px);
width: 500px;
height: 500px;
background: rgba(255,255,255,.5);
font-size: 50px;
}
/* メディアクエリ */
@media (max-width: 1024px) {
.top-title {
width: 400px;
height: 400px;
font-size: 40px;
transform: translate(-50%,40px);
}
}
@media (max-width: 840px) {
.top-title {
width: 300px;
height: 300px;
font-size: 35px;
transform: translate(-50%,30px);
}
}
@media (max-width: 580px) {
header {
margin-bottom: 60px;
}
.top-title {
width: 250px;
height: 250px;
transform: translate(-50%,25px);
}
}
@media (max-width: 450px) {
.top-title {
width: 200px;
height: 200px;
font-size: 30px;
transform: translate(-50%,20px);
}
}
@media (max-width: 370px) {
.top-title {
width: 150px;
height: 150px;
font-size: 25px;
transform: translate(-50%,15px);
}
}
/* ナビゲーション */
nav {
position: absolute;
top: 0;
left: 0;
right: 0;
}
nav ul {
display: flex;
background: rgba(255,255,255,.7);
margin: 0;
list-style: none;
padding: 0;
font-size: 1.2rem;
}
nav li {
text-align: center;
padding: 10px 0;
width: 80px;
cursor: pointer;
transition: all 1s;
}
nav li:hover {
background: white;
}
/* ナビゲーションモバイル版 */
nav.open {
display: block;
}
/* メディアクエリ */
@media (max-width:840px) {
nav {
position: fixed;
display: none;
}
nav ul {
flex-direction: column;
height: 100vh;
padding-top: 40px;
background: rgba(255,255,255,.9);
}
nav li {
width: 100%;
padding: 20px;
}
}
/* メニューボタン */
.menubutton {
position: fixed;
top: 0;
left: 0;
cursor: pointer;
z-index: 100;
width: 40px;
height: 40px;
padding: 5px;
background: black;
display: none;
}
.menubutton i {
display: block;
width: 30px;
height: 5px;
background: white;
margin-bottom: 7.5px;
}
.menubutton i:last-child {
margin-bottom: 0;
}
/* メディアクエリ */
@media (max-width:840px) {
.menubutton {
display: block;
}
}
/* メイン */
main {
grid-column-start: main;
grid-column-end: end;
grid-row-start: main;
grid-row-end: aside;
margin-bottom: 100px;
}
h1,h2 {
color: white;
text-align: center;
}
.plan {
display: flex;
width: 100%;
max-width: 800px;
margin: 2em auto;
}
.plan img {
display: block;
height: 200px;
}
.plan h2 {
font-size: 20px;
color: black;
}
.plan .comments {
width: 100%;
padding: 0 20px;
background: #cccccc;
}
@media (max-width: 700px) {
.plan {
flex-direction: column;
}
.plan img {
width: 100%;
height: auto;
}
.plan .comments {
padding: 20px;
}
}
/* サイド */
aside {
grid-column-start: main;
grid-column-end: end;
grid-row-start: aside;
grid-row-end: footer;
}
.news {
max-width: 1000px;
border-top: dashed 1px #cccccc;
border-bottom: dashed 1px #cccccc;
margin: 2em auto;
padding: 1em 20px;
color: white;
}
.news .topic {
display: flex;
align-items: center;
padding: 10px;
margin: 1em 0;
border-left: solid 10px #cccccc;
}
.news .time {
margin-right: 1em;
}
@media (max-width: 450px) {
.news .topic {
flex-direction: column;
align-items: flex-start;
}
}
/* フッター */
footer {
grid-column-start: left;
grid-column-end: right;
grid-row-start: footer;
grid-row-end: bottom;
text-align: center;
background: white;
padding: 10px 0;
}

ヒツジのサイトを使ってくれてありがとうございます。

よかったらTwitterでシェアしてくれると嬉しいです!!