見出し画像

【無料コーディング練習】Apple風サイトを作ってみた

実践的なWebサイト制作のスキルを身につけるためのコーディング学習サイト「Codejumpのオフィシャルアカウントです。



前回に引き続き、コーディング練習の第2弾です!!!

前回は、note風のサイトを作りながら2カラムのタイル状レイアウトの勉強をしていきましたね。

まだの方は、今回の学習が終わった後でも大丈夫ですので、ぜひこちらの記事も学習に役立ててくださいね!


さて、今回ですが、言わずと知れた超有名サイト、Apple風サイトの作り方を学習していきたいと思います!

かっこいいですよねー。Appleのサイト。

今回は、そのサイトをベースに、初級者の方でも学習しやすいように複雑な部分を取り除きシンプルに構成しなおした架空のサイトを作っていきます。

完成イメージはこんな感じです!

画像5

※写真はフリー素材を使用しています。


いかがでしょうか?

1カラムのシンプルなサイトですが、今回も学び所は盛りだくさんです!

ちなみに、前回はHTMLとCSSのみでしたが、今回は少しだけjQueryも入れてみました。

スマホのレイアウトの時に、ハンバーガ―メニューを使用しているのですが、そこでjQueryを使用します。

実は、ハンバーガーメニューはjQueryが入るのとCSSが少しややこしくなるので、今回の学習に含めるかどうか最後まで悩んだのですが、この学習の対象者が「これから実践的なサイト制作にチャンレジしていきたい方」だったことを思い出し、入れることにしました!

ちょっと難しい箇所もあるかもしれませんが、その分やり遂げた時のスキルもアップしているはずですので、頑張って最後まで学習してくださいね!

それでは、改めて今回の学習の対象者と学べる内容をまとめておきます。

▼対象者
・HTMLを学習中の初級の方
・HTML、CSSの基礎学習を一通り終えた方(Progateやドットインストールなど)
・そろそろ実践的なサイト制作にチャレンジしていきたい方

▼学べる内容
・1カラムのレイアウト
・固定ヘッダー
・PCとスマホでの画像切り替え
・positionの使い方
・flexboxの使い方
・gridの使い方
・ハンバーガ―メニュー
・レスポンシブデザイン
・実践的なWebサイトの制作

今回は前回よりもさらに長くなっていますので、休憩をとりながら自分のペースで進めていってくださいね。

ちなみに、完成イメージを見て「作れそう」って思った方は、解説を見ずに模写コーディングにチャレンジしていただいてもOKです。
解説を見ずに作り上げることができたら、大きな自信になると思います。

それでは、準備はよろしいでしょうか?

さっそく始めて行きましょう!

学習の流れは下記の通りです。


①:完成イメージの確認

まずは、改めて完成イメージの確認していきましょう!

▼PC表示

画像6


▼スマホ表示

画像7


1カラムのシンプルなレイアウトです。

ハンバーガーメニューが少し難しいですが、それ以外は基礎的な技術だけで全て作ることができます。

コーディングのポイントは下記の通りです。

・画面幅は全幅表示(一部コンテンツは最大980px)
・ヘッダーは固定にする
・グローバルナビは、スマホ時にハンバーガ―メニューに切り替える
・メインビジュアルの画像をPCとスマホで別画像に切り替える
・リンクの右矢印をCSSで実装
・Music、Watch、TV、Storeの4つのボックスはGridを使用
・ブレークポイントは767pxに設定

ちなみに、説明の中で「PCの場合」とか「スマホの場合」という表現が出てきますが、画面幅が768px以上をPCの場合、767px以下をスマホの場合と表現していますのでご注意ください。

それでは、学習に入っていきましょう。

まずは全体のレイアウト構成です!


②:全体のレイアウト構成を確認

画像8

大きく分けて、ヘッダー、メイン、フッターの3つに分かれます。

メインの中はコンテンツが多いですが、ヘッダーとフッターはシンプルですね。

それでは、各パーツのレイアウト構成を確認していきましょう!


③:各パーツのレイアウト構成を確認

■ヘッダー

画像9

全体をheaderタグで囲みます。

ヘッダー全体は黒背景の全幅で表示しますが、ロゴとメニューは980oxの幅におさめて中央に配置したいので、内側全体をdivで囲みます。

ロゴ
h1タグで記述します。

ローバルナビゲーション
全体をnavタグで囲みます。
メニュー部分はul、liタグで記述し、横並びに配置します。

次にMainの中身です。

■セクション(phone)

画像10

全体をsectionタグで囲みます。

タイトルとサブタイトル
セクションのタイトルはh2タグで記述します。
タイトルとサブタイトルは画像の上に重ねて配置します。

■セクション(laptop)

画像11

全体をsectionタグで囲みます。

タイトル
h2タグで記述します。

■セクション(compare)

画像12

全体をsectionタグで囲みます。

タイトル
h2タグで記述します。

プロダクト比較
全体をdivタグで囲み、さらにプロダクト毎にdivタグで囲んでフレックスボックスで横並びに配置します。
プロダクトのタイトルはh3タグ、商品説明部分をul、liタグで記述します。

■collectionエリア

画像13

全体をdivタグで囲み、各sectionをCSSのグリッドで横並びに配置します。
グリッドの詳細については、またコーディングで説明します。

section
Music、Watch、TV、Storeは、それぞれタイトルを含んだ独立したコンテンツになるのでsectionタグで囲みます。

タイトルエリア
テキストを画像の上に配置するために、全体をdivタグで囲みます。
セクションのタイトルはh2タグで記述します。

■フッターエリア

画像14

全体をfooterタグで囲みます。
フッター全体はグレー背景の全幅ですが、中身のコンテンツは980oxの幅におさめて中央に配置したいので、内側全体をdivで囲みます。

テキストエリア
全体をdivタグで囲みます。

メニューエリア
全体と各メニューをそれぞれdivタグで囲み、フレックスボックスで横並びに配置します。

以上でレイアウトは終了です。

前回のコーディング学習でも勉強しましたが、サイト制作においてレイアウト構成を考える作業というのはすごく大切です。

デザインカンプ見たらすぐにコーディングをはじめたくなる気持ちは分かりますが、ちょっと待ってください。

