本文へ移動

ホーム / Web / 第3部 フロントエンド

第3部 フロントエンド・第4章

HTML・CSS・アクセシビリティ

★★☆ 重要7トピック・面接 3問

画面の土台になる HTML と CSS、誰でも使える画面にするためのアクセシビリティを押さえる。

4.1セマンティックな HTML

用語★★☆ 重要
ひとことで

見た目ではなく意味でタグを選ぶ(button・nav・main・見出しの階層)。支援技術や検索エンジンが正しく理解できる。

セマンティックな HTML とは、見た目ではなく意味に合ったタグを使うことです。<button> はボタン、<nav> はナビゲーション、<h1>〜<h6> は見出しの階層を表します。スクリーンリーダーや検索エンジンは、タグからページの構造を理解します。

button を使えば、最初から全部そろっているdiv + onclick・Tab で移動できない・Enter・Space で押せない・「ボタン」と読まれない・自分で全部足す必要button・Tab で移動できる・Enter・Space で押せる・「ボタン」と読まれる・フォームの送信も扱える
div で作ったボタンと button の違い

div だらけの問題

<!-- よくない -->
<div class="btn" onclick="save()">保存</div>
<!-- よい -->
<button type="button" onclick="save()">保存</button>

div で作ったボタンは、Tab キーで移動できず、Enter や Space で押せず、スクリーンリーダーにも「ボタン」と読まれません。それを補うには tabindex・role・キー操作の処理を自分で足す必要があります。button を使えば最初から全部できます。ページの移動は <a href>、操作は <button> と使い分けます。header・main・footer で領域を示すと、スクリーンリーダーの利用者は目的の場所に飛べます。

面接ではこう答える

セマンティックな HTML とは、見た目ではなく意味に合ったタグを使うことです。ボタンは button、ページの移動は a、見出しは h1 から順に使います。div にクリックを付けたボタンは、Tab で移動できず、Enter で押せず、読み上げでもボタンと分かりません。正しいタグを使えば、キーボード操作や読み上げ、検索エンジンの理解が最初からそろいます。

4.2フォームとラベル

用語★★☆ 重要
ひとことで

label と入力欄を結びつけ、正しい type と autocomplete を付ける。エラーは文字で示して入力欄と結びつける。

フォームは、ユーザーが一番つまずく場所です。正しい HTML で書くだけで、読み上げ・自動入力・スマホのキーボードが効きます。

<label for="email">メールアドレス</label>
<input id="email" type="email" name="email" autocomplete="email" required>
  • label と入力欄を結びつけると、読み上げられ、ラベルを押しても入力欄に移れる。placeholder はラベルの代わりにならない(入力すると消える)。
  • type="email"・tel・number でスマホのキーボードが変わる。autocomplete で自動入力が効く。
  • エラーは色だけでなく文字で示し、aria-describedby で入力欄と結びつける。
  • ラジオボタンのまとまりは fieldset と legend で囲む。
入力使う type・属性効果
メールtype="email" autocomplete="email"@ のあるキーボード、自動入力
電話type="tel" autocomplete="tel"数字のキーボード
ワンタイムコードinputmode="numeric" autocomplete="one-time-code"SMS のコードの候補が出る
パスワードautocomplete="current-password"・new-passwordパスワード管理の自動入力・生成

入力チェックは、送信前にブラウザ(required・pattern)でも行いますが、正しさの保証は必ずサーバーで行います。

面接ではこう答える

フォームでは、まず label と入力欄を for と id で結びつけます。こうするとスクリーンリーダーで読み上げられ、ラベルを押しても入力欄に移れます。type と autocomplete を正しく付けると、スマホのキーボードが変わり、パスワード管理やワンタイムコードの自動入力も効きます。エラーは色だけでなく文字で示し、aria-describedby で入力欄と結びつけます。

4.3Flexbox と Grid

用語★★☆ 重要
ひとことで

Flexbox は1方向、Grid は2方向の配置。中身に合わせて並べるなら Flexbox、枠を先に決めるなら Grid。

1方向に流すか、2方向の枠に入れるかFlexbox(1方向)・横1列・縦1列に並べる・中身の大きさに合わせる・ボタンの並び・中央寄せGrid(2方向)・行と列の枠を先に決める・枠に中身を入れる・ページの枠組み・カード一覧
Flexbox と Grid の考え方の違い

Flexbox と Grid の使い分け

FlexboxGrid
向き1方向(横1列・縦1列)2方向(行と列)
向いているものボタンの並び、ヘッダーの左右寄せ、中央寄せページ全体の枠組み、カードの一覧、フォームの表組み
よく使う指定display:flex; gap; justify-content; align-itemsgrid-template-columns: repeat(auto-fill, minmax(240px, 1fr))

「中身の大きさに合わせて並べる」なら Flexbox、「枠を先に決めて中身を入れる」なら Grid と考えると選びやすいです。余白は margin より親の gap で付けると崩れにくくなります。

面接ではこう答える

