CSSを活用してHTMLのセマンティックエラーを指摘する方法

110
71
75

CSSはWebページの見た目を整えるものですが、ちょっと違う使い方もできます。たとえば、予期せぬ横スクロールが発生した時、以下のようにすることで全ての要素のアウトラインが表示され、不用意にはみ出している部分が視覚的に分かりやすくなります。

* {
  outline: 2px solid red;
}

これを応用してタグの不適切な利用部分をハイライトできます。

このような不適切なタグ利用を検知して警告する「デバッグCSS」を作ってみました。このようなCSSをLintのようにする使い方は#lintHTMLwithCSSのハッシュタグで海外でも考案されています。仕様上許可されないものは赤色で点滅、ダメではないが、やらない方がベターなものは黄色で点滅するようになっています。

当記事では下記のデモを見ながらだと理解を深めやすいので、合わせて読むことをオススメします。

ulタグ・olタグ・dlタグの子要素で使えるタグは限られている

<ul>タグ<ol>タグの子要素は<li>タグのみ許可されています。直下に<div>などを使うのはNGです。なお、<dl>タグの子要素にはグルーピングするために<div>タグを使うことは許可されているので、<dl>タグ直下で使えるのは<dt><dd>そして<div>タグになります。

ul,ol,dlタグのNG例

aタグの不適切な属性、あった方がよい属性

name属性の使用

name属性はHTML5で廃止されました。ページ内リンクを使う場合はid属性を使いましょう。

rel属性の値に"noopener"

<a>タグの属性にはいくつか注意が必要なものがあります。一つはrel="noopener"です。これはtarget="_blank"を指定した際に、JavaScriptの悪用を防ぐための属性です。これがない場合、遷移先から遷移元をリダイレクトさせることができてしまいます。ブラウザー側でもnoopenerの挙動をデフォルトになるように進めているので近い将来はこの属性はなくても上記問題は解決される見込みです(記事『アンカー上の target=_blank が rel=noopener を暗示するようになりました | Firefox サイト互換性情報』より)。

javascript:void(0)の利用

href属性の値にjavascript:void(0)を利用するのは推奨されません(記事『 a アンカー要素 | MDN』より)。<a>タグをインタラクションの要素として利用しているのであれば、<button>のほうが適切でしょう。<a>タグはアンカーの名の通り、リンクなどに使用すべきです。

imgタグにあった方がよい属性

alt属性

画像のalt属性をきちんと入力するのはアクセシビリティの観点からも重要です。何らかの事情で画像が読み込まれなかった場合に代替テキストが表示されるだけでなく、読み上げソフトが内容を読み上げるようになります。これにより、読み上げ支援が必要な人にもページの内容を伝えられます。

width, height属性

画像の表示横幅・縦幅を指定するwidthheight属性も、入れたほうがメリットがあります。入力しない場合、完全に画像が読み込まれるまでサイズが決定しないので、読み込み完了時にレイアウトがズレる原因になります。

CSSでwidth: 100%; height: autoのような指定をした場合も、widthheight属性を入力しておけばその比率を計算して画像が読み込み終わるまでスペースを確保してくれます。

ちょっと注意が必要なtimeタグの使い方

日時などを表す<time>タグですが、ちょっと使い方に注意が必要です。<time>タグには機械(ブラウザーやコンピューター)にも日時を知らせるという側面があるからです。次のような使い方は推奨されません。

<time>7月15日</time>

「7月15日」という表記は機械では解析できません。YYYY-MM-DD形式などで伝える必要があります。タグ内の内容をその形式に直しても良いですが、datetime属性を用いた方が自由度は高いでしょう。

<!-- datetime属性に機械可読な記述をする -->
<time datetime="2020-07-15">7月15日</time>

<!-- datetime属性を用いない場合はこれも可 -->
<time>2020-07-15</time>

このような形で記述するほうが望ましいです。そのため、datetime属性のない<time>タグには非推奨の警告を与えています。また、datetime属性がない場合はその内容が機械可読であるべきなので、子要素をもってはいけません。

hgroup内に見出しタグ以外をいれてはいけない

当たり前といえば当たり前ですが、<hgroup>タグには<h1><h6>タグのみの使用が許可されています。文字通り見出しをグルーピングするためのタグです。

<!-- これはOK -->
<hgroup>
  <h1>メインの見出し</h1>
  <h2>~ サブタイトル ~</h2>
</hgroup>

<!-- これはNG -->
<hgroup>
  <div>
    <h1>メインの見出し</h1>
    <h2>~ サブタイトル ~</h2>
  </div>
</hgroup>

余談になりますが、このタグはW3C仕様では削除されましたが、WHATWG仕様では認められていたので、逆転復活したタグです。

captionタグはtableタグの最初の要素

表にキャプションを付ける、<caption>タグは<table>タグの最初の子要素でなくてはなりません。表の下側にキャプションを配置したい場合はCSSのcaption-side: bottomを指定しましょう。

<!-- たとえ表の下側に配置するにしてもNG-->
<table>
  <tbody>...</tbody>
  <caption>表のキャプション</caption>
</table>

正直、自分なら表にタイトル的なものをつけたい場合は<table>タグに縛られない見出しタグを使うと思います…。

古い属性・タグの使用

HTML5以降で廃止されたタグ・属性があります。たとえば<font>タグ<frame>タグ、alignbgcolor属性といったタグです。

<!-- 古いタグの使用はNG -->
<font size="4">フォントタグなどの古いタグ</font>

<!-- 古い属性の使用はNG -->
<span color="red">color属性などの古い属性</span>

古い属性に関してはCSSで代替できるので、文書構造と装飾の分離の観点からも属性に書くのはやめましょう。

デバッグCSSでは、これらのタグが使われていたらアウトラインを表示するようにしています。

無用な改行タグの連続

余白を作るため、<br>タグを連続させるのは、本来の改行タグの使い方ではありません。「改行を連続させる」という意図を持っている自由詩などを除いては、margin<p>などを用いて余白を作りましょう。

このCSSデバッグにおいてはちょっと困ったことに、<br>タグは大きさなどを持たないのでoutlineで表示できません。そのため、連続する<br>には2つ目以上をdisplay: noneとし、非表示にすることで対応しています。空けたはずの改行がなくなっていたら、デバッグCSSが効いているか確認してください。

シンタックスエラーには非対応…

このデバッグCSSですが、明らかなシンタックスエラーには対応していません。例えば次のような誤ったHTMLを作成した場合に不都合が起こります。

<p>
  <div>...</div>
</p>

明らかに正しくないHTMLなので、ブラウザーがレンダリング時に世話を焼いていい感じにタグを勝手に閉じてしまいます。

<p></p>
<div>...</div>
<p></p>

たとえCSSでp > divのようなセレクタを作っても、上記CSSのような誤ったHTMLは生成されないので検知することができません。

このデバッグCSSで検知できるのは基本的にセマンティックエラーになります。逆にシンタックスエラーはエディターなどが機械的に指摘できるので、それを活用しましょう。

ちょっと手を加えてよりよいWeb体験を

ここに挙げた例は、修正しなくてもサイト全体に大きな影響はありません。しかし、これらを改善することでセマンティック・アクセシビリティの向上が図られ、ユーザー体験の改善にもつながります。

見た目以外の細かいところにも気を配って、よりよいWebの世界を作っていきましょう。