🕸️

HTMLのタグちゃんと使おう

2023/01/27に公開
3

初めに

Team DELTA の三浦です。
昨年のアドベントカレンダーでweb 制作から開発領域に足を踏み出している話を書きました。
React で書かれたスマートクリニックシステムの UI 調整をメインでやっています。

アドベントカレンダー以降も Team DELTA として情報発信していくぞ!ということで、今週は、自分が UI 調整をする中で気づいた、マークアップで気をつけたいことの記事を書きました。

どんな人に読んでほしいか

まずは自分(戒めも込めて)
そして、どちらかというとサーバー側をメインで書いていて、あまりマークアップに触れてこなかったという方にも、参考になる部分があれば幸いです。

どんな内容か

なるべく適切なタグを使おうというテーマです。WAI-ARIA のようなアクセシビリティには細かく踏み込んでいません。
誤っている内容があれば、(優しめに)ご指摘いただきたいです!

HTML タグをちゃんと使うメリット

そもそも Web アプリでもタグやセマンティックを意識したマークアップって要る?

結論としては、「必要」です。
2024 年には障害者差別解消法が施行され、「情報の利用におけるバリアフリー化」を推進するべく、様々な情報媒体におけるアクセシビリティの向上が求められるようになります。「ウェブアクセシビリティ方針策定ガイドライン」でも、対象は「ウェブコンテンツ(ウェブアプリケーションを含む)」と明記されています。

参考 ▼
https://www8.cao.go.jp/shougai/suishin/tyosa/h26info/chapter1.html
https://waic.jp/docs/jis2016/accessibility-plan-guidelines/202112/

セマンティックを意識することがアクセシビリティにつながる理由は、タグにはその意味合いとキーボード操作が暗黙的に付いているためです。具体的には、スクリーンリーダーなどの支援技術がそれらを読み取って、フォーカスした要素が持つ目的を適切に読み上げられるようになります。

また、階層を意味づけできる言語になっているのであれば、きちんと意味に対応したタグで整理して書かれていたほうが見やすいしマシンリーダブルでよいよね、と個人的に思ったりしています。

参考 ▼
https://developer.mozilla.org/ja/docs/Learn/Accessibility/HTML
https://momdo.github.io/html/

【補足】HTML の現況

知っている方は今更と思われるかもしれませんが、現在は HTML5 ではなく HTML Living Standard が標準となっています。HTML5 から変更されたもの・廃止されたものもありますが、今回はフロントエンドのマークアップをやっていて感じたことがテーマなので、割愛します。
W3C と WHATWG の歴史が関係していて面白かったので、気になる方はこちらの記事を読んでみてください。

参考 ▼
https://future-architect.github.io/articles/20210621a/

HTML タグの具体的なマークアップ

大枠のレイアウトに関するマークアップ-header,nav,main,footer を使う

こちらはほとんどの方が理解されていると思いますが、改めて振り返ります。

導入的なコンテンツ、ふつうは導入部やナビゲーション等のグループを表します。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/header

現在の文書内の他の部分や他の文書へのナビゲーションリンクを提供するためのセクションを表します。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/nav

nav の中で ul タグ、a タグを使ってサイトのナビゲーションをマークアップするのが定石ですね。

main

文書<body>の主要な内容を表します。主要な内容とは、文書の中心的な主題、またはアプリケーションの中心的な機能に直接関連または拡張した内容の範囲のことです。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/main

main は 1 ページに 1 つのみです。説明にアプリケーションという単語が出てきていますね。やはり web アプリもマークアップの想定内ということだと感じます。

直近の区分コンテンツまたは区分化ルート要素のフッターを表します。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/footer

コンポーネントのマークアップ-意味付けを意識して使う

テキストのまとまり-p タグ

見出しでなければ、テキストのまとまりは p タグを使います。そんなん知っとるという方もいるとは存じますが…
Chakra UI を使う場合は、Text コンポーネントが該当します。divBox は装飾的な括りの手段、ぐらいの勢いでいきましょう!

悪い例
<h3>吾輩は猫である</h3>
<div>吾輩は猫である。名前はまだ無い。</div>
<div>どこで生れたかとんと見当けんとうがつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。……</div>
良い例
<h3>吾輩は猫である</h3>
<p>吾輩は猫である。名前はまだ無い。</p>
<p>どこで生れたかとんと見当けんとうがつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。……</p>

リスト-ul,ol タグ

箇条書きのように、情報を並列で並べたいときはリスト(順不同、順序付き)を表す ul,ol タグを使います。子要素を li タグで囲んで入れることで、読み上げなどの支援技術がリストとして認識できるようになり、内容の読み上げ前にリスト項目数を説明してくれたり、ショートカットキーを使って次のリスト項目へ移動できるようになります。

悪い例
<h3>好きな食べ物</h3>
<p>ラーメン</p>
<p>砂肝</p>
<p>紅茶</p>
良い例
<h3>好きな食べ物</h3>
<ul>
  <li>ラーメン</li>
  <li>砂肝</li>
  <li>紅茶</li>
</ul>

ラベルとフォームの関連付け-label タグと form 要素

