STEP 1 / HTML

ページの意味を、
先に決める。

HTML は見た目を作る言語ではありません。「ここは見出し」「ここは段落」「ここは移動先のあるリンク」と、文書の意味と構造を書き記すための言語です。ここを丁寧にやっておくと、あとの CSS と JavaScript が驚くほど楽になります。

目次を開く(全 14 章)

各コードの「⬇ 保存」を押すと、そのままダブルクリックで開ける HTML ファイルとして保存できます。書き換えて試してみてください。

01

HTML は「意味」を書くもの

Web ページは 3 つの言語でできています。役割ははっきり分かれていて、混ぜると後で必ず困ります。まずはこの分担を頭に入れてください。

HTML

構造・意味

「これは見出し」「これは一覧」「これは送信ボタン」。文書が何でできているかを書きます。拡張子は .html

CSS

配置・装飾

色・文字の大きさ・並べ方。HTML に書いた要素を、どう見せるかだけを担当します。拡張子は .css

JS

動き・処理

押されたら開く、入力を計算する、データを取ってくる。あとから状態を変える係です。拡張子は .js

なぜ意味が大事なのか

見た目だけなら、すべて <div> でも CSS で似せられます。けれど検索エンジン・読み上げソフト・キーボード操作・ブラウザの翻訳機能は、 タグの意味を手がかりに動いています<button> と書けば Enter キーで押せる。<div> ではそうなりません。正しいタグを選ぶことは、自分で機能を書かずに済ませるための近道でもあります。

02

最小の HTML 文書

メモ帳でもエディタでも構いません。次の内容を index.html という名前で保存し、ダブルクリックすればブラウザで開けます。これが出発点です。

HTML
<h1>はじめてのページ</h1>
<p>これは段落です。HTML はこうやって書きます。</p>

上の枠が、実際にブラウザが表示した結果です。文字の大きさや余白は、何も指定しなくてもブラウザが付けてくれます。

ただし、実際のファイルには外側の決まり文句が必要です。全体はこうなります。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>はじめてのページ</title>
</head>
<body>
  <h1>はじめてのページ</h1>
  <p>これは段落です。HTML はこうやって書きます。</p>
</body>
</html>
<!DOCTYPE html>
「これは今の HTML です」という宣言。1 行目に必ず書きます。これが無いと、ブラウザが古い互換モードで表示してしまいます。
<html lang="ja">
文書全体の入れ物。lang でページの言語を伝えます。読み上げの発音や自動翻訳の判断に使われるので、必ず書きます。
<head>
画面には出ない設定置き場。文字コード、タイトル、CSS の読み込みなどを書きます。
<body>
画面に表示される中身。以降に書く見出しや段落は、すべてこの中に入ります。
ファイル名の約束

ファイル名は半角英数字・小文字・ハイフンで付けます(about-us.html)。日本語やスペースは、公開したときにリンク切れの原因になります。そしてトップページのファイル名は index.html。これはサーバーが自動で開いてくれる決まった名前です。

04

タグの書き方

HTML は要素を積み重ねて書きます。要素は「開始タグ・中身・終了タグ」の 3 つでできています。

HTML
<p class="lead">これが中身です</p>
 ↑     ↑                    ↑
開始タグ 属性              終了タグ

<!-- 中身を持たない「空要素」は終了タグを書かない -->
<img src="cat.jpg" alt="窓辺で眠る猫">
<br>
<hr>

<!-- 入れ子は、開いた順と逆の順で閉じる -->
<p>これは <strong>とても <em>大事</em></strong> です。</p>

<!-- コメント。メモを残せる(画面には出ないが、閲覧者からは読める) -->
  • 属性は開始タグの中に 名前="値" の形で書きます。値は必ず引用符で囲みます。
  • 入れ子の順序を守ります。<p><strong>…</p></strong> は間違いです。
  • インデント(字下げ)は半角スペース 2 個が一般的。ブラウザは気にしませんが、人が読めなくなります。
  • HTML では、連続した半角スペースや改行はまとめて 1 個の空白として表示されます。余白は CSS で作ります。
日本語では、改行する位置に注意

ソースの改行が半角スペース 1 個になるのは、英語なら単語の区切りとして都合がよい仕様です。 けれど日本語では困ります。文の途中で改行すると、そこに余分な空白が入ってしまうからです。

