【第4回】メディアクエリとは?レスポンシブデザインのサイトを作るための必須知識を解説!

※本記事は「HTML&CSS 基礎講座(全4回)」の第4回目の内容を踏まえて作成しています

最終回となる第4回目は、今まで作ったサイトをレスポンシブ対応に仕上げました。最終回ですが、擬似クラス、擬似要素、メディアクエリといった現場でも必須の知識が盛りだくさんです。また最後には、少し難易度の高いハンガーバーメニューの作成にも挑戦するので、CSSの自由度の高さを実感できる内容となっています。

本講座では、講座内容をただの知識で終わらせないために、講座参加者自身が実際に1つのサイトを作ることをゴールとしています。本記事でHTML&CSSを勉強する人も、実際に手を動かしてみることをおすすめします。自分で記述したHTML&CSSがブラウザにちゃんと反映されていると、格別の達成感を得られるはずです。

擬似クラス

擬似クラスとは、要素が特定の状態にある時にスタイルを指定できるセレクタです。「特定の状態」というのは、「要素の上にポインターがあるとき」などのユーザーの動きに対応したものや、「親要素の中で〇番目の要素」などで、20種類以上が指定可能です。

使い方は以下の例のように、要素の直後にコロン(:)を付けます。半角スペースも必要ありません。

上の画像では、:hoverという擬似クラスを付与することで、「<a>にポインターが乗った時に文字色を赤に変更」という指定をしています。

前回までの実演で、ある程度の体裁を整えることができましたが、擬似クラス(そして後述する擬似要素)を上手く利用することで、さらに表現の幅を広げることができます。また、ユーザーの動きに対してインタラクティブにスタイルの変更が行えるようになるため、ユーザビリティ(ユーザーにとっての使いやすさ)の向上にも寄与します。

擬似クラスには以下のようなものがあります。

よく使うもの:link未訪問のリンクに対して指定する
:visited訪問済みのリンクに対して指定する
:hoverマウスを当てた状態に対して指定する
:activeマウスをクリックして話すまでの状態に対して指定する
その他A:not(B)A要素の中のB要素以外に指定
:nth-child(n)親要素の中のn番目の要素を指定
:nth-of-type(n)親要素の中の同じ要素のn番目を指定
:targetリンク先のターゲットにスタイルを指定

なお、擬似クラスでスタイルを指定する場合は、効果の重複や排他性に注意しなければなりません。たとえば、上の表のうち「よく使うもの」に挙げた擬似クラスを全て使う場合は、表の通りの順番で記述する必要があります。

なぜなら、CSSは下に書いたものを優先的に上書きする特性があるためです。つまり:hoverを:linkの上に記述してしまうと、未訪問のリンクがある場合、:link内の記述が優先され、その要素に対しては:hoverで指定したスタイルが適用されなくなってしまうのです。

プロパティの場合でも同様ですが、やはりCSSでは使用するものの効果を良く理解して使うことが重要となります。

擬似要素

擬似要素とは、要素の一部に対してスタイルを指定できるセレクタです。擬似要素を用いることで、HTMLへの要素の追加などを行わずに、CSS側で擬似的に要素を追加して装飾が行えます。たとえば、「タイトルの上に英題を入れる」「吹き出しを付ける」「見出しに画像を追加する」などです。

使い方は以下の例の通り、要素のあとに2つのコロン(::)を付けて記述します。下の画像の::afterと並んで、::beforeという擬似要素も良く使われます。

文字を入れる場合はダブルクォテーションの中にテキストを入れればよいですが、画像を入れたい場合はダブルクォテーション内を空にして、background-imageプロパティを用います。

なお擬似要素はHTMLに反映されないため、検索にも引っかかりません。したがって、擬似要素はあくまで装飾目的で用いるのが基本です。

メディアクエリ

メディアクエリとは、画面サイズに応じてスタイルを変更できるセレクタです。近年は様々なタイプのデバイスが普及しているため、メディアクエリを活用してレスポンシブ対応のサイトを作成することが必須となっています。書き方の例は以下の通りです。

スタイルは{}の中に記述します。また()の中の記述が適用する画面サイズの範囲となります。上記の例ではmax-widthとしたので、画面サイズ599px以下では{}の中のスタイルが適用されます。その他にも、min-widthで指定する方法や、両者を組み合わせた指定方法があり、まとめると以下の通りです。