Flexbox は横1列や縦1列のように1方向に並べる仕組みで、中身の大きさに合わせて並べるのに向きます。Grid は行と列の2方向の枠を先に決めて、そこに中身を入れる仕組みで、ページの枠組みやカードの一覧に向きます。余白は個々の margin より、親の gap で付けると崩れにくくなります。

ひとことで

画面の幅に応じてレイアウトを変えること。ページはメディアクエリ、部品はコンテナクエリで切り替える。

画面の幅で変えるか、置かれた枠の幅で変えるかメディアクエリ・画面全体の幅で切り替え・ページの段組みに向く・@media (min-width: …)コンテナクエリ・親要素の幅で切り替え・部品の形に向く・@container (min-width: …)
メディアクエリとコンテナクエリの違い
/* 画面の幅で切り替える */
@media (min-width: 768px) { .list { grid-template-columns: 1fr 1fr; } }

/* 置かれた枠の幅で切り替える */
.card-wrap { container-type: inline-size; }
@container (min-width: 400px) { .card { display: flex; } }

メディアクエリは画面全体の幅で、コンテナクエリは親要素の幅で切り替えます。同じカードをサイドバーにもメインにも置くような部品は、コンテナクエリのほうが自然に作れます。スマホから書いて広い画面で足す(min-width)のが一般的です。<meta name="viewport" content="width=device-width, initial-scale=1"> を忘れるとスマホで縮小表示になります。

よくある失敗直し方
viewport の meta がないスマホで縮小表示になる。必ず入れる
幅を px で固定max-width・%・fr・clamp() で伸び縮みさせる
横スクロールが出る長い URL や表は overflow-wrap: anywhere・横スクロールの枠に入れる
押せる場所が小さいタップの対象は十分な大きさに(WCAG 2.2 では 24px 四方が最低ライン)

面接ではこう答える

レスポンシブは、スマホから広い画面まで1つのコードで見やすくすることです。スマホ向けを先に書き、min-width のメディアクエリで広い画面の段組みを足すのが一般的です。同じカードをサイドバーにもメインにも置くような部品は、親要素の幅で切り替えるコンテナクエリのほうが自然に作れます。幅を px で固定せず、fr や clamp で伸び縮みさせるのも基本です。

  • CSS Modules:クラス名をファイルごとに自動で変えて、他の部品と衝突させない。普通の CSS で書ける。
  • Tailwind CSS:flex gap-4 p-2 のような小さなクラスを HTML に並べる。CSS ファイルを行き来せずに済み、デザインのトークン(色・余白)をそろえやすい。クラスが長くなるので部品に切り出す。
  • BEM などの命名規則:仕組みに頼らず名前で衝突を防ぐ。

どれを選ぶかよりも、色・余白・文字の大きさをトークン(CSS 変数など)にまとめて、チームで同じ値を使うことが大事です。

方法向いているチーム
CSS Modules普通の CSS で書きたい。部品ごとにファイルを分ける
Tailwind CSSデザインのトークンをそろえて速く作りたい
CSS-in-JSJS の値でスタイルを変えることが多い(Server Components では使えないものもある)
BEM などの命名仕組みを足さずに、名前のルールで管理したい
ひとことで

障害の有無や環境に関わらず使えるようにすること。キーボード操作・コントラスト・代替テキストが基本。

アクセシビリティ(a11y)は、目が見えにくい・マウスを使えない・色の区別がつきにくいなど、さまざまな人が同じようにサービスを使えるようにすることです。高齢の人や、片手でスマホを操作している人にも役立ちます。

aria は「正しいタグで足りないとき」だけ1. 正しい HTML のタグbutton・a・label・dialog・見出し2. キーボードとフォーカスTab で全部操作・枠を消さない3. 見た目コントラスト・文字の大きさ・色だけに頼らない4. aria 属性状態・名前を補う(最後の手段)
アクセシビリティで手を付ける順番

WCAG の考え方

WCAG は Web のアクセシビリティの国際的なガイドラインで、4つの原則があります。多くの組織は「レベル AA」を目標にします。

原則実装の例
知覚できる画像に alt、文字と背景のコントラスト比 4.5:1 以上(大きな文字は 3:1)、動画に字幕
操作できるキーボードだけで全部使える、フォーカスの枠を消さない、十分な押せる大きさ
理解できるラベルとエラーの説明が分かる、lang="ja" の指定
堅牢正しい HTML で、支援技術が解釈できる

aria 属性は最後の手段

aria-* 属性は、支援技術に役割や状態を伝えるためのものですが、見た目や動きは変えません。<div role="button"> にしてもキー操作は自分で作る必要があります。まず button・a・input・dialog などの正しいタグを使い、それで表せないもの(タブ・開閉の状態 aria-expanded・アイコンだけのボタンの aria-label・読み上げてほしい通知 aria-live)だけに使います。間違った aria は、何もしないより悪くなります。

面接ではこう答える

