ここが変だよHTML&CSS

## HTML

### 略語多すぎ問題

HTMLは略語のタグが多い。一文字の要素を挙げるだけでも`<a>` `<b>` `<i>` `<p>` `<q>` `
` `<u>`の7個ある。2文字の要素は現存しているだけでも20個あった。数え間違えているかもしれない。ここまでくるとニュースピークである。実際、意味合いがイニシャルが同じ別の言葉に置き換わる(例: `<dl>`は → "[Definition List](https://www.w3.org/TR/html401/struct/lists.html#h-10.3)"(定義リスト)から"[Description List](https://html.spec.whatwg.org/multipage/grouping-content.html#the-dl-element)"(説明リスト)に変わった)という「1984年」を思わせる改竄、もとい仕様変更が発生したりもした。元来の意味を忘れ、見た目だけで要素を作るテーブルレイアウトの暗黒時代は間違いなく略語のせいで発生した。今ですら本来の意味を逸脱して`<i>`タグが使われる始末だ。

おそらく、HTML成立時の貧弱なコンピューターでは、長い単語を打つのが大変で、打ち間違えが発生しやすいという理由から、比較的よく使われると考えられた要素を短くしていったのだろう。今となってはタグのサジェストリストや入力補助をVisual Studio Codeみたいなエディタが提案してくれる時代になったし、短すぎる名前の要素は新人コーダーの頭痛の種でしかない。幸いなことに、HTML5以降に追加された要素はいずれもフルネームだ。おかげで覚えやすくなったし、セマンティックウェブの推進もあって誤用も減った。

### 閉じる要素

HTMLの要素の多くは閉じタグを必要とする。`</p>`というあれだ。しかし、これはこれで冗長である。例えばこんな構造は実際にありえない(だからこそ人間がバグに気づきやすいという側面もあるにはある)。

``` html
<p>前<span>中</p>後ろ</span>
```

現代のエディタならタグのハイライトをしてくれるので、`</>`だけで省略できないかと考えてしまうのは昔を知らないからだろうか。

一部タグは条件により閉じタグを省略できる。しかし、これははっきり言ってありがた迷惑だ。なぜなら単体で意味のある要素がHTMLには存在するからである。`<br>`が代表例だ。初心者コーダーはぱっと見で要素の範囲を読み取ることができないばかりか、単体要素との区別がつかないのでこの書き方はおすすめできない。はっきり言えば、これは書き損じた、もしくは何らかの理由で破損したHTMLを読み取る際のフェイルセーフ機能だ。

### 閉じない要素

単体タグの要素を`<element />`と書く流儀がある。これはバーナーズ=リー博士が一時期流行らせようとし~~て失敗し~~た~~誰得言語~~XHTMLの記法だ。サイトのHTMLソースを見てXHTMLだと「このページ年季入っているなあ」という何とも言えない感慨がある。区別は重要だが、これはこれで面倒くさい。

思うに、すべての言語を閉じタグ形式にして、フォールバック要素をテキストとして入力するべきだった。`<video>`要素などでとられた設計だ。`<img>`の`alt`属性はこの実装方法なら不要だった。ただ`<br>`はどうなるか。英文ならスラッシュが入るだろうが、日本語なら空要素になるし、全ての`<br>`に同じ内容が入るので冗長である。文書の改行をそのまま読み込める仕様にすべきだったと思うのは、昔の1行80字制限を知らないからだろうか。いにしえのWebページを見ていると、改行に起因すると思われる謎の半角スペースがちらほら見受けられて何ともやるせない気持ちになる。

現代ならCSSで`white-space: pre`もしくは`white-space: pre-wrap`とすれば、ソースの改行を残すことができる。現代のエディターには長い行の自動折り返し機能がついている。そのため2022年現在、`<br>`を使うべき積極的な理由は無い。

### `<html>`タグ結局必須説