たとえば …4 つだけ決め、 で改行して次の行を 名前は… から書き始めると、 画面では読点のあとに半角スペース 1 個ぶん(文字の約 3 分の 1)の隙間が空きます。 コードを読みやすくするつもりの改行が、そのまま表示に出てしまうわけです。

対策は簡単で、日本語の文はソースでも 1 行で書くこと。 どうしても折り返したいときは、タグの区切りなど空白が入ってよい位置で改行します。 英語と日本語が混ざる部分(<code>margin</code> の値 など)は、 もともと空白を入れたい場所なので気にしなくて構いません。

05

ページの骨組み

<body> の中は、いきなり本文を書き始めるのではなく、 意味を持った箱で区切ります。これがセマンティック(意味的)なマークアップです。

HTML
<header>
  <h1>山田製作所</h1>
  <nav>
    <ul>
      <li><a href="/">ホーム</a></li>
      <li><a href="/about">会社概要</a></li>
      <li><a href="/contact">お問い合わせ</a></li>
    </ul>
  </nav>
</header>

<main>
  <article>
    <h2>新しい工場が完成しました</h2>
    <p>2026 年 4 月、第 2 工場の稼働を開始しました。</p>
  </article>

  <section>
    <h2>採用情報</h2>
    <p>現在、製造スタッフを募集しています。</p>
  </section>
</main>

<aside>
  <h2>関連リンク</h2>
  <p>本文の補足や広告など、本筋から少し外れる内容。</p>
</aside>

<footer>
  <p>© 2026 山田製作所</p>
</footer>
<header>
そのページ(またはその記事)の導入部。ロゴ・サイト名・ナビゲーションなど。
<nav>
主要なリンクのまとまり。ページ内のすべてのリンクを囲む必要はありません。
<main>
そのページの主役。1 ページに 1 つだけ。「本文へスキップ」の飛び先にもなります。
<article>
それだけ切り出しても意味が通るまとまり。記事・投稿・商品カードなど。
<section>
意味のある区切り。見出しとセットで使うのが原則です。
<aside>
本筋から外れる補足。サイドバー、関連記事、広告など。
<footer>
締めくくり。著作権表示、サイトマップ、連絡先など。
<div> / <span>
意味を持たない箱。他に当てはまるタグが無いときだけ使います。div がブロック、span が文中の一部分。
section と div の選び方

迷ったら「そこに見出しを付けられるか」で判断します。付けられるなら <section>、単に CSS で囲みたいだけなら <div> です。

06

見出しと文章

見出しは <h1> から <h6> まであり、 本の目次と同じ階層を表します。大きく見せたいから <h1>、ではありません。大きさは CSS の仕事です。

HTML
<h1>料理の基本</h1>
<p>毎日の食事づくりを、少し楽にするための覚え書きです。</p>

<h2>だしをとる</h2>
<p>だしは <strong>味の土台</strong> です。ここを丁寧にやると、
  調味料は <em>ぐっと少なく</em> て済みます。</p>

<h3>昆布だし</h3>
<p>水 1L に対して昆布 10g。<mark>沸騰させない</mark>のがコツです。</p>

<blockquote>
  <p>火加減は、鍋の底に小さな泡が並ぶくらい。</p>
</blockquote>

<p>公開日:<time datetime="2026-04-01">2026 年 4 月 1 日</time></p>
  • <h1> はそのページの題名。1 ページに 1 つが基本です。
  • 階層を飛ばさないh2 の次にいきなり h4 は避けます。
  • <strong> は「重要」、<em> は「強調」。太字・斜体にしたいだけなら CSS で。
  • 改行したいだけで <br> を並べない。段落が変わるなら <p> を分けます。

07

リストと表

並んでいるものはリストにします。順番に意味があるなら <ol>、無いなら <ul>。表は「行と列に意味があるデータ」にだけ使い、レイアウト目的では使いません。

HTML
<h2>買うもの(順不同)</h2>
<ul>
  <li>昆布</li>
  <li>かつお節</li>
  <li>醤油</li>
</ul>

<h2>作る手順(順番が大事)</h2>
<ol>
  <li>昆布を水に 30 分つける</li>
  <li>弱火にかける</li>
  <li>沸騰する直前に取り出す</li>
</ol>

<h2>用語</h2>
<dl>
  <dt>だし</dt>
  <dd>素材のうまみを水に移したもの。</dd>
  <dt>下ごしらえ</dt>
  <dd>調理の前に行う準備。</dd>
</dl>