まずは、

・デザインをしっかり確認する
・その後、レイアウトをメモする

この2点を心掛けてみてください。

頭が整理されますし、メモを手もとにおいておくことでコーディングの際のガイドにもなります。

ちなみに、デザインカンプを確認する時のコツと言いますか、こういう視点で確認するとよいという確認ポイントを3点記載しておきます。

デザインの確認
→レイアウトやページの構成はどうなっているか
動きの確認
→スクロール時やマウスオーバー、クリック時の動きはどうなっているか
レスポンシブの確認
→画面サイズがかわったとき、デザインはどのように変化するのか

上記、3点を意識してデザインを確認するとよく理解できます。

それでは、レイアウトの確認も終わりコーディングのイメージがわいてきたところで、いよいよコーディングに入っていきましょう。

まずは、コーディングをはじめる前の作業ディレクトの準備からです!


④:作業ディレクトの作成

今回作るサイトのディレクト構成は下記の通りです。

orange
│
├── css
│   └── style.css
│
├── img
│   │
│   ├── logo.svg
│   ├── favicon.ico
│   ├── phone-pc.jpg
│   ├── phone-sp.jpg
│   ├── laptop-pc.jpg
│   ├── laptop-sp.jpg
│   ├── compare1.jpg
│   ├── compare2.jpg
│   ├── compare3.jpg
│   ├── compare4.jpg
│   └── music.jpg
│   └── watch.jpg
│   └── tv.jpg
│   └── store.jpg
│
├── js
│   └── main.js
│
└── index.html

orangeという名前のフォルダを1個つくり、その中に、index.html、cssフォルダ、imgフォルダ、jsフォルダを作ります。

CSSは、CSSフォルダの中にstyle.cssというファイルを作りここに記述していきます。JavaScriptはjsフォルダの中にmain.jsというファイルを作りその中に記述していきます。

画像については、練習用の画像を用意しましたので、下記からダウンロードしてください。(※完成イメージで使用している画像は、フリー素材のため再配布ができないので、同じサイズで無地の画像を用意しました。)

ダウンロードはこちら

以上でディレクトリの作成は完了です。

それではコーディングを始めていきたいと思いますが、ここからがかなり長いので一旦休憩でもとりましょう!


ブレークタイム ・・・

画像2


さあ!それでは、気合をいれてコーディングにとりかかりましょう!


⑤:全体のHTMLとCSSのコーディング

まずは全体のHTMLとCSSのコーディングです。

▼HTML

<!DOCTYPE html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>コーディング練習用 デモサイト</title>
    <meta name="description" content="テキストテキストテキストテキストテキストテキスト">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="shortcut icon" href="img/favicon.ico">
    <link rel="stylesheet" href="https://unpkg.com/ress/dist/ress.min.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="js/main.js"></script>
  </head>

  <body>
    <!-- ヘッダー -->
    <header id="header">
    </header>

    <!-- メインコンテンツ -->
    <main id="main">
    </main>

    <!-- フッター -->
    <footer id="footer">
    </footer>
  </body>

</html>

metaタグ
title、descriptionは基本必須で設定します。(今回は、練習用なので適当なテキストを設定しています。)

リセットCSS
ここは人によって好みや使いやすいものがあると思いますので、実際の制作の際は好きなものを使用してください。
今回は、「ress.min.css」を使用しています。

JQuery
今回はjQueryを使用しますので、「jquery.min.js」の読み込みを行います。
バージョンは現時点の最新版3.5.1です。

main.js
ハンバーガ―メニューを実装するのにJQueryを記述するためのファイルを読み込みます。

▼CSS

@charset "UTF-8";

html {
 font-size: 100%;
}
body {
  font-family: "ヒラギノ角ゴ Pro W3", "Meiryo", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
  color: #1d1d1f;
}
a {
  color: #06c;
  text-decoration: none;
}
img {
  max-width: 100%;
}
li {
  list-style: none;
}
.wrapper {
  max-width: 980px;
  padding: 0 22px;
  margin: 0 auto;
}
.link-more {
  font-size: 14px;
  position: relative;
}
.link-more::after {
  position: absolute;
  top: 54%;
  right: -12px;
  width: 7px;
  height: 7px;
  transform: translateY(-50%) rotate(45deg);
  border-right: 2px solid currentColor;
  border-top: 2px solid currentColor;
  content: "";
}
.link-more:hover {
  text-decoration: underline;
}

/*-------------------------------------------
メイン
-------------------------------------------*/

#main {
  padding-top: 44px;
}

順に確認していきましょう。

フォントサイズや画像など前回の学習と重複している箇所は、既に学習済みの方は復習程度に軽く流してください。

■フォントサイズ

html {
  font-size: 100%;
}

htmlのフォントサイズを100%で指定しておくことで、ユーザーがブラウザで設定したフォントサイズが正しく反映されるようになります。

■画像

img {
  max-width: 100%;
}

レスポンシブで作る場合、全ての画像にmax幅を100%で指定しておくことで、親のコンテンツから画像がはみ出すのを防げます。

■コンテンツ幅

.wrapper {
  max-width: 980px;
  padding: 0 22px;
  margin: 0 auto;
}

コンテンツの最大幅を指定しているクラスです。
コンテンツ幅の指定を複数個所でしたい場合、このような共通で使えるクラスを1つ作っておくことで、色々なところで使いまわすことができます。


■リンク(Learn more)

.link-more {
  font-size: 14px;
  position: relative;
}
.link-more::after {
  position: absolute;
  top: 54%;
  right: -12px;
  width: 7px;
  height: 7px;
  transform: translateY(-50%) rotate(45deg);
  border-right: 2px solid currentColor;
  border-top: 2px solid currentColor;
  content: "";
}
.link-more:hover {
 text-decoration: underline;
}

compareセクションとcollectionエリア内で使用しているこちらのリンクです。

画像15

今回は勉強もかねて、リンクの右矢印をCSSの疑似要素「after」で実装してみました。

矢印の位置
positionを使用してリンクからの位置を指定しています。
.link-more の「position: relative;」を基準にして、.link-more::after の「position: absolute;」で矢印の位置を調整しています。