(max-width:〇〇px)画面サイズ〇〇px以下に適用
(min-width:●●px)画面サイズ●●px以上に適用
(min-width:●●px) and (max-width:〇〇px)画面サイズ●●px以上、〇〇px以下に適用

本講座ではこれまでPCでの表示を基準にCSSを適用してきたので、以降の実演ではmax-widthでメディアクエリを指定し、特定の画面サイズ「以下」のスタイルを追記していきます。

逆にスマホで見ることを前提とするサイトを作る場合は、始めにスマホの表示を基準にメインのスタイルを記述し、その後、min-widthのメディアクエリで特定の画面サイズ「以上」のスタイルを追記するパターンもあります。

なお、〇〇(または●●)にあたる数値はブレイクポイントと呼ばれ、推奨される値は毎年変化します。需要のあるデバイスサイズが変動するためです。推奨値はその都度確認するようにしましょう。

VScode実演

では以上で説明した新しい情報を存分に用いて、ユーザビリティが高く、かつ現在必須のレスポンシブ対応のサイトに仕上げていきます。

まずは、講座内では第4回目までの課題だった「<nav>の<a>にポインターが乗った時に、背景色を#a89797、フォントを白になる」という挙動を実装していきます。

  1. 【課題】

正しく記述すると、最終的に以下のような挙動になります。

CSSは以下の通りです。記述する場所に決まりはありませんが、ある程度のまとまりを持たせるために、「nav a」の後に新しくセレクタを追加するのが良いでしょう。追加で記述したのは、選択中の範囲です。

【CSS】

・nav a:hover

先に解説した疑似クラスを用いています。「nav a」に適用するスタイルではありますが、純粋な「nav a」とは別に「nav a:hover」を用意しなければなりません。とはいえ、その中はいつも通りの記述です。

  • <h2>の直後に画像を追加する

続いて各<section>の見栄えをよくするために、<h2>の下に次のように、足跡の画像を追加します。

CSSは次の通りです。セレクタ「h2」の直後に記述を追加するのが良いでしょう。

【CSS】

・セレクタ「h2::after」

足跡の画像は擬似要素を使って挿入しましょう。今回は完成画像の通り<h2>の直後に足跡の画像が入るので、「::after」で要素を擬似的に追加します。

・17行目 display: block;

擬似的に追加する要素をブロックレベル要素に設定することで、以降のwidthやheightを指定できるようにします。その上で、幅・高さを設定したボックスの中に画像(background-image)を収めるイメージです。

・22〜24行目

background-sizeプロパティの値にcontainを指定することで、挿入する画像の縦横比を維持したまま、画像全体が見える大きさに変更します。

また背景画像はデフォルトで左上に配置されるようになっているため、background-positionプロパティでcenterに配置します。さらに、背景画像はデフォルトで繰り返しが行われるので、今回はbackground-repeatで画像の繰り返しをなし(no-repeat)に変更しましょう。

レスポンシブデザインにする

以上までで一通りPC版の表示は完成しました。しかし、現状のコードのままスマホでサイトを開くと表示が崩れてしまいます。レスポンシブデザインにしていないためです。デベロッパーツール(開発ツール)を使って、スマホの表示を確認してみましょう。デベロッパーツールを開いて、次の画像にあるスマホ(タブレット?)のマークを選択してください。

動画のように サイトの画面上部に出てくる横長のバーの上でポインターを動かしてみると、「Tablet」や「MobileS」「MobileM」といった文字が現れます。これらを選択すると、タブレットの表示や標準サイズのスマホ、小さめサイズのスマホにおける実際の表示を確認することができるのです。または次の動画上部にある「Responsive▼」でも、主要メーカーのスマホ(タブレット)の表示に変更することができます。

では、今回はiPhoneXでの表示を見てみましょう。

表示が大きく崩れています。以降ではSP版(スマートフォン版)の表示を見ながら、崩れている箇所や見づらい箇所を1つずつ修正していきます。

  • SP版CSSのエリアを作成

SP版のCSSはPC版とは別に記述する必要があるので、まずはSP版のCSSを記述するエリアを作成していきます。以下の画像は、これまで記述してきたCSSの最後に書き加えています。

【CSS】

画像の中括弧の中に、これまでのようにセレクタ・プロパティ・値を記述していきます。今回は「@media screen and (max-width:599px)」として、「幅599pxまでのビューポートでは、以下の記述を適用する」という指定を行っています。