`<html>`は開始・終了の両タグを省略可能である。ただ、開始タグを省略すると問題が発生する…文書の言語`lang`を指定できないのだ。つまり、ブラウザにとって`<html>`が無い文書は宇宙人の言葉である。文書を丸々開始終了タグで囲うのは冗長という他無いので、残念である。以前この仕様的矛盾に関してWHATWGで質問したが、「別に矛盾してないじゃん」と言われスルーされたのをよく覚えている。本来、`<meta>`タグで設定すべき事柄だろう。

### `<head>` `<header>`なら`<headest>`は無いの？

もちろん、表題は冗談だ。実際の問題は紛らわしいタグが2つ存在するということだ。どっちがどっちか分からなくなったコーダーも多いことだろう。`<head>`ではなく`<settings>`ないし`<preference>`という名前なら、HTMLの設定をする部分だなというのが伝わってくる。名前がおかしい要素第1弾。

(2022/4/4)HTMLの最初期の仕様では、`<head>`は`<header>`だった。この方がHTTPヘッダに対応する要素ということが分かりやすかった。なぜ縮めたのだろうか。

### `<meta>`タグの混乱

`<meta>`タグは事業者が自由に拡張できるという特性を持つためか、やたら冗長である。いちいち`name`と`value`属性を指定しないといけないのは手打ちコーダーにとって面倒だ。`http-equiv`なんて関係あるのはブラウザだけだ。なんで`name`に統一できない？　また、そもそもname属性で指定するのではなく`<meta foo="bar" baz="hoge">`と書けるのであれば冗長性は無かったろうにと思う。いや、今なら直接JSONで書けるほうが開発者には大助かりなのではないか(どこかのhtmlトランスパイル言語でありそうな仕様だ)。

(2022/4/26) よく使われる`<meta>`名なら独立した要素にした方が利便性は高いだろうに、と思わざるを得ない。おまけに、Open Graph ProtocolはRDFaの`property`属性（`<meta>`属性の標準属性ではないのでややこしい）を使っているし。

### えっ、`<link>`ってリンクじゃなかったの？