矢印を作る
「border-right」「border-top」で右と上に線を引き、「transform: ~」で上への移動と45度の回転を行い矢印にしています。

矢印の長さ
widthとheightで矢印の長さを指定しています。

ちなみに矢印ついては、CSSで表現する以外にも画像を使用したりFont Awesomeを使用する等、色々な表現方法があります。

今回は、勉強のためにCSSで作成してみましたが、このような簡単な記号がCSSで作れるようになると、コーディングの幅も広がります。

特に、疑似要素transformの使い方を覚えておくと実務でもできることが増えますので、ぜひ覚えておいてくださいね。

全体のコーディングはここまでです。

続いて、ヘッダーのコーディングです!


⑥:ヘッダーのコーディング

▼HTML

<header id="header">
  <div class="header-inner wrapper">
    <h1 class="logo"><a href="#"><img src="img/logo.svg" alt="テキストテキスト"></a></h1>

    <nav id="navi">
      <ul>
        <li><a href="#">PC</a></li>
        <li><a href="#">Phone</a></li>
        <li><a href="#">Watch</a></li>
        <li><a href="#">TV</a></li>
        <li><a href="#">Music</a></li>
        <li><a href="#">Service</a></li>
        <li><a href="#">Support</a></li>
      </ul>
    </nav>

    <div class="hamburger">
      <span></span>
      <span></span>
    </div>
  </div>
</header>

ロゴ
h1タグで記述します。
altも忘れず設定しましょう。

グローバルナビゲーション
navタグで囲み、メニューをul、liタグで記述します。
前回もふれましたが、グローバルナビゲーションで、このnav、ul、liタグの組み合わせはよく使うので、覚えておくと便利です。

ハンバーガ―メニュー
スマホ用のハンバーガーメニューです。
詳細は、一番最後の「⑫ハンバーガ―メニューのコーディング」で解説します。

▼CSS

/*-------------------------------------------
ヘッダー
-------------------------------------------*/

#header {
  width: 100%;
  background-color: #000;
  position: fixed;
  z-index: 10;
}

#header .header-inner {
  height: 44px;
  display: flex;
  align-items: center;
}

#header .header-inner .logo {
  flex-shrink: 0;
  width: 16px;
  line-height: 1px;
  margin-right: 9%;
}

#navi {
  width: 100%;
}

#navi ul {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

#navi a {
  height: 44px;
  line-height: 44px;
  display: inline-block;
  color: #f5f5f7;
  font-size: 14px;
  padding: 0 10px;
  opacity: 0.8;
  transition: all 0.5s;
}

#navi a:hover {
  opacity: 1;
}
.hamburger {
 display: none;
}

順に確認していきましょう。

■ヘッダー全体

#header {
  width: 100%;
  background-color: #000;
  position: fixed;
  z-index: 10;
}

#header .header-inner {
  height: 44px;
  display: flex;
  align-items: center;
}

ヘッダー全体を全幅の黒背景にして、「position: fixed;」で固定します。
ヘッダーを固定する時の注意点として、スクロールした際にヘッダーがコンテンツで隠れてしまう場合があるので、「z-index」で重なり順を指定しておきます。数値が大きい方が上になります。
ちなみに、z-indexで指定する数値は、間に追加のコンテンツが入ることを想定して、連番ではなく10とか間隔をあけた番号にしておくのがおすすめです。

header-innerに「display: flex;」を指定して、ロゴとグローバルナビゲーションを横並びに配置します。

■グローバルナビゲーション

#navi ul {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

#navi a {
  height: 44px;
  line-height: 44px;
  display: inline-block;
  color: #f5f5f7;
  font-size: 14px;
  padding: 0 10px;
  opacity: 0.8;
  transition: all 0.5s;
}

#navi a:hover {
  opacity: 1;
}

ulタグに「display: flex;」を指定してメニューを横並びに配置します。

opacity
aタグに「opacity: 0.8;」を指定することで、文字を少し透過に設定し、マウスオーバー時に「opacity: 1;」を設定してもとに戻します。
この方法により、メニューの文字が少し透明がかった状態から、マウスオーバーの際に白く変化するような見せ方ができます。

transition

変化をアニメーションで表現するためのプロパティです。
今回は、aタグに「transition: all 0.5s;」を指定しているので、メニューにマウスオーバーした際の文字カラーの変化を0.5秒かけて行います。
ふわっとした動作を表現したい時に使える技です。
今回のようにマウスオーバーの際に使用することがよくあるので、覚えておくと役立ちます。

■ハンバーガーメニュー

.hamburger {
  display: none;
}

PC表示の場合は、ハンバーガーメニューを表示させないので、「display: none;」で非表示にしています。


⑦セクション(phone)のコーディング

▼HTML

<section id="phone">
  <h2 class="headline">Phone XX Pro</h2>
  <p class="subhead">New Model.</p>
</section>

セクション全体をsectionタグで囲みます。

タイトルをh2タグ、サブタイトルをpタグで記述します。

▼CSS

/*-------------------------------------------
Phone
-------------------------------------------*/

#phone {
  background-image: url(../img/phone-pc.jpg);
  background-size: cover;
  background-position: center;
  height: 580px;
  margin-bottom: 45px;
  position: relative;
}

#phone .headline {
  color: #f5f5f7;
  font-size: 56px;
  font-weight: bold;
  position: absolute;
  top: 40px;
  left: 0;
  right: 0;
  text-align: center;
}

#phone .subhead {
  color: #f5f5f7;
  font-size: 28px;
  font-weight: bold;
  position: absolute;
  top: 125px;
  left: 0;
  right: 0;
  text-align: center;
}

/*-------------------------------------------
レスポンシブ
-------------------------------------------*/
@media screen and (max-width: 767px) {
  #phone {
    background-image: url(../img/phone-sp.jpg);
  }
  #phone .headline {
    font-size: 32px;
  }
  #phone .subhead {
    font-size: 19px;
    top: 88px;
  }
}

順に確認していきましょう。

■背景画像

#phone {
  background-image: url(../img/phone-pc.jpg);
  background-size: cover;
  background-position: center;
  height: 580px;
  margin-bottom: 45px;
  position: relative;
}