アクセシビリティは、障害の有無や使う環境に関わらず、誰でも同じようにサービスを使えるようにすることです。国際的なガイドラインの WCAG には、知覚できる・操作できる・理解できる・堅牢、の4つの原則があり、多くの組織はレベル AA を目標にします。まず正しい HTML のタグを使い、キーボードだけで操作できること、文字のコントラスト、代替テキストを押さえます。aria 属性は正しいタグで表せないときの最後の手段です。

自動のチェックで見つかるのは問題の一部です。自動・キーボード・読み上げの3つを組み合わせます。

  • 自動チェック:Chrome の Lighthouse、axe(ブラウザ拡張・テストに組み込む @axe-core/playwright など)。コントラストやラベルの抜けを見つけられる。ただし自動で見つかるのは一部。
  • キーボード:マウスを使わず Tab・Shift+Tab・Enter・Esc で全部操作できるか。モーダルを開いたらフォーカスが中に移り、閉じたら戻るか。
  • スクリーンリーダー:macOS・iOS の VoiceOver、Windows の NVDA で実際に読み上げを聞く。
  • 画面を 200% に拡大して崩れないか。
チェックいつ見つかるもの
axe・Lighthouse(自動)CI・開発中コントラスト不足、ラベルや alt の抜け
キーボードだけで操作画面を作ったときフォーカスが見えない・閉じ込め・順番
スクリーンリーダー主要な画面のリリース前読まれ方・名前の付け方・通知
拡大・文字サイズレスポンシブの確認と一緒に崩れ・はみ出し

この章のまとめ

🖨 まとめシート(印刷・PDF)
  • 意味のある HTML(セマンティクス)とアクセシビリティの基本を説明できる
  • レイアウト(Flexbox・Grid)とレスポンシブの考え方
  • セマンティックな HTML:見た目ではなく意味でタグを選ぶ(button・nav・main・見出しの階層)。支援技術や検索エンジンが正しく理解できる。
  • フォームとラベル:label と入力欄を結びつけ、正しい type と autocomplete を付ける。エラーは文字で示して入力欄と結びつける。
  • Flexbox と Grid:Flexbox は1方向、Grid は2方向の配置。中身に合わせて並べるなら Flexbox、枠を先に決めるなら Grid。
  • レスポンシブ(メディアクエリとコンテナクエリ):画面の幅に応じてレイアウトを変えること。ページはメディアクエリ、部品はコンテナクエリで切り替える。
  • アクセシビリティと WCAG:障害の有無や環境に関わらず使えるようにすること。キーボード操作・コントラスト・代替テキストが基本。

この章のクイズ

面接ではこう聞かれる

まず答えを見ずに声に出して答え、そのあと開いて比べる。

Q1アクセシビリティで気をつけていることは?

模範回答

まず正しいタグを使うことです。操作は button、移動は a、入力欄には label を結びつけ、div にクリックを付けて済ませないようにしています。これでキーボード操作と読み上げの大部分がそろいます。

次にキーボードだけで全部操作できるかを確かめ、フォーカスの枠を消さないこと、モーダルを開いたらフォーカスを中に移して閉じたら戻すことに気をつけています。色はコントラスト比 4.5:1 以上を守り、エラーは色だけでなく文字でも出します。確認は axe を E2E テストに入れて自動で見つつ、重要な画面は VoiceOver で実際に聞いています。aria は正しいタグで表せない所だけに使います。

深掘りされたら

  • アイコンだけのボタンはどう実装しますか?

見られているポイント具体的な実装(キーボード・ラベル・コントラスト)を挙げられるか

Q2Flexbox と Grid はどう使い分けますか?

模範回答

1方向に並べるなら Flexbox、行と列の2方向で枠を決めるなら Grid を使います。例えば、ヘッダーの左右寄せやボタンの並びは Flexbox、カードの一覧やページ全体の枠組みは Grid です。

考え方としては、中身の大きさに合わせて並べたいときは Flexbox、枠を先に決めて中身を入れたいときは Grid です。カードの一覧は grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) と書くと、メディアクエリなしで列の数が画面に合わせて変わります。余白は子の margin ではなく親の gap で付けると崩れにくいです。

深掘りされたら

  • コンテナクエリはどんなときに使いますか?

見られているポイント1方向と2方向の違いを具体例で

Q3div にクリックを付けてボタンを作ると、何が問題ですか?

模範回答

見た目は同じでも、キーボードと支援技術で使えなくなります。div は Tab キーでフォーカスできず、Enter や Space で押せず、スクリーンリーダーにはボタンと読まれません。補うには tabindex・role="button"・キー操作の処理を自分で書く必要があり、漏れやすくなります。

<button type="button"> を使えば、これらが最初からそろいます。ページの移動なら <a href> を使い、操作なら button、と意味で選ぶのが基本です。正しいタグを選ぶことが、アクセシビリティの一番安くて効果の高い対策だと考えています。

深掘りされたら

  • フォームのラベルはどう付けますか?

見られているポイントキーボード操作と読み上げへの影響