**おそらく初心者が一番混乱する部分だ**。なぜこんなよく分からん仕様にしたのか、バーナーズ=リー博士に問い質したい。[10億ドル](https://ichi.pro/su-ju-oku-doru-no-machigai-60894245906962)には満たないだろうが、100万ドルはくだらないミスである。

Hyperlinkとうたわれるとおり、HTMLは他の文書との「リンク」がカギを握る言語だ。それでは他の文書を参照する際のタグは？？？　答えは`<a>`タグだ。こんなの分かるかーい！　では`<link>`は何なのかというと、おなじみMDN曰く「[現在の文書と外部のリソースとの関係を指定](https://developer.mozilla.org/ja/docs/Web/HTML/Element/link)」する要素とのことだ。言われただけでは何のことだかさっぱり分からない。具体的にはスタイル`rel="stylesheet"`やアイコン`rel="icon"`などを読み出すのに使用される。あとは先読みする要素に`rel="preload"`指定及び`rel="prefetch"`を付けて(スクリプトなどの割といろいろなものを)読み出せるようにする。はっきり言って抽象的すぎる要素だ。スタイルシートは`<style>`で読み込むのが自然だし(また後でも話題になるよ)、アイコンは`<icon>`属性を作るべきだ。

さらに解せない仕様は御覧の通り、**リンクするファイルの種別指定も、読み出し方法の指定も同じ`rel`属性が使われる**ということだ。その場合ファイル種別は`as`で指定する。言葉の意味的には分かるけれども、仕様が混沌とし過ぎている。`preload`などは`<style>`や`<script>`に対する属性として定義すべきだった。

そして`<a>`タグはanchorの略字だが、はっきり言って分かりづらい。`<abbr>`、`<address>`などaで始まるタグは多いし、先ほど述べた通り**HTMLを知らない一般人にとってはこのタグこそがリンクだ**。最初にCERNで仕様をまとめた研究者の皆さんは誰もこのことに突っ込まなかったのだろうか。名前がおかしい要素がさらに2つ増えた。

### `<style>`と`<script>`の一貫性の無さ

先程も述べた通り、外部スタイルシートを読み込むには`<link>`タグを使う。しかし、外部スクリプトは基本的に`<script>`だ。まるで意味がわからんぞ。おまけに、`<script>`で外部ソースを参照すると、中身は空でなければならないので格好悪い。`<script src="foo.js" />`と書いて単体タグ化できたら良かったのに。`<style>`は内部ソースしか読みこめないので、ページのクリティカルな(ロード直後に表示される要素の)スタイルを記述するのにつかわれるが、`<link>`の`preload`指定や`prefetch`指定があるために、これから衰退していくのは間違いないと思われる。

また、`<link>`および`<a>`は外部ソースの参照に`href`属性を使う。しかし、`<script>`と`<img>`は`src`である。これって分ける意味ある？　習得のしやすさを考えればsourceの略語である`src`に統一すべきだった。

url記法の不一致についての詳細は以下の記事に書いてある。

https://decketts.medium.com/it-is-time-to-finally-retire-html-c751a2c9c3cd

### 見出し系タグ

`<h1>` ~ `<h6>`であるが、タグ名にレベルが付属しているというよくわからない仕様である。HTML初期の略語を使う設計思想のせいもあるが、見出しランク属性を付けないという判断は明らかに間違いだったと思う。[`<h>`要素を追加しようという議論がWHATWG内である](https://github.com/whatwg/html/issues/7390)(もっと遡れば[W3C時代にも議論があった](https://github.com/w3c/html/issues/774))が、まだ決着は着いていない。このことにより、見出しレベルは単一文書内でのものしか表現できないので、HTMLのモジュール化が阻害される大きな要因と言える。

例えば`<h rank="-1">`とか記載できれば、文書のどこにあっても「前の見出しより1レベル小さいんだな」という風に解釈ができたのに！

### 謎のOutline Algorithm

HTML5の目玉機能として、`<section>`を使った意味合いの区切りの定義があげられるが、その際に考案されたのがOutline Algorithmだ。詳細は省くが、恐ろしいことにどのブラウザも実装していない。アルゴリズムのコストがかかりすぎるかららしい。文字通りの絵に描いた餅だ。そのため、複数`<h1>`を記述すべきかどうかいまだに意見が分かれる。実質存在していない機能を仕様に書くのは混乱のもとだということで、[使わないように警告を出すかどうかという議論がWHATWGでなされている](https://github.com/whatwg/html/issues/83)。

### コンテキストに応じる変化が少ない

HTMLのタグの多くが、特定の場所でしか使えない（親要素の制限がある）。コンテキストで特殊な意味合いを持つタグの例と言えば、`<dl>`内の`<div>`(用語のまとまりを示す)程度である。例えば、`<title>`が`<body>`内で使えたら、文章の主題だということがよりはっきり伝えられるのに(ついでに地味にうっとおしい宗教論争の種である「`<h1>`複数入れるか問題」も発生しなかった)！　`<caption>`(テーブル専用。なのに珍しく`t`で始まらない。何故だ)が`<figure>`に対応していれば、`<figcaption>`タグは不要だった。このように、使いどころが決まりすぎているタグが多く、覚えるタグの多さは初学者にとってハードルとなっている。

### (2022/4/4)`<ol>`と`<ul>`

この2つを別々の要素にしたのはなんでだろうか。正直順番付けするかどうか決めかねるリストも多いわけだし(並び順が大事かどうかいつも悩む)、1つの`<list>`要素として定義して、`type`属性や`start`属性が設定されている場合は順序付きリストとして扱うほうがスマートだったように思う。さらに言えば、CSSの`list-style`属性で`<ol>`を`<ul>`にしてしまうことだってできるわけだし、わざわざ分ける意味あったのかな。

上の「コンテキストに応じる変化が少ない」と合わせると、`<item>`要素を定義して、リストの中身とテーブルのセルを両方表せると分かりやすかったのではなかろうか。いや、逆に混乱するかも。

### (2022/4/4)`<table>`の方向

行は必ずインライン方向(日本語横書きの場合は左から右)、列はブロック方向(同条件で上から下)である。この辺り自由に選択できた方が書きやすかったり、意味が通りやすくなる場合もあるのではないか。そもそもテーブル自体が古臭い(CSSの制御が面倒なので`flex`や`grid`に逃げる輩が多い)部分があるので何とも言えないが。

### (2022/4/4)`class`における齟齬

プログラミング言語における`class`は、「[オブジェクトを生成するための設計図あるいはひな形に相当するもの](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%A9%E3%82%B9_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF))」であり、1オブジェクトにつき1つのクラスが割り当てられる。

しかし、HTMLのクラスは複数設定できる。しかも、JavaScriptというオブジェクト指向言語における`class`とは別である。おまけに属性説明が「[representing the various **classes** that the element belongs to.](https://html.spec.whatwg.org/multipage/dom.html#classes) (要素の属する様々なクラスを表す。)」と要領が悪い。そもそもその「クラス」って何やねん。予約語との兼ね合いもあり、JSでは最初から`className`と呼ばれていたが、正直`attribute`という名前の方が適切で、オブジェクト指向言語をかじったデザイナーに受け入れやすいものになったのではないか(これはこれでJSで属性を読み出すのに苦労ことになるが)。

## CSS

CSS3以降、仕様策定のスピードが上がっているため、突っ込みどころは比較的少ない。思いついたところだけ挙げる。

### `margin`指定の順番

3つまでは分かる。上→左右→下という順番だからだ。しかし、4つ目の値になると、なぜか上→右→下→左という指定になる。もし使う言語がアラビア語みたいなRTLだったら問題は無いが、英語にせよ日本語にせよ大多数の言語がLTRである。座標を決める値が最後というのは直感的ではない。

### ポジション指定にまつわるエトセトラ

~~`top`、`bottom`、`left`、`right`を一括で決められるプロパティが無い。いちいち`top`が何px、`left`が何pxという指定しかできないので地味に面倒。~~`inset`プロパティで指定できるようになりました。割と最近のことなので抜け落ちていました。

`position`が`absolute`などの絶対指定での起点は一番直前の`position: relative`な要素である。分かり辛いうえに、間違った要素に紐づけされてしまう危険もある。直近の親要素を起点とすべきとW3Cに提案したが、破壊的変更が過ぎるということで却下された。仕方ないね。

### [詳細度](https://developer.mozilla.org/ja/docs/Web/CSS/Specificity)問題

CSSの特徴として、コンテキストをセレクタにより分かりやすく指定できるという点がある。ただ、この方法には問題がある。詳細度がコントロールできないということだ。複雑すぎるセレクタは往々にして「どこのどの要素をどのスタイルにしたい」と設定するために書かれるもので、スタイルの優先度を上げるというのは完全な副作用である。

これがあるから、冗長性において悪名高いが有用性の高いBEMという手法が開発されるに至った。これは文書の論理構造ではなく文章の場所、要素、特徴を記述するというスタイルだ。もはやカスケードでは無い。

個人的には、右から左へ評価すべきだった。まず1番右のランクが高い方が優先され、同じ場合のみその左を見るというスタイルが、より開発者の意図通りのスタイル指定になったろうにと考える。`:where`属性で一番右以外をくるんでしまえば、このような書き方ができるようになる。

(2022/3/27)また、新しい仕様として「[Cascade Layers](https://coliss.com/articles/build-websites/operation/css/cascade-layers.html)」というものが考えられている。これはCSSの詳細度に「`@layer`指定の順番の後勝ち」という新しい要素が追加されるというものだ(インラインスタイル>レイヤー無しのスタイル>`@layer`指定>セレクタの詳細度という優先度)。つまり、セレクタの詳細度問題に悩まされる可能性が少なくなり、構造に頼ったカスケード指定がやりやすくなるようだ。

### (2022/3/27)CSS変数の怪

だいぶ前のことになるが、CSSに変数が追加された。しかし、過去のコードとの互換性の問題からか、その書式はかなり変なものになっている。

- 変数指定は「`--table-first-width: 5em;`」で行う。
- しかし、それを使用する際には「`width: var(--table-first-width);`」と書かなければならない。

読み手的には`--`が語頭に付いているので変数だということは十分伝わるのに、使用する際には`var()`で囲まなければならない(原理的には`var`のカッコ内は`--`で始まるものしか無い)ので、あまりにも冗長である。

(2022/4/22) 理由は[こちら](https://github.com/w3c/csswg-drafts/issues/2111)に示されていた。カウンターなどの識別子として`--x`などの値が使えてしまうからだ。あとからルールを追加したことによる弊害である。正直こうなったらJSの`"use strict"`みたいにバージョンを分けて破壊的変更をした方が良いように思うが？　[バージョニングがされないことによる弊害](https://qiita.com/NagayamaToshiaki/items/b56380aecf55803f52a5)も考えると、黒歴史との向き合い方は業が深い。

### (2022/4/4)`color`って何の色？

文字自体の色(気取って言えば「前景色」)だが、ただ色と言われて文字が思い浮かぶ人はまずいない。色関係のショートハンド名だと言われた方がすっきりする名前だ(コントラストを考えると、文字と背景をまとめて設定できた方が調整しやすそう)。無難に`text-color`とすべきだったのではないか？

### (2022/4/4)font? text? letter?

書体関連は`font-*`、文章中の文字関連は`text-*`とかなり厳密に呼び分けているが、正直どっちだっけと悩む部分がある。例えば、`text-align`は`font-align`にならないのは分かるが、`text-decoration`は時々`font-decoration`と書いてしまいそうになる自分がいる。そんな時は待ちガイルのように一旦溜めて、修正するわけだが、文字関連は`text-*`に統一してしまった方が良かったのではないかと思う。

しかし、解せないのは文字関連の中に`letter-spacing`があるということである。`letter`で始まるのはこの属性だけで、普通に`text-spacing`でよかったのでは、と思わざるを得ない。

### (2022/4/4)アプリ作成における「見た目とセマンティクスの分離」の面倒さ

ニュースサイトなどの情報提供がメインのサイトの場合、見た目とセマンティクスの分離は喜ばしいことである。リニューアルのたびに過去記事のコードを変えなくても済むからだ。

しかし、アプリの場合はデバイスがある程度決まってくる(スマフォなど、画面サイズ固定のものが多い)し、配置の微調整が必要になってくる。そうなると見た目とセマンティクスは不可分である。個人的には好きな手法ではないが、Atomic CSSが重宝されるのも無理はない。通常のCSSを修正しようものなら、要素に関連するCSSスタイルの特定(devtoolsでやってくれるけど)→変更による影響範囲の調査(Chromeならページ内は助けてくれる)→問題があれば新規クラス作成→修正というステップを踏まなければならない。BEMを使おうともこれらをしっかりやらないと見た目の破綻は起こりうる。その点、他の要素との関連性が排除されたACSSなら変更は早い。ただぶっちゃけ、現在アンチパターンと見なされている`style`属性とほとんど変わりがないし、数年後には`style`属性が見直されているのではなかろうか。

PWAなどと騒がれる昨今だが、実はHTML・CSSとアプリ開発の相性というのはあまり良くないのではないか、というのが「[HTMLブラウザエンジンの行く末とWeb4について思うことDX](https://qiita.com/NagayamaToshiaki/items/654e696f753c32b0b5df)」を書いた動機の1つとなっている。「何でもできる」というのは「何でもうまくできる」というのと違うのだ。