background-image → 背景画像を設定
background-size: cover → 画像の縦横比を維持したままできるだけ大きく表示できるように拡大縮小する
background-position: center → 画像を中央に配置

■タイトル

#phone .headline {
  color: #f5f5f7;
  font-size: 56px;
  font-weight: bold;
  position: absolute;
  top: 40px;
  left: 0;
  right: 0;
  text-align: center;
}

#phone .subhead {
  color: #f5f5f7;
  font-size: 28px;
  font-weight: bold;
  position: absolute;
  top: 125px;
  left: 0;
  right: 0;
  text-align: center;
}

ポイントはpositionを使用して、タイトルの表示位置を調整しているところです。

セクション全体の#phoneに「position: relative;」、タイトルのクラス .headline にposition: absolute;を指定することで、このセクションを基準にして、タイトルの表示位置を調整しています。
今回は、「top: 40px;」で上から40pxの位置、「left: 0;」「right: 0;」「text-align: center;」で中央に配置しています。

サブタイトルも同様に設定します。


⑧セクション(laptop)のコーディング

▼HTML

<section id="laptop">
  <h2 class="headline">What makes you beautiful.</h2>
  <picture>
    <source media="(max-width: 767px)" srcset="img/laptop-sp.jpg">
    <img src="img/laptop-pc.jpg" alt="テキストテキストテキスト">
  </picture>
</section>

セクション全体をsectionタグで囲みます。

タイトルをh2タグで記述します。

画像については、pictureタグを使用してPCの時とスマホの時とで表示する画像を切り替えます。

PCの場合
sourceタグで設定している「laptop-sp.jpg」を表示します。
「media="(max-width: 767px)"」で、767px以下の場合という条件を指定しています。max-widthでの指定も可能です。

スマホの場合
imgタグで設定している「laptop-pc.jpg」を表示します。

※pictureタグはIEには対応していないので、IEの場合はJavaScriptを使用する等の考慮が必要です。

<補足メモ>
レスポンシブの画像切り替えで、もう1つよく使用する方法として、「display: none」で、2つの画像の表示、非表示を切り替える方法があります。
ただし、こちらの方法は画面を表示する際に常に2つの画像が読み込まれるため、切り替えを行う箇所が複数ある場合や画像のサイズが大きい場合は画面表示に負担がかかるので、IEに対応しないのであればpictureタグの使用がおすすめです。

▼CSS

/*-------------------------------------------
laptop
-------------------------------------------*/

#laptop {
  margin-bottom: 80px;
}

#laptop img {
  width: 100%;
  max-width: 1920px;
  height: 500px;
  object-fit: cover;
}

#laptop .headline {
  font-size: 48px;
  font-weight: bold;
  text-align: center;
  margin-bottom: 40px;
}

/*-------------------------------------------
レスポンシブ
-------------------------------------------*/
@media screen and (max-width: 767px) {
  #laptop .headline {
    font-size: 32px;
  }
}

■画像のトリミング

object-fit: cover;」で画像の縦横比を維持しながらはみ出る部分をトリミングしてくれます。
今回は高さを500pxで固定しているので、500pxからはみ出る部分がトリミングされています。


⑨セクション(compare)のコーディング

▼HTML

<section id="compare" class="wrapper">
  <h2 class="headline">Which Phone is right for you?</h2>
  <a class="models" href="#">Compare all Phone models</a>

  <div class="compare-list">
    <div class="item">
      <img src="img/compare1.jpg" alt="">
      <h3 class="item-title">Phone X1</h3>
      <ul>
        <li>テキストテキストテキスト<br>テキストテキスト</li>
        <li>テキストテキストテキスト<br>テキストテキスト</li>
        <li>テキストテキストテキスト<br>テキストテキスト</li>
      </ul>
      <a class="link-more" href="#">Learn more</a>
    </div>

    <div class="item">
      <img src="img/compare2.jpg" alt="">
      <h3 class="item-title">Phone X2</h3>
      <ul>
        <li>テキストテキストテキストテキストテキストテキスト</li>
        <li>テキストテキストテキストテキストテキストテキスト</li>
        <li>テキストテキストテキストテキストテキストテキスト</li>
      </ul>
      <a class="link-more" href="#">Learn more</a>
    </div>

    <div class="item">
      <img src="img/compare3.jpg" alt="">
      <h3 class="item-title">Phone X3</h3>
      <ul>
        <li>テキストテキストテキストテキストテキストテキスト</li>
        <li>テキストテキストテキストテキストテキストテキスト</li>
        <li>テキストテキストテキストテキストテキストテキスト</li>
      </ul>
      <a class="link-more" href="#">Learn more</a>
    </div>

    <div class="item">
      <img src="img/compare4.jpg" alt="">
      <h3 class="item-title">Phone X4</h3>
      <ul>
        <li>テキストテキストテキストテキストテキストテキスト</li>
        <li>テキストテキストテキストテキストテキストテキスト</li>
        <li>テキストテキストテキストテキストテキストテキスト</li>
      </ul>
      <a class="link-more" href="#">Learn more</a>
    </div>
  </div>
</section>

全体をsectionタグで囲みます。

タイトル
h2タグで記述します。

プロダクトリスト(compare-list)
各プロダクトをフレックスボックスで横並びに配置するために、プロダクトリスト全体をdivタグで囲みます。

プロダクト(item)
各プロダクトをdivタグで囲みます。
タイトルはh3タグで記述し、その下のプロダクト情報はリスト形式になっているのでul、liタグを使用して記述していきます。
aタグには全体のCSSで定義した、link-moreクラスを指定します。

▼CSS

/*-------------------------------------------
Compare
-------------------------------------------*/

#compare {
  margin-bottom: 80px;
}

#compare .headline {
  font-size: 48px;
  font-weight: bold;
  text-align: center;
  margin-bottom: 10px;
}

#compare .models {
  display: block;
  font-size: 24px;
  text-align: center;
  margin-bottom: 40px;
}

#compare .models:hover {
  text-decoration: underline;
}

#compare .compare-list {
  display: flex;
  justify-content: space-between;
}

#compare .item {
  padding: 20px;
}

