1. ホーム
  2. Web制作
  3. HTML/Xhtml

HTMLのセマンティクスと関連するフロントエンドフレームワークの詳細分析

2022-02-05 23:09:31

セマンティクスについて

意味論は、記号やシンボルと、それらが表す意味との関係を研究する学問です。言語学では、これらの記号(単語、フレーズ、音など)が言語において持つ意味に焦点を当てます。一方、フロントエンド開発の分野では、HTMLの要素、属性、属性値(Microdataなどの拡張を含む)に対して合意された意味を主に扱います。このように正式に合意されたセマンティクスは、一般に仕様書として使用され、プログラム(後に開発に携わる人々)がサイトの様々な側面に関する情報をより理解するのに役立ちます。しかし、これらの要素、属性、プロパティ値のセマンティクスが形式化されていても、開発者の適応度や一般的な選択の対象になることは変わりません。このため、形式的な規約のセマンティクスも将来的に変更される可能性がある(これはHTMLの設計原則の1つである)。
HTMLセマンティクスの種類を区別する

セマンティックなHTMLを書くという原則を守ることは、現代のプロフェッショナルなフロントエンド開発の基礎の1つです。セマンティックのほとんどは、現在または予想されるコンテンツの性質に関連しています(例:h1要素、lang属性、type属性のメール値、Microdataなど)。

しかし、すべてのセマンティクスがコンテンツ指向である必要はない。クラス名は、意味的に無意味なものであってはならない。どのような名前を使うにしても、意味と目的を持たなければなりません。クラス名のセマンティクスは、HTML要素のセマンティクスとは異なる場合があります。HTML要素、特定のHTML属性、Microdataなどの"global"セマンティクスを利用し、サイトやアプリケーションの"local"固有のセマンティクス(通常class属性などの属性値に含まれる)を利用して区別することが可能です。

を使用していますが のセクションでは、HTML5仕様のclass属性である この推定される "ベストプラクティス" の class 属性に関するセクションで繰り返し述べられています。

    ...開発者は、表示されることが期待される内容を記述するのではなく、実際の内容を記述するために class 属性値を使用することを推奨しています。

...そうしなければならない理由は、本来はないのです。実際、この方法を大規模なサイトやアプリケーションで使用する場合、しばしば障害となることがあります。

    HTML要素やその他の属性は、すでにコンテンツレベルのセマンティクスを提供している
    クラス名が機械や訪問者に示すことのできる有用な意味的情報は、あったとしてもごくわずかなものです。それが合意された(そして同様に機械が読める)名前の小さな部分であれば別ですが -- Mircoformats
    クラス名の主な用途は、CSSやJavaScriptのフックとなることです。もし、ページに表示や動作を追加する必要がないのであれば、おそらくHTMLにクラス名を追加する必要はないでしょう。
    クラス名は、開発者にとって有益な情報を伝えるものでなければなりません。DOM フラグメントを読むとき、クラス名が何をするものかを正確に理解するのに役立ちます。特に複数人で共同開発するチームでは、HTMLコンポーネントを扱うのはフロントエンドの開発者だけではありません。

非常に簡単な例として

このクラス名newsは、コンテンツが明白でない場合には、何も教えてくれません。また、コンテンツがもはや "news"でなくなった時点で、このクラス名の使用は非常に不適切です。クラス名のセマンティクスがコンテンツに近すぎるため、アーキテクチャが容易に拡張できず、他の開発者が使用することもできません。
コンテンツに依存しないクラス名

より良い方法は、デザインパターンの構造と機能からクラス名のセマンティクスを抽出することである。コンテンツに依存しないクラス名を持つコンポーネントは、より再利用しやすくなります。

クラス名で明示的な内容を厳密に反映させるのではなく、レイヤー間の関係(この場合は構造レイヤー、コンテンツレイヤーなど)を明確かつ明示的にすることを恐れてはならない。これは、クラス名を意味的なものにするのではなく、その意味論がコンテンツに依存しないことを示すだけである。また、より強く、より柔軟で、より再利用性の高いコンポーネントを作成するのに役立つのであれば、追加のHTML要素を使用することを恐れるべきではないでしょう。これはHTMLをセマンティックにするものではなく、単にコンテンツをマークアップするために最小限の要素数以上のものを使っていることを意味します。
フロントエンドアーキテクチャ

