HTML の dl 要素内のグループを明示する2021年12月04日 23時34分

この記事は HTML アドベントカレンダーの 4 日目の分です。


HTML の dl 要素 (説明リスト、いわゆる定義リスト) は、名前と値 (用語と説明) からなるグループの連なりを表します。ひとつのグループには dt 要素と dd 要素がそれぞれひとつ以上含まれます。

よく見るのは dl 要素の直下に dt 要素と dd 要素が来る形でしょう。以下の例では dl 要素にふたつのグループが含まれます。

<dl>
  <dt>琥珀</dt>
  <dd>寒天を使い透明感のある菓子の総称。</dd>
  <dd>琥珀糖のこと。</dd>

  <dt>琥珀糖</dt>
  <dt>干琥珀</dt>
  <dd>寒天を煮て固め表面を乾燥させた菓子。シャリっとした表面とプルっとした中身の対比が癖になる。</dd>
</dl>

スタイルシートを適用したり、マイクロデータの項目を作成したりするために、グループひとつずつを表す要素が欲しくなるかもしれません。そのときは div 要素を使ってグループを明示できます。

<dl>
  <div>
    <dt>琥珀</dt>
    <dd>寒天を使い透明感のある菓子の総称。</dd>
    <dd>琥珀糖のこと。</dd>
  </div>
  <div>
    <dt>琥珀糖</dt>
    <dt>干琥珀</dt>
    <dd>寒天を煮て固め表面を乾燥させた菓子。シャリっとした表面とプルっとした中身の対比が癖になる。</dd>
  </div>
</dl>

dl 要素に含まれるグループを明示したいという要望は昔からあり、XHTML2 では di 要素が定義されていました。HTML5 に対しても di 要素 (または dli 要素) が何度も提案されましたが、スタイルに関することはスタイルシートで解決すべきという意見、および新要素を導入すると従来の HTML パーサでは意図しない結果になるという問題から、そのたびに見送られてきました。

最終的に、div 要素を使えば従来の HTML パーサでも問題なく、またブラウザのデフォルトスタイルシートの影響も受けづらいということで、div 要素を使う案が採用されました。

参考文献

同じような HTML コードでもパース結果が異なることがある2021年12月05日 23時11分

この記事は HTML アドベントカレンダーの 5 日目の分です。


HTML 標準では、誤りのある HTML コードを Web ブラウザがどう解釈すべきかも定められています。例えば、span 要素の終了タグを書き忘れた場合、

const c = document.createElement('div');
c.innerHTML = '<p><span>foo</p><p>bar</p>';
console.log(c.innerHTML);
// => "<p><span>foo</span></p><p>bar</p>"

最初の段落が終了する地点で span 要素も終了すると解釈されました。ここで span 要素を b 要素に変えてみるとどうなるでしょう。

const c = document.createElement('div');
c.innerHTML = '<p><b>foo</p><p>bar</p>';
console.log(c.innerHTML);
// => "<p><b>foo</b></p><p><b>bar</b></p>"

最初の段落が終了する地点で b 要素がいったん終了するのは span 要素のときと同じですが、今度は 2 番目の段落の内容にも b 要素が登場します。span 要素も b 要素も要素のカテゴリや内容モデルは変わらないのに、どうしてこの差が生まれるのでしょうか。

HTML のパースにあたって、abbigcodeemfontinobrssmallstrikestrongttu の各要素は書式設定要素という分類に含まれ、誤りの訂正方法が他の要素とは異なってくるのです。

Web 製作者が意図していたであろう構造を再現するため、また過去のブラウザのパース結果との互換性をできるだけ保つため、HTML パーサーはあれこれがんばって誤りを修正してくれているのですね。

HTML の form 要素の rel 属性2021年12月06日 23時00分

この記事は HTML アドベントカレンダーの 6 日目の分です。