#compare .item li {
  font-size: 14px;
  margin-bottom: 20px;
}

#compare .item .item-title {
  font-size: 24px;
  font-weight: bold;
  margin: 20px 0;
}

/*-------------------------------------------
レスポンシブ
-------------------------------------------*/
@media screen and (max-width: 767px) {
  #compare .headline {
    font-size: 32px;
  }
  #compare .models {
    font-size: 21px;
  }
  #compare .compare-list {
    flex-wrap: wrap;
  }
  #compare .item {
    width: 50%;
    padding: 10px;
  }
  #compare .item .item-title {
    font-size: 19px;
  }
}

順に確認していきましょう。

■タイトル下のリンク

#compare .models {
  display: block;
  font-size: 24px;
  text-align: center;
  margin-bottom: 40px;
}

「display: block;」でブロック要素に変更してから、「text-align: center;」を指定して中央に配置しています。

■プロダクトリスト 

#compare .compare-list {
  display: flex;
  justify-content: space-between;
}

/*-------------------------------------------
レスポンシブ
-------------------------------------------*/
@media screen and (max-width: 767px) {
  #compare .compare-list {
    flex-wrap: wrap;
  }
  #compare .item {
    width: 50%;
    padding: 10px;
  }
}

「display: flex;」で横並びに設定し、「justify-content: space-between;」で両端に揃うように間隔を均等に配置します。

画面幅が767px以下の場合は、「flex-wrap: wrap;」で折り返し指定を行い、各プロダクトの横幅を50%にすることで、2列の横並びに変化させています。


⑩collectionのコーディング

▼HTML

<div id="collection">
  <!-- Music -->
  <section class="music item">
    <div class="copy">
      <h2 class="headline">Music</h2>
      <p class="subhead">The music you love.</p>
      <a class="link-more" href="#">Learn more</a>
    </div>
  </section>

  <!-- Watch -->
  <section class="watch item">
    <div class="copy bg-dark">
      <h2 class="headline">Watch</h2>
      <p class="subhead">Anytime. Anywhere.</p>
      <a class="link-more" href="#">Learn more</a>
    </div>
  </section>

  <!-- TV -->
  <section class="tv item">
    <div class="copy bg-dark">
      <h2 class="headline">TV</h2>
      <p class="subhead">Watch Amazing Stories.</p>
      <a class="link-more" href="#">Learn more</a>
    </div>
  </section>

  <!-- Store -->
  <section class="store item">
    <div class="copy">
      <h2 class="headline">Store</h2>
      <p class="subhead">Get more out of your phone.</p>
      <a class="link-more" href="#">Learn more</a>
    </div>
  </section>
</div>

全体をdivタグで囲みます。

Music、Watch、TV、Storeの各コンテンツをsectionタグで囲みます。

タイトルはh2タグ、サブタイトルはpタグ、リンクはaタグで記述します。
上記のテキスト群はまとめて位置調整を行うために、copyというクラス名のdivタグで囲んでおきます。

▼CSS

/*-------------------------------------------
Collection
-------------------------------------------*/

#collection {
  display: grid;
  gap: 12px;
  grid-template-columns: 1fr 1fr;
  margin-bottom: 12px;
}

#collection .music {
  background-image: url(../img/music.jpg);
}

#collection .watch {
  background-image: url(../img/watch.jpg);
}

#collection .tv {
  background-image: url(../img/tv.jpg);
}

#collection .store {
  background-image: url(../img/store.jpg);
}

#collection .item {
  background-size: cover;
  background-position: center;
  height: 520px;
  position: relative;
}

#collection .item .copy {
  position: absolute;
  bottom: 50px;
  left: 0;
  right: 0;
  text-align: center;
}

#collection .item .bg-dark {
  color: #fff;
}

#collection .item .headline {
  font-size: 48px;
  font-weight: bold;
  line-height: 1.2;
}

#collection .item .subhead {
  font-size: 20px;
  font-weight: bold;
  margin-bottom: 7px;
}

/*-------------------------------------------
レスポンシブ
-------------------------------------------*/
@media screen and (max-width: 767px) {
  #collection {
    grid-template-columns: 1fr;
  }
  #collection .item .headline {
    font-size: 32px;
  }
  #collection .item .subhead {
    font-size: 19px;
  }
}

順に確認していきましょう。

■グリッドレイアウト

#collection {
  display: grid;
  gap: 12px;
  grid-template-columns: 1fr 1fr;
  margin-bottom: 12px;
}

4つのセクションの並びはグリッドレイアウトを使用します。

display: grid; → グリッドレイアウト
gap: 12px; → 行と列の隙間
grid-template-columns: 1fr 1fr; → 同幅で2列に並べる

@media screen and (max-width: 767px) {
  #collection {
    grid-template-columns: 1fr;
  }
}

画面幅が767px以下の場合は、「grid-template-columns: 1fr;」で1列に配置します。

グリッドレイアウトについては、奥が深いのでここでは詳細は割愛しますが、時間がある際にぜひ調べてみてください!

■背景画像

#collection .music {
  background-image: url(../img/music.jpg);
}

#collection .watch {
  background-image: url(../img/watch.jpg);
}

#collection .tv {
  background-image: url(../img/tv.jpg);
}

#collection .store {
  background-image: url(../img/store.jpg);
}

各セクションの背景画像を設定します。

#collection .item {
  background-size: cover;
  background-position: center;
  height: 520px;
  position: relative;
}

背景画像のプロパティについては、全てのセクションで同じ設定を使いたいので、itemとう名前のクラスを1つ作り共通で使用します。

background-size: cover; → 画像の縦横比はそのままで、できるだけ大きくなるよう拡大縮小する
background-position: center; → 中央に配置
height: 520px; → 画像の高さを固定

position: relative;
背景画像の上にテキストを配置するための基準を設定しておきます。

■テキストの配置

#collection .item .copy {
  position: absolute;
  bottom: 50px;
  left: 0;
  right: 0;
  text-align: center;
}

「position: absolute;」を指定することで、先ほど背景画像で指定した「position: relative;」を基準にしてテキストの位置を設定します。
今回は下から50pxの中央に配置します。