コンポーネント、テンプレート、オブジェクト指向のアーキテクチャの目的は、ある範囲内で異なるコンテンツタイプを含むことができる、限られた数の再利用可能なコンポーネントを開発できるようにすることである。大規模なアプリケーションにおけるクラス名のセマンティクスにとって最も重要なことは、プラグマティズムをもってその主目的を果たすこと、つまり、開発者が使用する表現または動作について、意味があり柔軟で再利用可能なフックを提供できることである。
再利用可能でコンポーザブルなコンポーネント

つまり、拡張可能なHTML/CSSは、再利用可能なコンポーネントを作成するために、HTMLのクラスに依存する必要があるのです。柔軟で再利用可能なコンポーネントは、DOM ツリーの特定の部分に依存することも、特定のタイプの要素を使用する必要もありません。異なるコンテナに適応でき、簡単にテーマを変更できる必要があります。必要であれば、HTML要素(マークアップの内容に必要な要素以外の要素)を追加することで、コンポーネントをより強固にすることができます。Nicole Sullivanがメディアオブジェクトと呼ぶものは、この良い例です。

タイプセレクタでクラスサポートを回避すると、コンポーネントの結合が容易になります。以下の例では、btn コンポーネントは uilist コンポーネントと簡単にマージされません。問題は、.btnは.uilist a(共有された属性を上書きする)よりも重みがないことです。また、ulistコンポーネントは子ノードとしてアンカーを必要とします。

uilistコンポーネントと他のコンポーネントを簡単に組み合わせる方法の1つは、uilistの子DOM要素にclassでスタイルを追加することです。これは重量を減らす一方で、その主な利点は、子ノードの任意の構造的なスタイルを処理するオプションを提供することです。

JavaScript 固有のクラス

何らかの形でJavaScript固有のクラスを使用することで、コンポーネントのスタイルや構造を変更したためにJavaScriptが失敗するリスクを減らすことができます。私は、JavaScriptフックのためだけにjs-*という特定のクラスを使用し、そのクラス名には何も説明を加えないという、非常に効果的な方法を見つけました。

コンポーネントの構造やスタイルを変更した場合、不用意にそれらの必要なJavaScriptの動作や複雑な機能に影響を与える可能性がありますが、この方法ではその可能性が低くなります。
コンポーネントモディファイア

コンポーネントには、ベースとなるコンポーネントとほんの少し異なるバリアントが存在することがよくあります。例えば、背景色やボーダーが異なるなどです。このようなコンポーネントのバリエーションを作成するには、主に2つのパターンがあります。私はこれを「単一クラス名パターン」と「複数クラス名パターン」と呼んでいます。

単一クラス名パターン

マルチクラス名パターン

プリプロセッサを使用する場合、Sassの@extend機能を使用すると、"単一のクラス名"パターンを使用した場合のメンテナンスの一部を軽減することができます。しかし、プリプロセッサを使っても、私は"multiple class names"パターンを使い、HTML内のクラス名を変更する方が好きです。

このパターンは、よりスケーラブルだと思います。例えば、基本的なbtnコンポーネントを実装し、5種類のボタンと3種類のサイズを追加する場合。このとき、quot;multiple class names"パターンでは9クラスで済みますが、quot;single class names"パターンでは24クラス必要になってしまいます。

また、必要に応じて、コンテキストをコンポーネントに適合させることも容易である。他のコンポーネントに表示されるbtnの詳細を微調整したい場合があります。

multiple class name" パターンは、コンポーネントの単一の内部セレクタで、すべてのタイプのbtn要素のスタイルを変更できることを意味します。単一クラス名" パターンは、新しいボタンのバリエーションを作成するときに、すべての可能なボタンの種類を考慮し、セレクタを調整する必要があることを意味します。
構造化されたクラス名