以降は特に指摘がない限り、メディアクエリの{}の中に記述していきます、

  • SP版の共通項目のCSSを記述

まずはPC版でも行ったように、SP版でも共通項目に適用するCSSを記述します。次の画像は修正後のブラウザ上の表示です。分かりづらいですが、フォントサイズ、足跡の画像の大きさを変更しています。

先述の通り、CSSは@media〜{}の中括弧の中に記述します。「SP共通項目」というコメントもメディアクエリ内の記述です。

【CSS】

  • SP版のメイン画像・ロゴを作成

次はヘッダ−のうちメイン画像とロゴをSP版に修正します。

画像が縦長になっていますが、HTMLにスマホ用の画像も挿入します。しかし、PC用とスマホ用の画像が2つ挿入されることになるため、CSSではビューポートのサイズに応じて表示させる画像と表示させない画像を設定する必要があります。

【HTML】

【CSS】

・HTMLへの追記

元々あったメイン画像の下に、「sp-main.png」を追加します。また1つの<div>に2つの<img>が入ることになるので、それぞれに新たなclass属性を与えます。PC版は「class=”main pc-only”」、SP版は「class=”main sp-only”」としましょう。

・ロゴのサイズを変更(CSS画像1枚目)

CSSの画像1枚目は、SP版のロゴのサイズを変更する内容です。PC版で指定したabsoluteはここでも適用されているため、ここでもtopとleftを指定することができます。

・PC版メイン画像とSP版メイン画像の切り替え(CSS画像2、3枚目)

まずは「SP共通項目」で、PC版メイン画像(.pc-only)をdisplay: none;とすることで、PC版メイン画像の表示がなくなります。

同時にビューポートが600px以上の場合には、SP版のメイン画像の表示を消さなくてはなりません。そこで画像3枚目の通り、SP版メイン画像(.sp-only)に対してdisplay: none;を適用しましょう。なお、3枚目は「共通項目」のエリアに記述しています。

  • SP版「お知らせ」エリアのCSS

では、「お知らせ」エリアにSP版のCSSを適用していきます。まずはブラウザ上の表示を確認しましょう。

PC版で横並びにしたお知らせ(<ul>)と猫の画像(<img>)が、SP版では縦並びです。さらに、お知らせのタグ(<span>)が左寄せになるなどの細かい修正を行っています。

【CSS】

・.news-topics

flex-wrap: wrap;によって、<ul>と<img>を縦並びにしています。以前にも出てきたflex-wrapプロパティはフレックスアイテムの並びを制御するものです。ところが画像内では.news-topicsをFlexbox化するような記述はありません。

しかし、すでにPC版で<ul>と<img>を横並びにするため、.news-topicsにdisplay: flex;を記述しFlexboxにしたのでした(「お知らせ」内の記述を確認)。つまり、PC版CSSで<div class=”news-topics”>の子要素をフレックスアイテムにしたことによって、SP版でもflex-wrapの適用が可能になっているのです。

以上のように、レスポンシブ対応にする際は、PC版とSP版それぞれに適用したCSSの影響関係を考えながらコーディングする必要があります。

・.news-topics img/ul

2つのセレクタに与えたorderプロパティは、アイテムの並び順を指定するものです。重ね順を指定するz-indexプロパティとは異なり、値の数値の昇順に配置されます。つまり、数字が小さい順に並べられるのです。

・.tag

お知らせの種類を区分けしている<span>の位置を修正するために、一度ブロックレベル要素に変更します。その後、margin/paddingをリセットしています。

  • 「ドマーニャのメンバー」エリアのSP版CSS

次は大きな崩れの原因となっている「ドマーニャのメンバー」に、SP版のCSSを適用していきます。ブラウザ上の表示は以下の通りです。

画像が枠内に収まり、画像サイズも小さくなっています。また、「もっと見る」ボタンの横幅も広くなっています。

【CSS】

・.member ul

画像の並びが大きく横に伸びてしまっているのは、PC版の.member ulでwidthを大きく928pxと設定していることが原因となっています。そこでSP版ではwidthをautoに変更します。

その他はスマホ上の表示に合った余白・サイズを設定する記述です。

  • 「私たちについて」エリアのSP版CSS

次は「私たちについて」を整えていきます。ブラウザ上の表示は以下の通りです。

基本的に高さ、フォントサイズ等をスマホの画面に合わせていきます。

【CSS】

・.about/.about-container