#collection .item .bg-dark {
  color: #fff;
}

WatchとTVセクションは背景が暗いので、bg-darkという文字を白色に設定したクラスを適用します。

collectionのコーディングは以上です。

これでMainのコンテンツは全て終了しました。

ようやく終わりが見えてきましたねw

残すはフッターとハンバーガ―メニューだけですので、あと少し頑張っていきましょう!


⑪フッターのコーディング

▼HTML

<footer id="footer">
  <div class="wrapper">
    <div class="text-area">
      <p>
        テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<br>
        テキストテキストテキストテキストテキストテキストテキストテキスト
      </p>
      <p>テキストテキストテキストテキストテキストテキストテキストテキスト</p>
      <p>テキストテキストテキストテキストテキストテキストテキストテキスト</p>
    </div>

    <div class="footer-menu">
      <!-- 製品情報と購入 -->
      <div class="menu">
        <p class="title">製品情報と購入</p>
        <ul>
          <li><a href="#">Desktop</a></li>
          <li><a href="#">Wraptop</a></li>
          <li><a href="#">Phone</a></li>
          <li><a href="#">Watch</a></li>
          <li><a href="#">TV</a></li>
          <li><a href="#">Music</a></li>
        </ul>
      </div>

      <!-- サービス -->
      <div class="menu">
        <p class="title">サービス</p>
        <ul>
          <li><a href="#">Music</a></li>
          <li><a href="#">TV</a></li>
          <li><a href="#">Arcade</a></li>
          <li><a href="#">Pay</a></li>
          <li><a href="#">Books</a></li>
        </ul>
      </div>

      <!-- Store -->
      <div class="menu">
        <p class="title">Store</p>
        <ul>
          <li><a href="#">オンラインで購入</a></li>
          <li><a href="#">分割でのお支払い</a></li>
          <li><a href="#">ご注文状況</a></li>
          <li><a href="#">ご利用ガイド</a></li>
        </ul>
      </div>

      <!-- サポート -->
      <div class="menu">
        <p class="title">サポート</p>
        <ul>
          <li><a href="#">修理オプション</a></li>
          <li><a href="#">サービス情報</a></li>
          <li><a href="#">ハードウェア保証</a></li>
          <li><a href="#">無償サポート</a></li>
        </ul>
      </div>
    </div>
    <p class="copyright">Copyright © 2020 Sample Site</p>
  </div>
</footer>

フッター全体をfooterタグで囲みます。

中のコンテンツは980oxの幅におさめて中央に配置したいので、内側全体をdivタグのwrapperクラスで囲みます。

テキストエリア
テキストを段落ごとにpタグで囲みます。

フッターメニュー
各メニューごとにdivタグで囲み、中はul、liタグで記述します。

▼CSS

/*-------------------------------------------
フッター
-------------------------------------------*/

#footer {
  width: 100%;
  background-color: #f5f5f7;
  color: #86868b;
  font-size: 12px;
  padding: 20px 0;
}

#footer .text-area {
  border-bottom: 1px solid #d2d2d7;
}

#footer .text-area p {
  margin-bottom: 20px;
}

#footer .footer-menu {
  display: flex;
  border-bottom: 1px solid #d2d2d7;
  padding-bottom: 20px;
  margin-bottom: 10px;
}

#footer .footer-menu .menu {
  width: 25%;
}

#footer .footer-menu .title {
  color: #1d1d1f;
  font-weight: bold;
  margin-top: 20px;
}

#footer .footer-menu li {
  margin-top: 10px;
}

#footer .footer-menu a {
  color: #86868b;
}

#footer .footer-menu a:hover {
  text-decoration: underline;
}

#footer .copyright {
  font-size: 12px;
}

/*-------------------------------------------
レスポンシブ
-------------------------------------------*/
@media screen and (max-width: 767px) {
  #footer .footer-menu {
    flex-wrap: wrap;
  }
  #footer .footer-menu .menu {
    width: 50%;
  }
}

フッター部分のポイントは、下記のフッターメニューのみです。

■フッターメニュー

#footer .footer-menu {
  display: flex;
  border-bottom: 1px solid #d2d2d7;
  padding-bottom: 20px;
  margin-bottom: 10px;
}

#footer .footer-menu .menu {
  width: 25%;
}

/*-------------------------------------------
レスポンシブ
-------------------------------------------*/
@media screen and (max-width: 767px) {
  #footer .footer-menu {
    flex-wrap: wrap;
  }
  #footer .footer-menu .menu {
    width: 50%;
  }
}

フッターメニューは、お馴染みのフレックスボックス「display: flex;」での横並び配置です。
各メニューの横幅を25%に設定することで、4つを横に並べています。

レスポンシブでは、各メニューの横幅を「width: 50%;」で50%に設定し、「flex-wrap: wrap;」で折り返しの指定を行うことで、2列の表示に変化させています。

以上でフッターは終了です。

最後はいよいよハンバーガ―メニューです。

ここから少しややこしくなりますが、順を追って理解していけば難しくありません。

それではいきましょう!


⑫ハンバーガ―メニューのコーディング

最後はハンバーガ―メニューのコーディングになります。

まずは動きを確認しておきましょう。

▼メニューが閉じている状態

画像4

右側の2重線のボタンを押すと、上からメニューがおりてきて下のような状態になります。

▼メニューが開いている状態

画像4

この状態でもう一度ボタンを押すと、メニューが上へ隠れます。

こんか感じのハンバーガ―メニューを作っていきます。

これだけ見ると何から手をつけていいか悩んでしまいそうですが、コーディングのポイントは下記の3点だけです。

1.ハンバーガ―メニューのボタンを表示する
2.ボタンを押すとボタンのデザインが2重線から×に変わり、もう一度押すと2重線に戻る
3.ボタンを押すと上からメニューが出ててきて、もう一度押すと上へ戻る

この3点だけです。

複雑な処理をコーディングする場合は、こんな感じで1作業ごとに細分化してやることを考えると頭が整理できます。

それでは上記のポイントにしたがって、確認していきましょう。

まずは、ボタンの表示からです。

1.ハンバーガ―メニューのボタン

▼HTML

<div class="hamburger">
  <span></span>
  <span></span>