HTML の link 要素や a 要素には rel 属性を指定できます。もともとは閲覧中の Web ページとリンク先のリソースの関係性を示すものでしたが、現在はリンクの挙動を指定するためにも使われています。rel="noreferrer" ならリンク先の文書にリファラーを送らない、rel="noopener" ならリンク先文書の JavaScript から元の文書へのアクセスを禁止する、といった挙動です。

これらの rel 属性の値は、a 要素だけでなく form 要素にも使えます。以下のようなフォームがあったとき、フォームを送信すると新たなタブ (またはウィンドウ) が開きますが、そのタブの JavaScript から window.opener プロパティで元のタブの文書を参照することはできません。

<form method="get" action="/search" target="_blank" rel="noopener">
  ...
</form>

2021 年 12 月現在、Safari の開発版では form 要素の rel 属性への対応が進んでいますが、Chorme と Firefox は対応していません。

参考文献

HTML の属性値の先頭または末尾に含まれる空白文字の扱い2021年12月07日 23時18分

この記事は HTML アドベントカレンダーの 7 日目の分です。


HTML の属性値の先頭または末尾にスペースなどの空白文字を記述したとき、それらの文字がそのまま扱われる場合と無視される場合があります。例として form 要素の属性を見ていきましょう。

<form
    method=" post "
    action=" /edit "
    target=" _blank "
    rel=" noopener ">
  • method 属性の値は特定のキーワードであり、空白文字を含む値は指定できません。" post " は無効な値として無視され、デフォルト値である "get" を指定したのと同じ扱いになります。
  • action 属性の値はスペースで囲まれる可能性のある空でない妥当な URL であり、先頭と末尾の空白文字の並びは無視されます。この場合は "/edit" を指定したのと同じ扱いになります。
  • target 属性の値は特定のキーワードまたは名前であり、空白文字も名前の一部として扱われます。この場合は " _blank " という名前のウィンドウがフォーム送信先になります。常に新しいウィンドウを開くキーワード "_blank" とは異なります。
  • rel 属性の値はスペース区切りのトークンであり、先頭と末尾の空白文字の並びは無視されます。この場合は単に "noopener" を指定したのと同じ扱いになります。

先頭と末尾の空白文字の扱いは属性によってバラバラですね。HTML コードを記述する際は、どの属性ならどう扱われるといったことを覚えるよりも、属性値の先頭または末尾に空白文字を置かないと決めてしまったほうが楽だと思います。

HTML 文書内で翻訳してよい箇所かどうか指定する2021年12月08日 23時31分

この記事は HTML アドベントカレンダーの 8 日目の分です。


英語の技術文書を機械翻訳して読んでいたら、固有名詞やプログラミングコードまで翻訳されておかしな日本語になっていたという経験はないでしょうか。そのような事態を防ぐために使えるのが translate 属性です。

ある要素の translate 属性の値に no を指定すると、その要素の内容を翻訳の対象にしてはいけないと示すことになります。yes または空文字列を指定すると、翻訳の対象にしてよいと示すことになります。

<pre translate="no"><code>
int n = 0;
/* <span translate="yes">ここで <span translate="no">printf</span> しないと
   なぜか <span translate="no">segmentation fault</span> する。</span> */
printf("%d\n", n);
</code></pre>

translate 属性を指定しない場合は親要素の値を引き継ぎ、親要素がない (自身が html 要素である) 場合のデフォルト値は yes です。つまり、デフォルトでは文書全体を翻訳の対象にしてよいということになります。

translate 属性の効果は一部の属性にも及びます。任意の要素の title 属性、img 要素の alt 属性、input 要素の placeholder 属性などの値は、(その要素が translate="yes" 相当なら) 翻訳の対象となりえます。さらには、style 属性の値を解析した結果の CSS content プロパティの値なども翻訳の対象となりうるとされています。

この記事を書いていて気づきましたが、a 要素の download 属性の値も翻訳の対象になりうるとされています。しかし、download 属性の値はファイル名として扱われるので、勝手に翻訳されると困ったことになるかもしれませんね。