MDNにあるセマンティクスの説明を直したい
この記事の説明は問題があるので、できれば直したい。直すならGitHubにissueを出すのが筋だと思うが、いきなり英語で書くのは大変なので、とりあえず日本語で問題点をまとめておく。
プログラミングでは、セマンティクスとは、コードの断片の意味を指します。たとえば、「JavaScript でその行を実行すると、どのような効果があるのか?」、「その HTML 要素には、どのような目的や役割があるのか?」 (「どのように見えるのか?」ではなく)。
最初の、この説明は、とりあえずOKだと思う。細かい表現にケチをつけられるかもしれないけど。セマンティクスとはコードの意味のことで、その非形式的な実体としては、プログラムを実行した際に起きるエフェクトだとか、それが繋がっている目的や役割などだと言えるだろう。(言語学なんかでは、コンテキストから独立した意味を考える意味論と、コンテキストと意味の関係を論じる語用論とを分けるかもしれないが、ここでは、特に両者を区別していない。)
しかし、その後につづく、JavaScript, CSS, HTMLのセマンティクスについての個別の説明は、だいぶあやしい。
JavaScript でのセマンティクス
JavaScript において、文字列の引数を取り、その文字列を
textContent
とする<li>
要素を返す関数を想像してみてください。build('Peach')
またはcreateLiWithContent('Peach')
という関数名の場合、何をするのかを理解するためにコードを見る必要があるのはどちらでしょうか?
この説明は、どうやってコードをリーダブルにするか、という話をしている。コードのリーダビリティは、コードのセマンティクスとは関係がない。
最初の説明通り「JavaScript でその行を実行すると、どのような効果があるのか?」というのが、JavaScriptのセマンティクスだ。関数の名前をbuild
にしようがcreateLiWithContent
にしようがaa
にしようが、それはJavaScriptで書かれたプログラムの動作に、ほぼ影響がない1。識別子にどう名づけるか自体はプログラムの動作に影響しないし、だからこそ、minifierのようなツールを使って識別子を短いものに書き換えることで、JavaScriptプログラムを小さくすることができる。
JavaScriptのセマンティクスは、主に次のような文書で規定されている。
- ECMA-262 ECMAScript® 2023 language specification ECMAScript (JavaScript) 言語自体のセマンティクスを規定している。
- WHATWG Standards JavaScriptからアクセスできる種々のファシリティ(機能)が規定されている。
HTML でのセマンティクス
HTMLのセマンティクスに関しては、OKな説明であるとは思う。ただ、最新のHTML仕様に合わせた説明に書きかえると、もっといいと思う。
HTML仕様 1.8 HTML vs XML syntax で、文書やアプリケーションを記述する抽象言語と、情報交換用の具体構文として「HTML構文」「XML構文」が規定されている。これらの構文によって記述されたHTML文書は、ファイルに保存されたり、HTTPで送信されたりする。
これらのHTML文書は、ブラウザーで処理される際、メモリ上では、「DOM HTML」というより抽象的な形に変換される。HTML構文については13 The HTML syntaxで、XML構文については14 The XML syntax で、それぞれDOM HTMLに変換する方法が規定されている。
HTMLのセマンティクスは 3 Semantics, structure, and APIs of HTML documents で定められている。それは、厳密に言えば、ファイルに保存されたり送信されたりするHTML構文やXML構文に対してではなく、より抽象的な内部表現であるDOM HTMLに対して、それぞれの要素、属性、属性値のセマンティクスを規定している。
Elements in the DOM represent things; that is, they have intrinsic meaning, also known as semantics.
For example, an ol element represents an ordered list.
要素はそれぞれ、なにか物事 (thing) を表現 (represent) している。たとえば、ol要素は、順序付きリストを表現している、ということが、仕様として書かれている。
また、HTMLの各要素にはAPIが定義されていて、そのAPIを介して、要素の機能に関する操作を、JavaScriptから行える。たとえば、<button>
要素はボタン操作に関するAPIを提供しているし、<video>
要素はビデオ再生に関するAPIを提供している。こういったAPIに関する規定は、仕様のいう "intrinsic meaning" や "semantics" というよりは、それをブラウザー上で実現するための機構のようなものといえる。しかし、JavaScriptのようなプログラムの、プログラムの振る舞いがセマンティクスだという考えからすれば、DOM HTMLのAPIも、一種のセマンティクスだと考えられるだろう。言語的な、コードによって表現される物事を指すセマンティクスと、プログラム的な、コードによって実現される機構の振る舞いを指す「セマンティクス」の両方が、仕様に規定されていることになる。
HTMLのセマンティクスは、ブラウザーの画面上での具体的な見た目(プレゼンテーション)を規定していない。HTMLの見た目は、HTML自体ではなく、HTMLに関連づけられたスタイルシートによって決まっている。
CSS でのセマンティクス
CSS において、さまざまな種類の果物を表すために
li
要素でリストをスタイル付けすることを想像してみてください。div > ul > li
または.fruits__item
で選択された DOM の一部が何であるか分かるのはどちらでしょうか?
本来であれば、「CSSでのセマンティクス」とは、やはり「CSSのコードがどのような意味を持つのか?」といった部分を説明するべきだろうと思う。ここでのMDNの説明は、セマンティクスではなくて、よりよいCSSを書くためのプラクティスの説明でしかない。
div > ul > li
という指定は、「div要素の子ul要素のさらに子のli要素」を指定している。一方で、.fruits__item
は「class
属性がfruits__item
の要素」を指定している。どちらも意味のある記述であり、どちらの方がどちらもCSSとしての意味がある。要素の意味はHTML仕様としておおむね規定されているが、クラス(class
属性の値)の意味に関しては、そのHTMLの書き手が勝手に決めていることだ。class
属性はHTML要素の意味を拡張する機構で、たとえばMicroformatのような仕様が、HTML仕様で規定されない意味を表現するために使っている。しかし、そういう仕様で規定されていない、独自クラス fruits__item
が厳密にどのような意味をもっているのかを知ることは難しい。人間は(あるいは今日のLLMは)fruits__item
というクラス名に埋め込まれた英単語の意味を解釈できるかもしれないが、それはCSS自体のセマンティクスではなく、英単語の意味を解釈している。CSS意味の先にある人間の意図を説明しているか、という観点では、差があるだろう。ただ、それは、パスを使ったからセマンティックでないとか、クラス名だからセマンティックだ、ということにはならない。これが ul > li
というセレクターだったら、「ul要素の子li要素」という意味の先にある「順序なしリストのリストアイテム」という意図は明瞭だろうし、逆に、.aaaa
のようなセレクターだったら、クラス名を使っていても意図を読み取ることはできない。また、ulやliのような要素の意味はHTML仕様で規定されているが、fruits__item
クラスの要素がどのような意味であるのかを知るには、どうにか推測するしかない。
ここに書くことは特に個人的な考えになるとは思うのだけれども、CSS自体は、あまり「セマンティック」な仕組みではないかもしれない。というのも、CSSは、DOMに対して構文的にマッチし、マッチした要素に対してCSSプロパティを割り当てる機構だからだ。CSSの処理の仕組み上、HTMLの各要素が本来持っているセマンティクスは、無視して処理することになる。だから、HTMLの意味上は同じ意味になるはずでも、CSSは異なるスタイル付けをしてしまう。たとえば <div>
要素の意味は "The div element has no special meaning at all. It represents its children." のように定まっている。だからといって、CSSは<div>
要素を無視して処理したりはしない。
HTML のセマンティクスの拡張
先述のように、HTMLではclass
属性を使って、HTML自体に規定されていない要素の意味を表現することができる。その他に、意味の拡張を行いたいのであれば、カスタム要素を使うこともできる。カスタム要素は、class
属性を使った場合と違って、カスタム要素のAPIの提供が可能になるので、HTML仕様に規定されているプリミティブの要素と近い形で、カスタム要素を規定し、実装し、利用することができる。
その他、HTMLの意味を拡張・変更しているものに ARIA in HTML がある。HTMLのセマンティクスでは、アプリケーション操作中の遷移的なステートを表現しきれていないことがある。たとえば、トグルボタンを実装しようとしたとき、たとえ、HTMLのbutton要素と、JavaScript、CSSによってトグルボタンの視覚表現を実装したとしても、そうした視覚表現が使えないユーザーにとっては、アクセシビリティーの欠如したアプリケーションになってしまう。そういう、HTMLレベルでは欠如している情報をDOM HTML上で表現するため、ARIAではセマンティクスを拡張しており、トグルボタンの例でいえばaria-pressed
属性によって、トグルボタンのステートを表現し、支援技術を介して、より多くのユーザーがアプリケーションを利用することができる。
- ほぼ、というのは、JavaScriptには関数の名前を取得する方法が用意されていて、そういう名前の取得を行う処理を含んでいれば動作が変わるから。↩