</div>

headerタグの中にある、hamburgerというクラスがハンバーガーメニューのボタンです。
spanタグ1行がボタンの線1つに対応しており、spanタグを2つ記述することで2重線を表現しています。線はCSSで引いていきます。

▼CSS

@media screen and (max-width: 767px) {
  .hamburger {
    width: 44px;
    height: 44px;
    display: block;
    position: fixed;
    top: 0;
    right: 8px;
    z-index: 20;
    cursor: pointer;
  }
  .hamburger span {
    width: 16px;
    height: 1px;
    background: #fff;
    position: absolute;
    left: 14px;
    transition: 0.3s ease-in-out;
  }
  .hamburger span:nth-child(1) {
    top: 18px;
  }
  .hamburger span:nth-child(2) {
    top: 26px;
  }

 ・
 ・
 ・
 
}

.hamburger
「position: fixed;」でボタンを右端に固定します。
スマホ時は「display: block;」を設定して表示させます。

.hamburger span
「position: absolute;」で、ボタン全体に対する線の位置を指定します。
「transition: 0.3s ease-in-out;」はボタンがクリックされた時に×に変わる変化の速度です。今回は0.3秒で変化させます。

.hamburger span:nth-child(1)
1つめの線の上からの位置を指定します。

.hamburger span:nth-child(2)
2つめの線の上からの位置を指定します。

これでハンバーガ―メニューのボタンができあがりました。

次に、ボタンをクリックした時に×に変化させる処理について確認していきましょう。

2.ボタンをクリックした時に×に変化させる

まずは、×のCSSを記述しておきます。

▼CSS

@media screen and (max-width: 767px) {

・
・
・

  .hamburger.active span:nth-child(1) {
    top: 22px;
    transform: rotate(-45deg);
  }
  .hamburger.active span:nth-child(2) {
    top: 22px;
    transform: rotate(45deg);
  }
}

先ほどのボタンのCSSに「.active」というクラス名を追加した新しい定義を作り、ここに×のスタイルを記述していきます。

.hamburger.active span:nth-child(1)
1つ目の線は、「top: 22px;」で線の位置を少し上にあげて、「transform: rotate(-45deg);」で左に45度回転させることで右肩あがりの線を作ります。

.hamburger.active span:nth-child(2)
2つ目の線は、「top: 22px;」で線の位置を少し下に下げて、「transform: rotate(45deg);」で右に45度回転させることで右肩さがりの線を作ります。

上記の2つが重なりあうことで×ができあがります。

続いて、ボタンがおされた時に×のCSSに切り替える処理です。

もう一度、2重線のCSSと×のCSSを見比べてみてください。

2重線のCSS
.hamburger span:nth-child(1)
.hamburger span:nth-child(2)

×のCSS
.hamburger.active span:nth-child(1)
.hamburger.active span:nth-child(2)

×のCSSには「.active」というクラスが追加されていますね。

実は、ボタンが押された際にjQueryでボタンのdivタグに active というクラスを追加することで、上記のactiveがついた×のCSSが適用される仕掛けになっているのです。

下記のようなイメージです。

【ボタンが押される前】

▼HTML
<div class="hamburger">
  <span></span>
  <span></span>
</div>

▼2重線のCSSが適用されている
.hamburger span:nth-child(1)
.hamburger span:nth-child(2)

【ボタンが押された後】

▼HTML
<div class="hamburger active">
  <span></span>
  <span></span>
</div>

▼×のCSSが適用される
.hamburger.active span:nth-child(1)
.hamburger.active span:nth-child(2)

いかがでしょうか、イメージがわきましでしょうか?

ボタンが押される前は、activeがついていない2重線用のCSSが適用されているけど、ボタンが押されたタイミングでdivタグに active というクラスが追加されるため、適用されるCSSがactiveがついている×のCSSに切り替わります。

ちなみに、activeがついている状態でもう一度ボタンを押すと、今度はjQueryでactiveというクラスを削除するので、またactiveがついていない方のCSSが適用されるという仕組みです。

要は、jQueryでactiveというクラスをつけたりはずしたりすることで、参照するCSSを切り替えているということですね。

ここのjQueryのソースコードについては後ほど確認していきますので、最後のボタンをクリックしたタイミングで上からメニューがおりてくる処理を確認していきましょう。

3.ボタンをクリックすると上からメニューが出ててくる

まずは、上から出てきた時に表示されるメニューのCSSを記述します。
HTMLについては、PC表示用のグローバルメニューと同じなので、CSSでレイアウトの変更を行っていきます。

▼CSS

/*-------------------------------------------
レスポンシブ
-------------------------------------------*/
@media screen and (max-width: 767px) {
  /*-------------------------------------------
  ヘッダー
  -------------------------------------------*/
  #header .header-inner .logo {
    z-index: 20;
  }
  #navi {
    position: fixed;
    background: #000;
    top: 0;
    left: 0;
    transform: translateY(-100%);
    transition: all 0.6s;
    z-index: 10;
  }
  #navi a {
    font-size: 12px;
    padding-left: 0;
  }
  #navi ul {
    flex-direction: column;
    padding: 44px 40px 0 40px;
    text-align: left;
  }
  #navi ul li {
    width: 100%;
    border-bottom: solid 1px #f5f5f7;
  }
  #navi ul li:last-child {
    border-bottom: none;
  }
  #navi.active {
    transform: translateY(0%);
  }
} 

PC表示の時はメニューは横並びですが、スマホ表示では縦並びのメニューに変化させます。

#navi ul
メニューに「flex-direction: column;」を指定することで、横並びから縦並びに変更します。

#navi ul li
「border-bottom: solid 1px #f5f5f7;」で各メニューの下に下線を引きます。

#navi ul li:last-child
メニューの最後は「border-bottom: none;」で下線を消します。

後はフォントサイズやパディングの調整を行うことで、スマホ用のメニューができあがります。

次に、上から出てくるという動きを設定します。

ポイントとなる下記の太字のコードです。


#navi {
  position: fixed;
  background: #000;
  top: 0;
  left: 0;
  transform: translateY(-100%);
  transition: all 0.6s;
  z-index: 10;
}

