Heim >Web-Frontend >HTML-Tutorial >Die Semantik von HTML und den zugehörigen Front-End-Frameworks
Über Semantik
Semantik untersucht die Beziehung zwischen Zeichen und Symbolen und die Bedeutungen, die sie darstellen. In der Linguistik geht es um die Untersuchung der Bedeutung von Symbolen (wie Wörtern, Phrasen oder Lauten) in der Sprache. Im Bereich der Front-End-Entwicklung umfasst die Semantik hauptsächlich die vereinbarte Bedeutung von HTML-Elementen, Attributen und Attributwerten (einschließlich Erweiterungen wie Mikrodaten). Diese formale Konventionssemantik, die häufig in Spezifikationen verwendet wird, kann Programmen (und später an der Entwicklung beteiligten Personen) helfen, alle Aspekte einer Website besser zu verstehen. Selbst wenn die Semantik dieser Elemente, Attribute und Attributwerte formalisiert ist, unterliegen sie dennoch der Anpassung durch Entwickler und kollektiven Entscheidungen. Dadurch ist es möglich, dass die formale Vertragssemantik in Zukunft geändert wird (und dies ist eines der HTML-Designprinzipien).
Unterscheiden Sie verschiedene Arten der HTML-Semantik
Das Befolgen des Prinzips des Schreibens von „semantischem HTML“ ist eine der Grundlagen der modernen professionellen Frontend-Entwicklung. Die meisten Semantiken beziehen sich auf die aktuelle oder erwartete Art des Inhalts (z. B. h1-Element, lang-Attribut, E-Mail-Wert des Typattributs, Mikrodaten).
Allerdings muss nicht jede Semantik inhaltsorientiert sein. Klassennamen dürfen nicht „semantisch“ sein. Egal wie die Namen lauten, sie müssen eine Bedeutung und einen Zweck haben. Die Semantik von Klassennamen kann sich von der Semantik von HTML-Elementen unterscheiden. Wir können die „globale“ Semantik von HTML-Elementen, bestimmten HTML-Attributen, Mikrodaten usw. verwenden und dann die „lokale“ spezifische Semantik der Website oder Anwendung zur Unterscheidung verwenden. Diese spezifischen Semantiken sind normalerweise in Attributwerten enthalten, z Klassenattribute.
Obwohl diese vermeintliche „Best Practice“ im Klassenattributabschnitt der HTML5-Spezifikation wiederholt wird...
...werden Entwickler dazu ermutigt, den Klassenattributwert eher zur Beschreibung des tatsächlichen Inhalts zu verwenden als die Beschreibung Der voraussichtlich angezeigte Inhalt.
…Es gibt keinen eigentlichen Grund, warum ich das tun muss. Tatsächlich kann dieser Ansatz bei großen Websites oder Anwendungen oft zu einem Hindernis werden.
HTML-Elemente und andere Attribute stellen bereits Semantik auf Inhaltsebene bereit.
Für Maschinen oder Besucher können Klassennamen nur wenige oder keine nützlichen semantischen Informationen preisgeben. Sofern es sich nicht um einen kleinen Teil des Namens handelt, der vereinbart wurde (auch maschinenlesbar) – Mikroformate
Der Hauptzweck des Klassennamens besteht darin, ein Hook für CSS und JavaScript zu werden. Wenn Sie Ihren Seiten keine Präsentation und kein Verhalten hinzufügen müssen, müssen Sie Ihrem HTML wahrscheinlich keine Klassennamen hinzufügen. Klassennamen sollten Entwicklern nützliche Informationen vermitteln. Wenn Sie ein DOM-Fragment lesen, hilft es, den spezifischen Zweck eines bestimmten Klassennamens zu verstehen. Gerade in einem mehrköpfigen Entwicklungsteam sind nicht nur Frontend-Entwickler mit HTML-Komponenten beschäftigt.
<p class="news"> <h2>News</h2> [news content] </p>Wenn der Inhalt nicht offensichtlich ist, können Ihnen die Nachrichten zum Klassennamen nichts sagen. Es gibt Ihnen keine Informationen über die Gesamtstruktur der Komponente, und sobald der Inhalt keine „Neuigkeiten“ mehr ist, erscheint es sehr unangemessen, diesen Klassennamen zu verwenden. Die Semantik der Klassennamen ist zu nah am Inhalt und die Architektur ist weder einfach zu erweitern noch für andere Entwickler einfach zu verwenden.
Inhaltsunabhängige Klassennamen
Front-End-Architektur
Wiederverwendbare und zusammensetzbare Komponenten
避免用类型选择器支持class,可以让组件更容易合并。下面这个例子中,btn组件与uilist组件不易于合并。问题在于.btn的权重比.uilist a要小(这将覆盖任何共享属性)。而且ulist组件需要锚点作为子节点。
.btn { /* styles */ } .uilist { /* styles */ } .uilist a { /* styles */ } <nav class="uilist"> <a href="#">Home</a> <a href="#">About</a> <a class="btn" href="#">Login</a> </nav>
一种让uilist组件与其它组件轻松组合的方法是,uilist的子级DOM元素用class来添加样式。尽管这会降低权重,但是它的主要好处在于,它为你提供了处理子节点的任何结构样式的选择权。
.btn { /* styles */ } .uilist { /* styles */ } .uilist-item { /* styles */ } <nav class="uilist"> <a class="uilist-item" href="#">Home</a> <a class="uilist-item" href="#">About</a> <span class="uilist-item"> <a class="btn" href="#">Login</a> </span> </nav>
JavaScript专用类
使用某种形式的JavaScript专用类,可以降低因组件样式或结构的改变导致JavaScript失效的风险。我已经找到了一种非常有效的方法,那就是专为JavaScript的钩子使用一种特定的类——js-*——不要在这个类名上添加任何描述。
<a href="/login" class="btn btn-primary js-login"></a>
在你修改组件的结构或样式的时候,可能会不经意间对那些必要的JavaScript行为和复杂的功能造成影响,用这种方法的话,可以降低这种可能性。
组件修改器
组件常常会有一些变体,它们与基本组件只有细微的差别。比如,不同的背景色或者边框。主要有两种创建这些组件变体的模式。我将它们称为“单类名”模式和“多类名”模式。
单类名模式
.btn, .btn-primary { /* 按钮模板样式 */ } .btn-primary { /* 主按钮的特殊样式 */ } <button class="btn">Default</button> <button class="btn-primary">Login</button>
多类名模式
.btn { /* 按钮模板样式 */ } .btn-primary { /* 主按钮的特殊样式 */ } <button class="btn">Default</button> <button class="btn btn-primary">Login</button>
如果你使用预处理程序,你可以用Sass的@extend功能,以减少一些在使用“单类名”模式时所涉及的维护工作。然而,即使有预处理程序的帮忙,我依然倾向于使用“多类名”模式,并在HTML中修改类名。
我发现这是一种更具扩展性的模式。比如,要实现一个基本的btn组件,并增加5种类型的按钮与3种额外的尺寸。用“多类名”模式的话只要9个class就可以搞定,用“单类名”模式则需要24个class。
如果需要的话,它也更容易让上下文环境适应组件。你可能想对出现在其它组件中的任一btn做一些细节调整。
/* “多类名”样式调整 */ .thing .btn { /* 相应的样式调整 */ } /* “单类名”样式调整 */ .thing .btn, .thing .btn-primary, .thing .btn-danger, .thing .btn-etc { /* 相应的样式调整 */ }
“多类名”模式意味着,你只需要用一个单独的组件内部选择器,便可以改变所有类型的btn元素的样式。“单类名”模式意味着,你必须顾及所有可能的按钮类型,并在创造一个新的按钮变体时调整这个选择器。
结构化的类名
当创建一个组件时——并为之添加了“主题”——其中一些class被用来区分各个组件,一些class被当做组件的修改器,其它的class则被用来关联DOM节点,它们一起被包含在一个较大的抽象组件中。
很难去判断btn(组件)、btn-primary(修改器)、brn-group(组件)和btn-group-item(组件子对象)之间的关系,这是因为这些名字不能清晰地表现class的目的。没有一致的模式。
在过去的一年中,我一直在尝试命名模式,目的是能帮助我快速理解在一个DOM片段中节点的表象之间的关系,而不用为此来回切换HTML、CSS与JS文件拼凑网站的架构。这种模式主要受到BEM系统的命名方法的影响,但被改编成一种我认为更容易浏览的形式。
t-template-name t-template-name--modifier-name t-template-name__sub-object t-template-name__sub-object--modifier-name</p> <p>component-name component-name--modifier-name component-name__sub-object component-name__sub-object--modifier-name</p> <p>is-state-type</p> <p>js-action-name js-component-type
我将一些结构当做抽象的“模板”来处理,其它的则视为更清晰的组件(通常建立在“模板”上)。但是这种区分并非总是必要的。
这仅仅是我目前发现的一种有用的命名模式。命名模式可以采用任何形式。但这种命名模式的好处在于消除了模糊的类名,只依赖(单)连接符,或者下划线,或者是驼峰格式。
原始文件大小和HTTP压缩的注意事项
任何关于模块化与可扩展的CSS的讨论都会谈及对文件大小与“膨胀”的担心。Nicole Sullivan的言论中经常会提到文件大小的存储(以及维护改进),并提到了像Facebook这样的公司采用这种方法的经历。进一步的,我想我会分享我在预处理输出时的HTTP压缩效果,以及大量使用HTML类的一些事情。
当Twitter Bootstrap刚刚问世的时候,我重写了已编译的CSS,以便更好地与手动操作的文件比较大小。在最小化所有的文件之后,手动操作的CSS文件比预处理程序输出的小10%。但是当所有的文件都通过gzip压缩后,预处理程序输出的CSS文件比手动操作的小了5%。
这强调了比较HTTP压缩后文件大小的重要性,因为减少的文件大小并不能说明全部问题。它暗示了有经验的CSS开发者在用预处理程序时不必太过关注编译后的CSS中一定程度的重复,因为它将在HTTP压缩后变得更小。通过预处理程序处理更易于维护的CSS代码所带来的好处,要胜过关注原始CSS和压缩后输出的CSS的美观或文件大小。
In einem anderen Experiment habe ich eine 60 KB große HTML-Datei aus dem Internet gecrackt (bestehend aus vielen wiederverwendbaren Komponenten) und jedes ihrer Klassenattribute gelöscht. Nach dieser Verarbeitung reduziert sich die Dateigröße auf 25 KB. Wenn sowohl die Originaldatei als auch die extrahierte Datei mit gzip komprimiert werden, betragen ihre Größen 7,6 KB bzw. 6 KB – ein Unterschied von nur 1,6 KB. Die tatsächlichen Auswirkungen einer großzügigen Verwendung von Klassen auf die Dateigröße sind nicht länger der Rede wert.
Weitere Artikel zur Semantik von HTML und verwandten Front-End-Frameworks finden Sie auf der chinesischen PHP-Website!