PC版では.aboutのheightを100vhとしていたため、スマホで表示すると縦長に見えてしまいます。そこで.aboutとその中の.about-containerの高さの調整が必要となります。

・.about-container p/.about img

この2つのセレクタでも、フォントサイズと画像サイズをそれぞれ調整します。

  • 「営業時間・アクセス」エリアのSP版CSS

「営業時間・アクセス」については簡単に余白を修正するだけです。

左側と右側の間の余白が広すぎるため、住所が改行されてしまっています。そこで右側(<dd>)のmarginを調整します。

【CSS】

  1. フッターのSP版CSS

ではフッターを調整していきます。ブラウザ上の表示は次の通りです。

少し分かりづらいですが、ロゴのサイズとコピーライトの改行が無くなっています。

【CSS】

・footer/footer img

PC版ではpadding上下左右を30pxとしていますが、SP版では左右のpaddingの影響でコピーライトが改行されています。そこで左右のpaddingは0にします。

ロゴ画像も少し小さいので、スマホの表示に合わせた調整を行います。

SP版ナビゲーションメニューの作成

では最後に少し難易度は高くなりますが、「CSSではこんなこともできる」という意味合いも込めて、ナビゲーションメニューをスマホサイトによくあるハンガーバーメニューにします。最終的には次のような挙動になります。

ハンガーバーメニューの作成は手順が複雑になるので、順を追って説明します。

  1. HTMLへの追記

後から別の場所に少しだけ追記しますが、まずは以下の画像の通り編集します。

まずは<nav>のすぐ下に、<div id=”open” class=”btn sp-only”>を書き足します。SP版ではこの<div>のエリアにナビゲーションメニューが表示されます。またsp-onlyとしており、PC版共通項目のCSSで.sp-onlyをdisplay: none;と記述しているため、600px以上ではこのエリアは表示されません。

さらに<div id=”open”>の直下に、<ul>を含めるように<div id=”g_menu”>を作ります。そして、その中には<div id=”close” class=”btn sp-only”>を追加します。

追記した内容のうち、ham-line/ham-line2というクラスを付けた要素がハンガーバーになります。

  1. 白背景のナビゲーションメニュー

次に白背景のナビゲーションメニューを作成します。次の画像の内、1枚目は「SPヘッダー」、2・3枚目は新たに作成した「SPナビ」エリア内の記述です。

・header/nav

まずはSP版の<header>を基準に(relative)、<nav>全体を絶対配置(absolute)できるようにCSSを適用します。

・#g_menu

#g_menuの「#」を使ったセレクタの指定方法は、HTMLでid属性を付けた要素に対して行うものです。

さて、#g_menuはナビゲーションメニューが表示される半透明の白い背景にあたる箇所となります。今回はbackground-colorはrgbaで設定します。rgb(赤・緑・青)で白を作り、aで透明度を指定することが可能です。

また、position: fixed;とすることで、ナビゲーションメニューを開いた状態でスクロールしても、背景のサイトだけ動いてナビゲーションメニュー自体は画面上に固定されます。そして画面いっぱいに表示させるため、widthとheightを100%にし、最前面に来るようにz-indexプロパティで大きい値を設定します。

・nav ul

PC版でナビゲーションメニューの上下に表示されていたボーダーを消去します。

・nav a

PC版ではナビゲーションメニューを横並びにするためにインライン要素にしましたが、SP版では縦並びにするためにブロックレベル要素に変更します。

・3枚目の画像

3枚目の画像は、SP版ナビゲーションメニューを開くためのハンガーバー(ham-line)に関する記述です。(閉じる用のハンガーバーはham-line2です)。

まずセレクタが列挙された箇所では、ハンガーバーに共通のスタイル(横棒の色、幅と高さなど)を記述します。::beforeや::afterのような擬似要素は、ハンガーバーの2本目、3本目にあたるものです。

ハンガーバーに共通のスタイルを記述したら、その下で.ham-line::before(2本目)と.ham-line::after(3本目)に別々の位置を指定します。

以上で白背景のナビゲーションメニューの作成はできました。しかし、以上の記述だけではナビゲーションメニューが動的に開閉する挙動は実現できていません。

  1. ハンガーバーを選択−>ナビゲーションメニューの表示

そこで次は、先ほど作成した開く用のハンガーバーをクリックすると、白背景のナビゲーションメニューが表示されるように記述します。画像は「SPナビ」の中に記述しています。

・#g_menu:not(:target)/#g_menu:target