コンポーネントが作成され、それに "theme" が追加されると、クラスのいくつかはコンポーネントを区別するために使われ、いくつかはコンポーネントへの修飾子として使われ、他のいくつかはより大きな抽象コンポーネントで一緒に DOM ノードを関連付けるために使われます。他のクラスは、DOMノードを関連付けるために使用され、一緒に大きな抽象的なコンポーネントに含まれます。

btn(コンポーネント)、btn-primary(モディファイア)、brn-group(コンポーネント)、btn-group-item(コンポーネント子オブジェクト)は、これらの名前がクラスの目的を明確に表していないため、関係を判断することが困難です。一貫したパターンがない。

この目的のために、HTML、CSS、JS の各ファイルを行ったり来たりしてサイトのアーキテクチャを組み立てなくても、DOM フラグメント内のノードの表現間の関係をすばやく理解できるようにするための命名パターンを、この 1 年間、実験的に使用しています。このパターンは、BEMシステムの命名アプローチに大きく影響されていますが、私がより簡単にナビゲートできるような形にアレンジされています。


テンプレート名
t-template-name-modifier-name
t-template-name__sub-object
t-template-name__sub-object--modifier-name</p> <p>component-name
コンポーネント名-修飾名
コンポーネント名__サブオブジェクト
component-name__sub-object--modifier-name</p> <p>is-state-type</p> js-アクション名
js-component-type(コンポーネントタイプ

私は、ある構造を抽象的なテンプレートとして扱い、他の構造をより明示的なコンポーネント(多くの場合、テンプレートの上に構築される)として扱っています。しかし、この区別は必ずしも必要ではありません。

これは、私がこれまでに便利だと思ったネーミング・パターンのひとつに過ぎない。ネーミングパターンはどんな形でもいいのです。しかし、この命名パターンの利点は、曖昧なクラス名を排除し、(単一の)合字、アンダースコア、キャメルフォーマットだけに頼っていることです。
生ファイルのサイズとHTTP圧縮の考慮事項

モジュール化された拡張可能なCSSについて議論すると、ファイルサイズやquot;bloat"に関する懸念が浮上します。 ニコル・サリバンの発言 は、ファイルサイズの保存(とメンテナンス性の向上)についてよく言及し、このアプローチを採用したFacebookなどの企業の経験について触れています。さらに、私の前処理された出力に対するHTTP圧縮の効果や、HTMLクラスを多用して行ったことを紹介しようと思いました。

Twitter Bootstrapが初めて登場したとき、私はコンパイルされたCSSを書き直して、手動で操作したファイルとのサイズ比較をより良くしました。すべてのファイルを最小化した後、手動で操作した CSS ファイルは、プリプロセッサの出力よりも 10% 小さくなりました。しかし、すべてのファイルを gzip で圧縮すると、プリプロセッサで出力された CSS ファイルは手動で出力されたものより 5 % 小さくなりました。

これは、HTTP圧縮後のファイルサイズを比較することの重要性を強調するもので、ファイルサイズの減少がすべてを物語っているわけではありません。これは、経験豊富な CSS 開発者がプリプロセッサを使用する場合、HTTP 圧縮後のファイルサイズが小さくなるため、コンパイルされた CSS にある程度の繰り返しがあっても、あまり気にする必要がないことを示唆しています。プリプロセッサによって保守性の高い CSS コードが処理されることのメリットは、生の CSS と圧縮後の CSS の美観やファイルサイズに関する懸念よりも大きいのです。

別の実験では、60KBのHTMLファイル(多くの再利用可能なコンポーネントで構成)をワイヤーから取り出し、そのクラス属性をひとつひとつ削除しました。元のファイルと剥がしたファイルの両方をgzipで圧縮すると、それぞれ7.6KBと6KBになり、その差はわずか1.6KBでした。classの自由な使用による実際のファイルサイズの結果は、もはや強調するほどのものではありません。