構造・意味
「これは見出し」「これは一覧」「これは送信ボタン」。文書が何でできているかを書きます。拡張子は .html。
STEP 1 / HTML
HTML は見た目を作る言語ではありません。「ここは見出し」「ここは段落」「ここは移動先のあるリンク」と、文書の意味と構造を書き記すための言語です。ここを丁寧にやっておくと、あとの CSS と JavaScript が驚くほど楽になります。
01
Web ページは 3 つの言語でできています。役割ははっきり分かれていて、混ぜると後で必ず困ります。まずはこの分担を頭に入れてください。
「これは見出し」「これは一覧」「これは送信ボタン」。文書が何でできているかを書きます。拡張子は .html。
色・文字の大きさ・並べ方。HTML に書いた要素を、どう見せるかだけを担当します。拡張子は .css。
押されたら開く、入力を計算する、データを取ってくる。あとから状態を変える係です。拡張子は .js。
見た目だけなら、すべて <div> でも CSS で似せられます。けれど検索エンジン・読み上げソフト・キーボード操作・ブラウザの翻訳機能は、
タグの意味を手がかりに動いています。
<button> と書けば Enter キーで押せる。<div> ではそうなりません。正しいタグを選ぶことは、自分で機能を書かずに済ませるための近道でもあります。
02
メモ帳でもエディタでも構いません。次の内容を index.html という名前で保存し、ダブルクリックすればブラウザで開けます。これが出発点です。
<h1>はじめてのページ</h1>
<p>これは段落です。HTML はこうやって書きます。</p>
上の枠が、実際にブラウザが表示した結果です。文字の大きさや余白は、何も指定しなくてもブラウザが付けてくれます。
ただし、実際のファイルには外側の決まり文句が必要です。全体はこうなります。
<!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>
lang でページの言語を伝えます。読み上げの発音や自動翻訳の判断に使われるので、必ず書きます。
ファイル名は半角英数字・小文字・ハイフンで付けます(about-us.html)。日本語やスペースは、公開したときにリンク切れの原因になります。そしてトップページのファイル名は index.html。これはサーバーが自動で開いてくれる決まった名前です。
03
<head> は画面に出ませんが、ページの品質はここでかなり決まります。最低限この 5 つは覚えてください。
<head>
<!-- 1. 文字コード。必ず head の先頭に置く -->
<meta charset="utf-8">
<!-- 2. スマホで正しい幅にする。これが無いと縮小表示になる -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 3. タブと検索結果に出る題名。ページごとに変える -->
<title>会社概要 | ○○デザイン事務所</title>
<!-- 4. 検索結果に出る説明文。120 文字くらいまで -->
<meta name="description" content="○○デザイン事務所の所在地・沿革・アクセスのご案内です。">
<!-- 5. CSS の読み込み -->
<link rel="stylesheet" href="assets/stylesheets/style.css">
<!-- JavaScript は defer を付けて head で読み込むのが今の定番 -->
<script src="assets/javascripts/main.js" defer></script>
</head>
defer を付けると、JavaScript の読み込みはページの表示を止めず、
HTML を全部読み終えてから実行されます。これが無いと「まだ存在しない要素を触ろうとして null になる」という定番のエラーが起きます。
</body> の直前に置く昔ながらの方法もありますが、今は defer が簡単です。
04
HTML は要素を積み重ねて書きます。要素は「開始タグ・中身・終了タグ」の 3 つでできています。
<p class="lead">これが中身です</p>
↑ ↑ ↑
開始タグ 属性 終了タグ
<!-- 中身を持たない「空要素」は終了タグを書かない -->
<img src="cat.jpg" alt="窓辺で眠る猫">
<br>
<hr>
<!-- 入れ子は、開いた順と逆の順で閉じる -->
<p>これは <strong>とても <em>大事</em></strong> です。</p>
<!-- コメント。メモを残せる(画面には出ないが、閲覧者からは読める) -->
名前="値" の形で書きます。値は必ず引用符で囲みます。<p><strong>…</p></strong> は間違いです。ソースの改行が半角スペース 1 個になるのは、英語なら単語の区切りとして都合がよい仕様です。 けれど日本語では困ります。文の途中で改行すると、そこに余分な空白が入ってしまうからです。
たとえば …4 つだけ決め、 で改行して次の行を 名前は… から書き始めると、
画面では読点のあとに半角スペース 1 個ぶん(文字の約 3 分の 1)の隙間が空きます。
コードを読みやすくするつもりの改行が、そのまま表示に出てしまうわけです。
対策は簡単で、日本語の文はソースでも 1 行で書くこと。
どうしても折り返したいときは、タグの区切りなど空白が入ってよい位置で改行します。
英語と日本語が混ざる部分(<code>margin</code> の値 など)は、
もともと空白を入れたい場所なので気にしなくて構いません。
05
<body> の中は、いきなり本文を書き始めるのではなく、
意味を持った箱で区切ります。これがセマンティック(意味的)なマークアップです。
<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>
迷ったら「そこに見出しを付けられるか」で判断します。付けられるなら <section>、単に CSS で囲みたいだけなら <div> です。
06
見出しは <h1> から <h6> まであり、
本の目次と同じ階層を表します。大きく見せたいから <h1>、ではありません。大きさは CSS の仕事です。
<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>。表は「行と列に意味があるデータ」にだけ使い、レイアウト目的では使いません。
<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> はその場で何かを起こすもの。ここを取り違えないでください。
<!-- 同じサイトの中へ -->
<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">
../ で 1 つ上の階層、先頭の / でサイトのルートからの指定になります。id="contact" を付けた要素まで移動します。href="#" だけならページ先頭へ。tel:+81312345678。?subject=件名&body=本文 を付ければ、あらかじめ入れておけます。target="_blank" rel="noopener noreferrer" をセットで。
飛び先には id を付けておくだけです。
id はページの中で重複させないこと。同じ名前が 2 つあると、最初の 1 つにしか飛べません。
<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="" と空にして「読み上げなくてよい」と伝えます。width と height を書く。読み込み前に場所を確保でき、表示中にガタッとずれるのを防げます。loading="lazy"。スクロールするまで読み込まないので、表示が速くなります。同じ写真でも、形式を選び間違えるとファイルが何倍にも膨らみます。使い分けを決めるのは 写真か図形か、そして 透過が要るかの 2 点です。
| 形式 | 向いているもの | 透過 | 覚えておくこと |
|---|---|---|---|
.jpgJPEG | 写真 | × | 色数の多い写真を小さくできます。保存するたびに少しずつ劣化する(非可逆)ので、元のデータは別に残しておきます。 |
.pngPNG | 透過が要る画像、図、画面の写し | ○ | 劣化しません(可逆)。そのぶん写真に使うとファイルが大きくなりがちです。 |
.webpWebP | 写真も図も | ○ | JPEG や PNG より 2〜3 割ほど軽くなります。いまのブラウザはすべて表示できます。 |
.svgSVG | ロゴ、アイコン、図形 | ○ | 点の集まりではなく形の設計図です。どれだけ拡大してもぼやけません。写真には使えません。 |
<!-- 写真は 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">
SVG は画像ファイルとして <img> で読み込むほかに、タグとして HTML の中に書くこともできます。そうすると CSS から色を変えたり、ホバーで動かしたりできます。この下のデモがその書き方です。なお WebP よりさらに小さくなる .avif という形式もありますが、まずは WebP で十分です。
写真に説明を添えるときは <figure> を使います。
<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="…"> を同じ名前で結ぶと、ラベルをクリックしただけで入力欄が選ばれ、読み上げも正しく働きます。
<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 を書く前に、同じことをするタグが無いかを疑ってください。
<!-- 開閉する箱。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><p></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 つです。
<html lang="ja">。読み上げの発音が変わります。
読み上げソフトは見出しを拾って目次を作ります。飛ばすと迷子になります。
見えない人にとっては alt が画像そのものです。飾りなら alt=""。
ラベルの無い入力欄は「編集テキスト」としか読まれません。
移動するなら <a>、動作するなら <button>。<div onclick> はキーボードで押せません。
Tab キーで進み、Enter や Space で押せるか。マウスを置いて確認します。
「赤字が必須」ではなく、文字でも「(必須)」と書きます。
role や aria-* という属性で意味を補うこともできますが、
正しいタグに勝るものはありません。「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 footer | main は 1 ページ 1 つ |
| 見出し | h1〜h6 | 階層を飛ばさない |
| 文章 | p strong em mark br | br は本当の改行だけ |
| リスト | ul ol li dl dt dd | 順番に意味があれば ol |
| 表 | table thead tbody tr th td caption | th に scope を付ける |
| リンク | a href | 行き先が分かる文言で |
| 画像 | img picture figure figcaption | alt / width / height |
| フォーム | form label input textarea select button fieldset | label と id を結ぶ |
| まとまり | div span | 他に無いときだけ |
| 便利もの | details summary dialog time progress | JS を書かずに済む |
14
ここまでで「何が書いてあるか」は表現できるようになりました。次は、それをどう見せるかです。意味のあるタグで書いておいたおかげで、CSS 側は狙った場所を簡単に指定できます。
配置と装飾を身につける 色・文字・ボックスモデルから、Flexbox・Grid・:has()・@layer・コンテナクエリまで。