<h2>営業時間</h2>
<table>
  <caption>店舗の営業時間</caption>
  <thead>
    <tr><th scope="col">曜日</th><th scope="col">開店</th><th scope="col">閉店</th></tr>
  </thead>
  <tbody>
    <tr><th scope="row">平日</th><td>9:00</td><td>18:00</td></tr>
    <tr><th scope="row">土曜</th><td>10:00</td><td>16:00</td></tr>
  </tbody>
</table>

表の scope は「この見出しは列(col)か行(row)か」を伝える属性です。読み上げソフトが正しく案内できます。

08

リンクと画像

リンクは Web の心臓部です。<a>移動するもの<button>その場で何かを起こすもの。ここを取り違えないでください。

HTML
<!-- 同じサイトの中へ -->
<a href="about.html">会社概要</a>

<!-- ページ内の場所へ(id を目印にする) -->
<a href="#contact">お問い合わせへ</a>

<!-- 外部サイトを別タブで開くときは rel をセットで -->
<a href="https://example.com" target="_blank" rel="noopener noreferrer">外部サイト</a>

<!-- 電話とメール -->
<a href="tel:0312345678">03-1234-5678</a>
<a href="mailto:info@example.com">メールを送る</a>

<!-- 画像。alt・width・height は必ず書く -->
<img src="assets/images/factory.jpg"
     alt="稼働を始めた第 2 工場の外観"
     width="1200" height="800" loading="lazy">
href="about.html"
同じサイトの別ページへ。../ で 1 つ上の階層、先頭の / でサイトのルートからの指定になります。
href="#contact"
ページ内リンク。同じページの id="contact" を付けた要素まで移動します。href="#" だけならページ先頭へ。
href="about.html#access"
別ページの特定の場所へ。ページ移動と位置指定を同時にできます。
href="tel:0312345678"
電話をかける。スマホでタップすると発信画面が開きます。番号はハイフンを入れず数字だけ。国番号を付けるなら tel:+81312345678
href="mailto:info@example.com"
メールを書く。メールソフトが開きます。?subject=件名&body=本文 を付ければ、あらかじめ入れておけます。
href="https://…"
外部サイトへ。別タブで開くなら target="_blank" rel="noopener noreferrer" をセットで。

ページ内リンクを試す

飛び先には id を付けておくだけです。 id はページの中で重複させないこと。同じ名前が 2 つあると、最初の 1 つにしか飛べません。

HTML
<h2 id="toc">目次</h2>
<ul>
  <li><a href="#access">アクセス</a></li>
  <li><a href="#contact">お問い合わせ</a></li>
</ul>

<p>下のリンクを押すと、同じページの中を移動します。</p>
<p>(間を空けるための文章です。ここは読み飛ばしてください。)</p>
<p>(間を空けるための文章です。ここは読み飛ばしてください。)</p>
<p>(間を空けるための文章です。ここは読み飛ばしてください。)</p>

<h2 id="access">アクセス</h2>
<p>JR 大阪駅から徒歩 8 分。駐車場はございません。</p>
<p>(間を空けるための文章です。ここは読み飛ばしてください。)</p>
<p>(間を空けるための文章です。ここは読み飛ばしてください。)</p>

<h2 id="contact">お問い合わせ</h2>
<p>電話:<a href="tel:0312345678">03-1234-5678</a></p>
<p>メール:<a href="mailto:info@example.com?subject=お問い合わせ">info@example.com</a></p>
<p><a href="#toc">▲ 目次へ戻る</a></p>

「アクセス」を押すと、その見出しまで移動します。電話とメールのリンクは、実際の端末では発信画面やメールソフトが開きます(※ 番号とアドレスはサンプルです)。

固定ヘッダーで見出しが隠れる

画面上部に固定したヘッダーがあると、ページ内リンクで飛んだ先の見出しがヘッダーの下に潜ってしまいます。飛び先の要素に scroll-margin-block-start: 5rem; のように余白を持たせると解決します。また html { scroll-behavior: smooth; } を書くと、なめらかにスクロールします。

  • リンク文字は行き先が分かる言葉に。「こちら」「詳しくはこちら」だけでは、リンク一覧を読み上げたときに何も伝わりません。
  • alt は必ず書く。写真の内容を短く説明します。飾りの画像なら alt="" と空にして「読み上げなくてよい」と伝えます。
  • widthheight を書く。読み込み前に場所を確保でき、表示中にガタッとずれるのを防げます。
  • 最初の画面より下の画像は loading="lazy"スクロールするまで読み込まないので、表示が速くなります。