input や select などのフォーム要素とそのラベル(項目名)があるときは、要素とラベルを関連付けます。関連付けると、フォーム要素を読み上げるときにラベルを一緒に読み上げることができるほか、ラベルをクリックしてラジオボタンやチェックボックスなどを選択できるようになり、マウスでの操作性も向上します。

  • ラベルは label タグを使う。
  • 関連付けは 2 通り
    • label でフォーム要素を囲う。
    • フォーム要素に id 属性を設定し、label の for 属性にフォームの id 名を指定する。
悪い例
<div>果物</div>
<input type="text" name="name">
良い例1
<!-- ラベルは label タグを使う -->
<!-- label でフォーム要素を囲う -->
<label>果物
<input type="text" name="name"></label>
良い例2
<!-- ラベルは label タグを使う -->
<!-- フォーム要素に id 属性を設定し、label の for 属性にフォームの id 名を指定する。 -->
<label for="fruits">果物</label>
<input type="text" id="fruits" name="name">

文書の関連付け-dl タグ

Q&A のような、名前(ラベルや文章)と値のグループを含む文書構造は、dl タグを使います。このタグについては支援技術の中でも対応が分かれているようですが、全て p タグでマークアップするよりも、意味付けが明確になります。

  • 質問は dt タグ、回答は dd タグを使う。
  • dt タグと dd タグを dl タグで囲う。dl タグの中には dt+dd のセットをいくつ入れてもよい。
悪い例
<div>アレルギーはありますか。</div>
<div>えび、ねぎ、そば</div>
<div>症状はいつからですか。</div>
<div>3日前</div>
良い例
<dl>
  <dt>アレルギーはありますか。</dt>
  <dd>えび、ねぎ、そば</dd>
  <dt>症状はいつからですか。</dt>
  <dd>3日前</dd>
</dl>

番外編 CSS と関係するマークアップ

マークアップとはいえ避けて通れないのが CSS。
ということで CSS 関係も少し書かせてください。。

なるべく Flexbox を入れ子にしない

Flexbox はとても使いやすいのですが、細かい仕様が他の仕様とぶつかって地味にバグが起きることもあります。また、コンテナとアイテムという仕様上、入れ子にすると div が余計に増えてしまいます。

  • 要素を縦に積むだけなら、Flexboxを使わずに書けるか検討する。
    間隔は margin で調整できます。(またはgrid-gap)
  • 縦 or 横方向のみといった一方向のレイアウトなら Flexbox 、新聞の段組みのような多方向のレイアウトは Grid を使う。

こんなレイアウトにしたい時

Flexbox
green と pink を囲む div が必要。

Grid
Flexbox の入れ子にしなくても、親要素に display: grid; を指定すればOK!

CSS Grid はこのゲームが楽しいのでやってみてください▼
https://cssgridgarden.com/#ja

ジェネレーターもあります ▼
https://cssgrid-generator.netlify.app/

まとめ

知っていることばかりだったという方もいると思いますが、改めて基本的な部分を振り返ってみました。

コンポーネントを書く際、余裕がなくなって div で囲んでしまうこともありますが、なるべく意味に合ったタグでマークアップしたいですね!

本当の本当に番外編

この文章を書く予定だった朝、テンプレートリテラル内の文字列の改行について、サーバーサイドの方から質問がありました。

「{${formatDate(item.date)}\n${item.time}}が改行されない。」
※バッククォートが上手く読み込めず消えています

結果として white-space: pre-wrap; で解消できましたが、詳しく調べてみたところ、 white-space: normal; ではソース内の改行文字(バックスラッシュ + n )がホワイトスペースとして扱われるのが原因のようです。

<br> だと改行されるのですが、テンプレートリテラルの中でエスケープされたり、様々な条件が影響しているようでした。

HTML タグだけでなく、特殊文字と CSS の兼ね合いや、React でのエスケープ周りも理解を深める必要がありそうだと感じました。

We're Hiring!

最後までお読みくださり、ありがとうございます。

現在 Team DELTA では様々な形で一緒に働く仲間を募集中です。

こちらの記事を読んで、Team DELTA に興味を持ってくださった方。
https://note.com/delta_sevenrich/n/n4ff4ff4c9793

自社だけに留まらず他社にも事業支援の場を広げていく Team DELTA で、想いのある人の手助けをしたい。

そんな方はぜひこちらから、お気軽にご連絡ください!

https://docs.google.com/forms/d/e/1FAIpQLSfQuWNU1il5lq2rVdICM0tSK_jTsjqwc52LYEwUxBq7_ImtrQ/viewform?usp=sf_link

DELTAテックブログ

Discussion

かがんかがん

いい記事ですね!👏
自分も気を抜くとpタグにすべきところをdivにしちゃうときよくあるので、改めて気をつけねばと思います😖

1点気になったところですが、

css grid はこのゲームが楽しいのでぜひ!▼

のリンクがgridではなくuseIdの記事で間違っていそうです…!
ご確認ください!!

るなこるなこ

お読みくださりありがとうございます!
リンクが誤っており大変失礼いたしました。
修正いたしました🙇‍♀️

かがんかがん

ご対応ありがとうございます!

リンク先見ましたが、こんなかわいいCSSゲームがあったなんて知りませんでした 👀
早速やってみようと思います