#navi.active {
  transform: translateY(0%);
}

順に解説していきます。

まず「.active」についてですが、これについては先ほどのボタンの仕組みと同じです。
ボタンがおされた際にjQueryでnavタグにactiveとうクラスを追加しています。

下記のようなイメージになります。

【ボタンが押される前】

<nav id="navi">
  ・・・
</nav>

【ボタンが押される後】

<nav id="navi" class="active">
  ・・・
</nav>

続いて、transform~ についてです。

まず、#navi で設定している「transform: translateY(-100%);」ですが、縦方向の移動を表します。ここでは、-100%を指定しているので、メニューが上へ100%移動して隠れた状態になります。

続いて、#navi.active ですが、こちらは「transform: translateY(0%);」で、0%を指定しているので、もとに位置で表示されます。

つまり、ボタンが押される前は、.active がついていない #navi の方のCSSが適用されるのでメニューが上に隠れている状態で、ボタンが押されるたタイミングで activeがついている #navi.active のCSSが適用されるので、メニューがもとの位置までおりてきて表示されるという仕組みになります。

先ほどのボタンの表示を切り替える仕組みと同じですね。

こちらも、jQueryでactiveというクラスをつけたりはずしたりすることで、参照するCSSを切り替えています

それでは、最後にactiveのつけはずしを行っているjQueryを見ていきましょう。

▼jQuery

$(function() {

  $('.hamburger').click(function() {

    $(this).toggleClass('active');

    if ($(this).hasClass('active')) {
      $('#navi').addClass('active');
    } else {
      $('#navi').removeClass('active');
    }

  });
});

1行づつ確認していきましょう。

$(function() { ~ }
JQueryの処理は基本的にはこの中に記述します。
HTMLが読み込まれたタイミングで、ここの中身が処理されます。

$('.hamburger').click(function() { ~ }
hamburgerというクラス名の要素がクリックされたタイミングで、この中に記述された処理が実行されます。
この中にactiveクラスを追加、削除する処理を書いていきます。

$(this).toggleClass('active');
ボタン用のdivにactiveの追加、削除を行う処理です。
$(this)は、ここでは$('.hamburger')を指します。
toggleClassは、jQueryで用意されているクラスの追加、削除を行うためのメソッドです。指定したクラス名が存在していれば削除、存在しなければ追加という処理を自動でやってくれます。便利ですね!

if ($(this).hasClass('active')) {
  $('#navi').addClass('active');
} else {
  $('#navi').removeClass('active');
}

メニューにactiveの追加、削除を行う処理です。
1行目の「if ($(this).hasClass('active')) {」で、ボタン用のdivにactiveというクラスが追加されているか判定を行い、追加されている場合は、2行目の「$('#navi').addClass('active');」で、navタグにもactiveを追加します。
ボタン用のdivにactiveというクラスがなかった場合は、4行目の「$('#navi').removeClass('active');」でnavタグからもactiveを削除します。

以上で、ハンバーガ―メニューのコーディングは終了です。

はじめてハンバーガ―メニューを作った方は少し難しく感じたかもしれませんが、一度理解してしまえばなんてことはありません。

ハンバーガ―メニューは、色々なデザインや動きのものがありますが、今回学習した仕組みでできているものは結構多いです。

ネットで検索したらハンバーガーメニューのサンプルコードがたくさん出てきますので、時間がある時に他のデザインのものも作ってみてくださいね!

それでは、以上で今回の学習は全て終了になります。

最後まで本当にお疲れ様でした!


最後に・・・

今回の学習はいかがでしたでしょうか?

1カラムのシンプルなサイトですが、学べることが沢山あったのではないでしょうか。

今回学習した内容を簡単に振り返ってみましょう。

・固定ヘッダの作り方
・画像に文字を重ねる(positionを使用)
・pictureタグを使用したPCとスマホでの画像切り替え
・右矢印をCSSで実装
・疑似要素の使い方
・背景画像のプロパティ(background~)
・Flexboxの使い方
・Gridの使い方
・transitionの使い方
・ハンバーガ―メニューの作り方(jQueryを使用)
・レスポンシブのコーディング

けっこう、たくさん勉強していますね!

上記の内容の中で、もし理解があいまいなところがあったら重点的に学習しておいてください。実務でもよく使うものが多いです。

特にハンバーガ―メニューについては、使用しているサイトも多いのでしっかり復習しておいてくださいね。

今回の学習で使用したソースコードは下記からダウンロードできますので、よかったら学習の参考にしてください。

ダウンロードはこちら
(※画像についてはフリー素材を使用しており再配布ができないので、同じサイズで無地の画像に置き換えています。)

ハンバーガ―メニューなど、動きのある個所については実際に動かしながら、ディベロッパーツールなどで確認してみるとわかりやすいかと思います。

Web制作のスキルアップの近道は、とにかく1つでも多くのサイトを作ることです。

今回の学習をステップにして、これからも色々なサイト制作にチャレンジしていってください!

もし今回のnoteが「参考になったよ~」と思った方は、スキボタンとTwitterで他の学習中の方に紹介していたけると有難いです!

Twitterの方でも、Webサイト制作に関するTipsや、エンジニア、フリーランスに関することなどを日々発信していますので、ぜひフォローをお願いいたします!

Twitter:@codestep_com

それでは、今回も最後までお付き合いいただきまして、本当にありがとうございました!

ではまた次回!!!

--------------------------------------------------
Codejump - 作って学ぶコーディング学習サイト
https://code-jump.com/

HTML、CSS、JavaScriptの基礎学習を終えた方が、模写コーディングやデザインカンプからのコーディングを通してより実践的なWebサイト制作のスキルを身につけるための学習サイトです。【入門編~上級編】まで難易度別に無料でコーディングの学習ができます。

Codejump Pro - 実案件をモデルにしたコーディング学習サービス
https://code-jump.com/cp/

企業からのコーディング案件受注を想定した、実践的なコーディング学習サービスです。単価、納期、納品方法、デザイン、仕様など、全て実際の案件をもとにして作られた仮想案件に毎月1件チャレンジできます。
--------------------------------------------------

この記事が気に入ったらサポートをしてみませんか?