:target/:not(:target)とは、要素を選択中か選択中でないかによって適用するスタイルを分岐させる擬似クラスです。上の画像では、選択中でない(:not(:target))時に右側の画面外に隠します。マイナスにすることで、基準となる要素の外部に位置を指定することができるのです。一方で選択中(:target)のときに表示させるようにしています。

以上の記述だけで、ナビゲーションメニューの表示/非表示を切り替えられるようになります。しかし、現状では切り替えが速すぎて不自然です。そこで-100%の位置から0の位置への移動が滑らかになるような記述を追加します。すでに作成済みのセレクタ#g_menuの最後に、transition: right 1s;を書き足すだけです。

transitionプロパティは、特定のプロパティの値が変化するときの時間を指定して、アニメーションを実現するプロパティです。画像の通り、値は「対象とするプロパティ」と「変化の時間」で指定します。今回は#g_menu:not(:target)/:targetのrightプロパティにおいて、0↔−100%の変化に1秒(1s)かけるようにしました。

  1. closeボタン(×)の作成

次はナビゲーションメニューの右上にcloseボタン(×)を作成します。以下は.ham-line::afterの直後に記述しています。

・ham-line2/.ham-line2::before/.ham-line2::after

先述のham-lineと同じ要領ですが、×印は二本線で構成されているので、1本目の線(.ham-line2)のrgbaを全て0にして見えない状態にします。その上で.ham-line2の::beforeと::afterで×印を作成していきます。

×印は、まずtopとrightを::beforeと::afterで同じ値にし、2本の線が重なった状態でそれぞれを違う方向に45度回転させることで作成できます。そして、要素を回転させるプロパティがtransformです。今回は::beforeの線を正方向に45度、:afterの線を負方向に45度回転させています。

以上の記述によって、次のような×印が表示されます。

  1. ハンガーバーを画面右上に固定する

現状では、サイトをスクロールするとサイトが上に流れていくのに合わせてハンガーバーも上に隠れてしまいます。そこで次は、スクロールに対してハンガーバーが画面右上に固定されるように調整します。以下は#g_menu:target直下の記述です。

HTMLを確認すると、ナビゲーションメニューを開くためのハンガーバー<div class=”ham-line”>は、<div id=”open”〜>に包含されています。そのため、#openに位置の指定とposition: fixed;を与えることで、実際のハンガーバーにあたる要素(<div class=”ham-line”>)を指定した位置に固定することができるのです。

  1. ナビゲーションメニューの各項目にジャンプする挙動の作成

ナビゲーションメニューの各項目(「ドマーニャのメンバー」や「営業時間・アクセス」など)は、それぞれ同一ページ内の<h2>に対応しています。しかし、現状は各項目を選択してもページ最上部に戻るような動きになっているため、それぞれに対応する<h2>の場所にジャンプするような修正が必要です。

必要な措置は、ナビゲーションメニューの各項目を対応する<h2>(正確には<section>)とリンクさせることです。これはHTML内で完結させることができ、ポイントはid属性となります。

画像の順番とは前後しますが、まずは<section class=”member”>にid=”2”を、<section class=”access”>にid=”3”を追加します。その上で1枚目の画像の通り、対応する<a>のhrefをそれぞれ「#2」と「#3」としましょう。こうすることで、ナビゲーションメニューの各項目と<section>がリンクします。

以上の記述だけでもページ内リンクは機能しますが、切り替えが速すぎるのでユーザビリティは良いとは言えません。そこで仕上げに、スムーズに遷移が行われるようにCSSを変更します。

追記はscroll-behavior: smooth;のみです。scroll-behaviorプロパティでスクロールの振る舞いを指定することができます。今回はsmoothという値にしました。

まとめ

最終回となる本記事でも、擬似クラス、擬似要素、メディアクエリなどの現場では必須の知識が出てきました。また、ハンガーバーメニューを作成する過程では、CSSでアニメーションを実装するためのプロパティ(transitionなど)を紹介しました。すぐに使いこなすのは困難ですが、どれもモダンなサイトを作る上で必須の知識です。

以上で全4回のHTML&CSS基礎講座は終了となります。HTMLとCSSはどんなもので、何ができるのかは分かったと思います。しかし、継続して手を動かさなければ仕事で使えるレベルにはならず、すぐに忘れてしまうはずです。それではもったいないので、次は模写コーディングなどを行ってさらなるスキルアップを目指しましょう。