画像の形式を選ぶ

同じ写真でも、形式を選び間違えるとファイルが何倍にも膨らみます。使い分けを決めるのは 写真か図形か、そして 透過が要るかの 2 点です。

形式向いているもの透過覚えておくこと
.jpg
JPEG
写真×色数の多い写真を小さくできます。保存するたびに少しずつ劣化する(非可逆)ので、元のデータは別に残しておきます。
.png
PNG
透過が要る画像、図、画面の写し劣化しません(可逆)。そのぶん写真に使うとファイルが大きくなりがちです。
.webp
WebP
写真も図もJPEG や PNG より 2〜3 割ほど軽くなります。いまのブラウザはすべて表示できます。
.svg
SVG
ロゴ、アイコン、図形点の集まりではなく形の設計図です。どれだけ拡大してもぼやけません。写真には使えません。
HTML
<!-- 写真は WebP。ふだんはこれだけで足ります -->
<img src="assets/images/factory.webp" alt="稼働を始めた第 2 工場の外観"
     width="1200" height="800" loading="lazy">

<!-- 古い環境にも届けたいときは picture で切り替える。
     上から順に試して、表示できた最初のひとつが使われる -->
<picture>
  <source srcset="assets/images/factory.webp" type="image/webp">
  <img src="assets/images/factory.jpg" alt="稼働を始めた第 2 工場の外観"
       width="1200" height="800" loading="lazy">
</picture>

<!-- ロゴやアイコンは SVG。拡大してもぼやけない -->
<img src="assets/images/logo.svg" alt="カフェ ベベ" width="160" height="40">
  • 迷ったら WebP。写真も図も扱えて、いちばん軽くなります。
  • ロゴとアイコンは SVG。画面の解像度に左右されず、色や大きさをあとから変えられます。
  • 書き出す大きさは、表示幅の 2 倍まで。幅 600px で見せる写真に 4000px の元画像を置いても、重くなるだけで見た目は変わりません。
SVG は HTML に直接書ける

SVG は画像ファイルとして <img> で読み込むほかに、タグとして HTML の中に書くこともできます。そうすると CSS から色を変えたり、ホバーで動かしたりできます。この下のデモがその書き方です。なお WebP よりさらに小さくなる .avif という形式もありますが、まずは WebP で十分です。

写真に説明を添えるときは <figure> を使います。

HTML
<figure>
  <svg viewBox="0 0 200 90" width="200" height="90" role="img"
       aria-label="青い四角とオレンジの円">
    <rect x="10" y="15" width="80" height="60" fill="#2f80b8"/>
    <circle cx="150" cy="45" r="30" fill="#ff6a3d"/>
  </svg>
  <figcaption>図 1:図形は SVG で直接書くこともできます</figcaption>
</figure>

09

フォーム

入力欄には必ずラベルを付けます<label for="…"><input id="…"> を同じ名前で結ぶと、ラベルをクリックしただけで入力欄が選ばれ、読み上げも正しく働きます。

HTML
<form>
  <p>
    <label for="name">お名前(必須)</label><br>
    <input type="text" id="name" name="name" required autocomplete="name">
  </p>

  <p>
    <label for="mail">メールアドレス</label><br>
    <input type="email" id="mail" name="mail" placeholder="you@example.com"
           autocomplete="email">
  </p>

  <fieldset>
    <legend>ご希望の連絡方法</legend>
    <label><input type="radio" name="how" value="mail" checked> メール</label>
    <label><input type="radio" name="how" value="tel"> 電話</label>
  </fieldset>

  <p>
    <label for="body">お問い合わせ内容</label><br>
    <textarea id="body" name="body" rows="3"></textarea>
  </p>

  <p>
    <button type="submit">送信する</button>
    <button type="button">下書き保存</button>
  </p>
</form>

実際に入力して「送信する」を押してみてください。空のままだと、ブラウザが自分で「入力してください」と教えてくれます(required の働き)。

  • type を正しく選ぶと、スマホで最適なキーボードが出ます(email / tel / number / date)。
  • placeholder はラベルの代わりになりません。入力し始めると消えてしまうためです。
  • autocomplete を書くと、ブラウザが保存済みの住所や氏名を提案してくれます。
  • フォームの中の <button> は既定で送信ボタンになります。送信させたくないなら type="button" を明示します。

10

意味に合ったタグを選ぶ

