HTML の暗黙的なフォーム送信と CSS の :default 疑似クラス2021年12月11日 22時59分

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


Web ページに備えられた検索機能を使うとき、検索語の入力欄で Enter キーを押下 (ソフトウェアキーボードなら「実行」といったキーを実行) して検索結果画面に進んだことのある人は多いでしょう。このようにフォーム送信ボタンを介さずにフォームを送信する機能は、HTML 標準で暗黙的なフォーム送信として定義されています。

あるフォームに含まれる送信ボタンのうち、文書順で最初に出現するものをデフォルトボタンといいます。暗黙的な送信の基本的な挙動は、あるフォームのフォームコントロール上で Enter キーを押下したりすると、そのフォームデフォルトボタンを実行したのと同じ扱いになるというものです。以下の例では、テキスト入力欄で Enter キーを押下すると、「検索する」ボタンが実行されたとみなされ、/search?q={入力した語}&feeling=so-so という URL のページに移動します。

<form action="/search">
  <p>
    <input type="search" name="q" aria-label="検索する語">
    <button type="submit" name="feeling" value="so-so">検索する</button>
    <button type="submit" name="feeling" value="lucky">いい感じに検索する</button>
  </p>
</form>

デフォルトボタンが無効化されている (disabled 属性が付与されている) 場合は暗黙的なフォーム送信が行われません。

デフォルトボタンがない (フォーム内に送信ボタンが含まれない) 場合、そのフォームに含まれるテキスト入力欄 (パスワード入力欄や日時入力欄なども含む) がひとつだけなら暗黙的なフォーム送信が行われます。テキスト入力欄がふたつ以上あるときは暗黙的なフォーム送信が行われません。これらの挙動には歴史的経緯がありそうですが調べられていません。

デフォルトボタンを Web 製作者側で指定できるようにしようという提案もありますが、あまり議論が進んでいません。

デフォルトボタンは CSS の :default 疑似クラスにマッチします。以下の CSS を適用した文書では、フォーム内の最初に登場する送信ボタンに水色のアウトラインが表示されます。

:default { outline: thick solid #0ff; }

:default 疑似クラスはデフォルトボタン以外にも、チェックボックスまたはラジオボタンで checked 属性を持つものと、option 要素で selected 属性を持つものにもマッチします。ユーザーがチェックを外したり選択肢を変更したりしても、:default 疑似クラスがマッチする要素は変わりません。

HTML 要素の innerText プロパティで要素が生成されうる2021年12月10日 11時13分

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


HTML 標準では、HTML 文書を JavaScript などのプログラミング言語から扱うためのインターフェイスも定義しています。そのひとつが HTML 要素の innerText プロパティ、要素の内容を文字列として取得・設定するプロパティです。かつて Internet Explorer が独自に実装し、他の Web ブラウザも追従した結果として標準化されたものですね。

innerText プロパティの値の取得

innerText プロパティで取得できる値は、ブラウザにレンダリングされたようなテキスト内容となります。CSS で display: none; が指定された要素の内容は含まれませんし、display: block; が指定された要素の内容の前後には改行文字 (U+000A) が挿入されます。表のセル同士の間にはタブ文字 (U+0009) が挿入されます。

そのため、innerText プロパティの値を取得する際にはブラウザの描画処理、いわゆるリフローが走ることになります。スタイルを気にせず単に要素のテキスト内容を取得したいときは、innerText プロパティではなく textContent プロパティを使ったほうがよいでしょう。textContent プロパティの値の取得時にはリフローが走りません。

innerText プロパティの値の設定

innerText という名前からすると値の設定時には単なるテキストノードが生成されそうな気もしますが、HTML 要素が生成されることもあります。設定する値に改行文字が含まれるときは、その改行文字が br 要素に置換されるのです。

単に要素のテキスト内容を設定したいときは、innerText プロパティではなく textContent プロパティを使ったほうがよいでしょう。textContent プロパティの値の設定時には HTML 要素が生成されません。

参考文献

HTML のテキスト入力欄の minlength 属性2021年12月09日 21時30分

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


HTML の input 要素と textarea 要素には minlength 属性を指定できます。入力するテキストの最小文字数を指定するものですが、いくつか注意点があります。

まず、minlength 属性を指定していても入力が必須となるわけではありません。何も入力していなくても (0 文字の入力でも) クライアント側フォーム検証を通ってフォーム送信可能になります。入力を必須にするには別途 required 属性を指定する必要があります。

次に、minlength 属性で指定される「文字数」とは UTF-16 の符号単位の数です。絵文字など Unicode の BMP (基本多言語面) 外の文字 (U+10000 以上の文字) は 2 文字として数えられます。この文字数の扱いは maxlength 属性も同じです。

<input type="text" name="q" minlength="2" maxlength="3">

というテキスト入力欄があったとき、「🍣」1 文字だけでもフォーム送信可能ですし、「🍣🍣」と 2 文字入力することはできません。

参考文献

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 属性の値はファイル名として扱われるので、勝手に翻訳されると困ったことになるかもしれませんね。

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