HTML には「これ専用」のタグがたくさんあります。自分で JavaScript を書く前に、同じことをするタグが無いかを疑ってください。

HTML
<!-- 開閉する箱。JavaScript は要りません -->
<details>
  <summary>配送について</summary>
  <p>ご注文から 2〜3 営業日で発送します。</p>
</details>

<details>
  <summary>返品について</summary>
  <p>到着後 8 日以内にご連絡ください。</p>
</details>

<!-- 進み具合 -->
<p>アップロード:<progress value="70" max="100">70%</progress></p>

<!-- 略語・引用・コード -->
<p><abbr title="HyperText Markup Language">HTML</abbr> の
  <code>&lt;p&gt;</code> は paragraph(段落)の略です。</p>

<!-- 出典付きの引用 -->
<figure>
  <blockquote cite="https://example.com/">
    <p>速いサイトとは、待たされないサイトのことだ。</p>
  </blockquote>
  <figcaption>— 誰かの言葉(※ これはサンプルの引用です)</figcaption>
</figure>

「配送について」をクリックすると開きます。これを div と JavaScript で作ると 20 行かかります。

よく使う「専用タグ」

<details>/<summary>(開閉)、<dialog>(モーダル)、 <progress>(進捗)、<time>(日時)、 <picture>(画像の出し分け)、<video>/<audio>(再生)。どれもキーボード操作や読み上げへの対応が最初から入っています。

11

誰でも使えるようにする

アクセシビリティは特別な作業ではありません。 正しいタグを使うだけで、ほとんど達成できます。追加で意識してほしいのは次の 7 つです。

  1. lang を書く

    <html lang="ja">。読み上げの発音が変わります。

  2. 見出しの階層を守る

    読み上げソフトは見出しを拾って目次を作ります。飛ばすと迷子になります。

  3. 画像に alt を書く

    見えない人にとっては alt が画像そのものです。飾りなら alt=""

  4. 入力欄に label を付ける

    ラベルの無い入力欄は「編集テキスト」としか読まれません。

  5. リンクとボタンを使い分ける

    移動するなら <a>、動作するなら <button><div onclick> はキーボードで押せません。

  6. キーボードだけで操作できるか試す

    Tab キーで進み、Enter や Space で押せるか。マウスを置いて確認します。

  7. 色だけで情報を伝えない

    「赤字が必須」ではなく、文字でも「(必須)」と書きます。

ARIA は最後の手段

rolearia-* という属性で意味を補うこともできますが、 正しいタグに勝るものはありません。「ARIA を足す前に、HTML を直せないか」を先に考えてください。

12

やりがちな間違い

やりがちこうする
全部 <div>header / main / section / article / footer で意味を付ける
大きく見せたいから <h1>階層で選び、大きさは CSS で決める
<br> で余白を作る段落を <p> で分け、余白は CSS の margin
レイアウトに <table>表は「データの表」だけ。並べるのは CSS の grid / flex
<div onclick><button>。キーボードとフォーカスが最初から効く
alt を書かない・ファイル名を書く写真の内容を短く説明する
同じ id を複数の要素にid はページに 1 つだけ。複数なら class
スタイルを style="…" で直書きCSS ファイルにまとめる。後で直す場所が 1 か所になる
閉じタグの付け忘れ崩れたら、まず入れ子の対応を疑う

13

タグ早見表

最初はこれだけ知っていれば、たいていのページは組めます。

用途タグひとこと
骨組みheader nav main section article aside footermain は 1 ページ 1 つ
見出しh1h6階層を飛ばさない
文章p strong em mark brbr は本当の改行だけ
リストul ol li dl dt dd順番に意味があれば ol
table thead tbody tr th td captionth に scope を付ける
リンクa href行き先が分かる文言で
画像img picture figure figcaptionalt / width / height
フォームform label input textarea select button fieldsetlabel と id を結ぶ
まとまりdiv span他に無いときだけ
便利ものdetails summary dialog time progressJS を書かずに済む

14

次は CSS へ

ここまでで「何が書いてあるか」は表現できるようになりました。次は、それをどう見せるかです。意味のあるタグで書いておいたおかげで、CSS 側は狙った場所を簡単に指定できます。

STEP 2 / CSS 配置と装飾を身につける 色・文字・ボックスモデルから、Flexbox・Grid・:has()・@layer・コンテナクエリまで。
すべてその場で結果が見えるプレビュー付き。