属性

HTML 概览中简要介绍了属性;现在,我们来深入探讨一下。

属性是 HTML 如此强大的根本原因。属性是开头标记中以空格分隔的名称和名称/值对,用于提供元素的相关信息和功能。

HTML 元素上的标记开头标记、属性和结束标记。

属性用于定义元素的行为、关联和功能。有些属性是全局属性,这意味着它们可以在任何元素的开头标记中显示。其他属性适用于多个元素,但不适用于所有元素,而其他属性则因元素而异,仅与单个元素相关。在 HTML 中,除了布尔属性和在某种程度上枚举的属性之外,所有属性都需要值。

如果属性值包含空格或特殊字符,则必须用英文引号括起。因此,为了提高可读性,我们始终建议使用引号。

虽然 HTML 不区分大小写,但某些属性值会区分大小写。HTML 规范中的值不区分大小写。 定义的字符串值(例如类和 ID 名称)区分大小写。如果某个属性值在 HTML 中区分大小写,那么在 CSS 和 JavaScript 中将其用作属性选择器的一部分时,它也会区分大小写;否则,它不会区分大小写。

<!-- the type attribute is case insensitive: these are equivalent -->
<input type="text">
<input type="TeXt">

<!-- the id attribute is case sensitive: they are not equivalent -->
<div id="myId">
<div id="MyID">

布尔值属性

如果存在布尔值属性,则该属性始终为 true。布尔属性包括 autofocusinertcheckeddisabledrequiredreversedallowfullscreendefault,loopautoplaycontrolsmutedreadonlymultiple,selected。如果存在其中一个(或多个)属性,则表示相应元素处于停用、必填、只读等状态;如果不存在,则表示相应元素不处于这些状态。

布尔值可以省略、设置为空字符串,也可以是属性的名称;但值实际上不必设置为字符串 true。所有值(包括 truefalse😀)虽然无效,但都会解析为 true。

以下三个标记是等效的:

<input required>
<input required="">
<input required="required">

如果属性值为 false,请省略该属性。如果该属性为 true,请添加该属性,但不要提供值。例如,required="required" 在 HTML 中不是有效值;但由于 required 是布尔值,因此无效值会解析为 true。不过,由于无效的枚举属性不一定会解析为与缺失值相同的值,因此养成省略值的习惯比记住哪些属性是布尔值,哪些属性是枚举值,以及哪些属性可能会提供无效值更容易。

在 true 和 false 之间切换时,请使用 JavaScript 完全添加和移除该属性,而不是切换值。

const myMedia = document.getElementById("mediaFile");
myMedia.removeAttribute("muted");
myMedia.setAttribute("muted");

请注意,在 SVG 等 XML 语言中,所有属性(包括布尔属性)都需要包含值。

枚举属性

枚举属性有时会与布尔值属性混淆。它们是具有一组有限的预定义有效值的 HTML 属性。与布尔属性一样,如果存在此类属性但缺少值,则会采用默认值。例如,如果您添加 <style contenteditable>,则它默认为 <style contenteditable="true">

不过,与布尔值属性不同,省略该属性并不意味着其值为 false;缺少值的存在属性不一定为 true;无效值的默认值不一定与 null 字符串相同。继续使用上例,如果 contenteditable 缺失或无效,则默认为 inherit,并且可以明确设置为 false

默认值取决于属性。与布尔值不同,属性(如果存在)不会自动设为“true”。如果您添加了 <style contenteditable="false">,则该元素将无法修改。如果值无效(例如 <style contenteditable="😀">),或者令人惊讶的是 <style contenteditable="contenteditable">,则值无效,并默认为 inherit

在大多数情况下,对于枚举属性,缺失值和无效值是相同的。例如,如果 <input> 上的 type 属性缺失、存在但没有值,或者具有无效值,则默认为 text。虽然这种行为很常见,但并不是一成不变的规则。因此,请务必了解哪些属性是布尔值,哪些属性是枚举值;尽可能忽略值,以免出错,并根据需要查找值。

全局属性

全局属性是指可在任何 HTML 元素(包括 <head> 中的元素)上设置的属性。30 多个全局属性。虽然这些属性在理论上都可以添加到任何 HTML 元素,但在某些元素上设置某些全局属性不会产生任何效果;例如,在 <meta> 上设置 hidden 后,元内容不会显示。

id

全局属性 id 用于为元素定义唯一标识符。它具有多种用途,包括: - 链接的 fragment 标识符的目标。 - 标识要编写脚本的元素。 - 将表单元素与其标签相关联。 - 为辅助技术提供标签或说明。 - 在 CSS 中使用(高特异性或作为属性选择器)定位样式。

id 值是一个不含空格的字符串。如果它包含空格,文档不会中断,但您必须在 HTML、CSS 和 JS 中使用转义字符来定位 id。所有其他字符均有效。id 值可以是 😀.class,但不建议这样做。为了让您现在和将来的自己更轻松地编程,请将 id 的第一个字符设为字母,并且仅使用 ASCII 字母、数字、_-。最好制定 id 命名惯例,并严格遵循该惯例,因为 id 值区分大小写。

id 应是文档所独有的。如果多次使用 id,网页的布局可能不会破坏,但 JavaScript、链接和元素互动可能无法按预期运行。

导航栏包含四个链接。我们稍后会介绍链接元素,但目前需要了解的是,链接并不仅限于基于 HTTP 的网址;它们可以是指向当前文档(或其他文档)中页面各部分的 fragment 标识符。

在机器学习研讨会网站上,页面标题中的导航栏包含四个链接:

href 属性提供激活链接后将用户定向到的超链接。如果网址包含一个井号 (#) 后跟一串字符,则该字符串是片段标识符。如果该字符串与网页中某个元素的 id 匹配,则该 fragment 是该元素的锚点或书签。浏览器将滚动到定义锚点的位置。

这四个链接指向网页的四个部分,这些部分由 id 属性标识。当用户点击导航栏中的任一链接时,fragment 标识符关联的元素(即包含匹配 ID 减去 # 的元素)会滚动到视野中。

机器学习研讨会的 <main> 内容包含四个带有 ID 的部分。当网站访问者点击 <nav> 中的某个链接时,系统会滚动到包含该 fragment 标识符的版块。标记类似于:

<section id="reg">
  <h2>Machine Learning Workshop Tickets</h2>
</section>

<section id="about">
  <h2>What you'll learn</h2>
</section>

<section id="teachers">
  <h2>Your Instructors</h2>
  <h3>Hal 9000 <span>&amp;</span> EVE</h3>
</section>

<section id="feedback">
  <h2>What it's like to learn good and do other stuff good too</h2>
</section>

比较 <nav> 链接中的 fragment 标识符,您会发现每个 fragment 标识符都与 <main> 中的 <section>id 匹配。浏览器会免费提供“页首”链接。设置 href="#top"(不区分大小写)或 href="#" 会将用户滚动到页面顶部。

href 中的井号分隔符不是片段标识符的一部分。片段标识符始终是网址的最后一部分,不会发送到服务器。

CSS 选择器

在 CSS 中,您可以使用 ID 选择器(例如 #feedback)定位每个版块,也可以使用区分大小写的属性选择器 [id="feedback"]具体性较低)。

设计脚本

MLW.com 上有一个仅面向鼠标用户的彩蛋。点击开关即可开启或关闭页面。

开关图片的标记如下所示:html <img src="svg/switch2.svg" id="switch" alt="light switch" class="light" />id 属性可用作 getElementById() 方法的参数,如果加上 # 前缀,则可用作 querySelector()querySelectorAll() 方法的参数的一部分。

const switchViaID = document.getElementById("switch");
const switchViaSelector = document.querySelector("#switch");

我们的一个 JavaScript 函数利用此功能按 id 属性定位元素:

<script>
  /* switch is a reserved word in js, so we us onoff instead */
  const onoff = document.getElementById('switch');
  onoff.addEventListener('click', function(){
    document.body.classList.toggle('black');
  });
</script>

<label>

HTML <label> 元素具有 for 属性,其值为与其关联的表单控件的 id。通过在每个表单控件上添加 id 并将每个控件与标签的 for 属性配对,以创建显式标签,可确保每个表单控件都有关联的标签。

虽然每个标签只能与一个表单控件相关联,但一个表单控件可以有多个关联的标签。

如果表单控件嵌套在 <label> 起始标记和结束标记之间,则不需要 forid 属性:这称为“隐式”标签。标签可让所有用户了解每个表单控件的用途。

<label>
  Send me a reminder <input type="number" name="min"> before the workshop resumes
</label>.

forid 之间的关联可让辅助技术用户获取相关信息。此外,点击标签上的任意位置都会将焦点移至关联的元素,从而扩大控件的点击区域。这不仅对手部灵活度不佳、导致鼠标操作不准确的用户有帮助,也对手指宽度大于单选按钮的每位移动设备用户都有帮助。

在此代码示例中,虚构测验的虚构第五题是单选题。每个表单控件都有一个显式标签,每个控件都有一个唯一的 id。为确保不会意外重复 ID,ID 值是题目编号和值的组合。

添加单选按钮时,由于标签用于描述单选按钮的值,因此我们会将所有同名按钮包含在 <fieldset> 中,其中 <legend> 是整个集合的标签或问题。

其他无障碍用途

在无障碍功能和易用性方面,id 的使用不限于标签。在文本简介中,我们通过将 <h2>id 作为 <section>aria-labelledby 的值来引用,将 <section> 转换为区域地标,以提供可访问的名称:

<section id="about" aria-labelledby="about_heading">
<h2 id="about_heading">What you'll learn</h2>

有超过 50 个 aria-* 状态和属性可用于确保无障碍功能。aria-labelledbyaria-describedbyaria-detailsaria-owns 的值为以空格分隔的 id 引用列表。aria-activedescendant 用于标识当前聚焦的子元素,其值为单个 id 引用:即具有焦点的单个元素的引用(一次只能有一个元素获得焦点)。

class

class 属性提供了一种使用 CSS(和 JavaScript)定位元素的额外方法,但在 HTML 中没有任何其他用途(尽管框架和组件库可能会使用它们)。class 属性的值为元素的区分大小写的类的以空格分隔的列表。

构建合理的语义结构有助于根据元素的位置和功能对其进行定位。合理的结构有助于使用子元素选择器、关系选择器和属性选择器。在本部分学习属性时,请考虑如何为具有相同属性或属性值的元素设置样式。这并不是说您不应使用类属性,而是大多数开发者都没有意识到自己通常不需要使用类属性。

到目前为止,MLW 尚未使用任何类。网站是否可以不使用单个类名称发布?我们拭目以待。

style

style 属性可用于应用内嵌样式,即应用于设置了该属性的单个元素的样式。style 属性的值为 CSS 属性值对,值的语法与 CSS 样式块的内容相同:属性后跟英文冒号,就像在 CSS 中一样,每个声明以英文分号结尾,分号位于值之后。

样式仅应用于设置了该属性的元素,如果子孙没有被嵌套元素或 <style> 块或样式表中的其他样式声明替换,则会继承继承的属性值。由于该值仅包含等同于应用于该元素的单个样式块的内容,因此无法用于生成内容、创建关键帧动画或应用任何其他 at-rule。

虽然 style 确实是一个全局属性,但不建议使用它。而是应在单独的文件中定义样式。不过,style 属性在开发过程中非常有用,可用于快速设置样式(例如出于测试目的)。然后,将“解决方案”样式粘贴到关联的 CSS 文件中。

tabindex

您可以将 tabindex 属性添加到任何元素,以便该元素能够获得焦点。tabindex 值定义了它是否会添加到标签页顺序中,以及是否会添加到非默认标签页顺序中(可选)。

tabindex 属性的值为整数。负值(惯例是使用 -1)会使元素能够接收焦点(例如通过 JavaScript),但不会将该元素添加到按 Tab 键顺序中。tabindex 值为 0 会使元素可聚焦且可通过按 Tab 键访问,并将其按源代码顺序添加到网页的默认标签页顺序中。值为 1 或更大时,系统会将元素放入优先焦点序列,不建议这样做。

此页面上有一个共享功能,使用 <share-action> 自定义元素充当 <button>。添加值为零的 tabindex 是为了将自定义元素添加到键盘的默认 Tab 键顺序中:

<share-action authors="@estellevw" data-action="click" data-category="web.dev" data-icon="share" data-label="share, twitter" role="button" tabindex="0">
  <svg aria-label="share" role="img" xmlns="http://www.w3.org/2000/svg">
    <use href="#shareIcon" />
  </svg>
  <span>Share</span>
</share-action>

buttonrole 会告知屏幕阅读器用户,此元素应像按钮一样运行。JavaScript 用于确保按钮功能承诺得到遵守;包括处理 clickkeydown 事件,以及处理 Enter 和空格键按下操作。

表单控件、链接、按钮和可修改内容元素能够接收焦点;当键盘用户按下 Tab 键时,焦点会移至下一个可聚焦元素,就像设置了 tabindex="0" 一样。其他元素默认不可聚焦。向这些元素添加 tabindex 属性可让它们在原本无法接收焦点时接收焦点。

如果文档包含 tabindex1 或更大的元素,则这些元素会包含在单独的标签页序列中。您会在 CodePen 中注意到,按 Tab 键时,会先按从低到高的顺序(即值从小到大)在单独的序列中移动,然后再按源代码顺序在常规序列中移动。

更改 Tab 键顺序可能会导致用户体验非常糟糕。这会导致用户难以依靠辅助技术(键盘和屏幕阅读器)浏览您的内容。对开发者而言,管理和维护这些代码也非常困难。焦点很重要;我们有一个单元专门介绍焦点和焦点顺序。

role

role 属性属于 ARIA 规范,而不是 WHATWG HTML 规范role 属性可用于为内容提供语义含义,让屏幕阅读器能够告知网站用户对象的预期用户互动。

有些常见的界面 widget(例如组合框菜单栏标签页列表树状网格)没有原生 HTML 等效项。例如,在创建标签页式设计模式时,可以使用 tabtablisttabpanel 角色。能够实际看到界面的用户通过经验学会了如何浏览 widget,以及如何通过点击关联的标签页来显示不同的面板。当一组按钮用于显示不同的面板时,将 tab 角色添加到 <button role="tab"> 中,可让屏幕阅读器用户知道当前具有焦点的 <button> 可以切换相关面板以供查看,而不是实现典型的按钮功能。

role 属性不会更改浏览器行为或改变键盘或指针设备互动 - 向 <span> 添加 role="button" 不会将其转换为 <button>。因此,建议您将语义 HTML 元素用于其预期用途。不过,如果无法使用正确的元素,则可以使用 role 属性,在非语义元素被改造成语义元素的角色时告知屏幕阅读器用户。

contenteditable

如果将 contenteditable 属性设置为 true,则相应元素可编辑、可聚焦,并且会添加到标签页顺序中,就像设置了 tabindex="0" 一样。Contenteditable 是一个枚举属性,支持值 truefalse,如果该属性不存在或具有无效值,则默认值为 inherit

以下三个开头标记是等效的:

<style contenteditable>
<style contenteditable="">
<style contenteditable="true">

如果您添加 <style contenteditable="false">,则该元素将不可修改(除非它默认可修改,例如 <textarea>)。如果值无效(例如 <style contenteditable="😀"><style contenteditable="contenteditable">),则值默认为 inherit

如需在状态之间切换,请查询 HTMLElement.isContentEditable 只读属性的值。

const editor = document.getElementById("myElement");
if(editor.contentEditable) {
  editor.setAttribute("contenteditable", "false");
} else {
  editor.setAttribute("contenteditable", "");
}

或者,您也可以通过将 editor.contentEditable 设置为 truefalseinherit 来指定此属性。

全局属性可应用于所有元素,包括 <style> 元素。您可以使用属性和一些 CSS 代码来制作实时 CSS 编辑器。

<style contenteditable>
style {
  color: inherit;
  display:block;
  border: 1px solid;
  font: inherit;
  font-family: monospace;
  padding:1em;
  border-radius: 1em;
  white-space: pre;
}
</style>

请尝试将 stylecolor 更改为除 inherit 之外的其他值。然后,尝试将 style 更改为 p 选择器。请勿移除 display 属性,否则样式块将消失。

自定义属性

我们仅介绍了 HTML 全局属性的皮毛。还有更多属性仅适用于一个或一组有限的元素。即使定义了数百个属性,您可能仍需要使用规格中未涵盖的属性。HTML 可以满足您的需求。

您可以通过添加 data- 前缀来创建任何自定义属性。您可以使用以 data- 开头且后跟不以 xml 开头且不包含冒号 (:) 的任何小写字符串来命名属性。

虽然 HTML 具有容错性,如果您创建的属性不受支持且不以 data 开头,或者您自定义属性以 xml 开头或包含 :,系统也不会中断,但创建以 data- 开头的有效自定义属性会带来一些好处。使用自定义数据属性,您可以确保自己不会意外使用现有属性名称。自定义数据属性具有前瞻性。

虽然浏览器不会为任何特定的 data- 前缀属性实现默认行为,但有一个内置的数据集 API 可用于迭代自定义属性。自定义属性是通过 JavaScript 传达特定于应用的信息的绝佳方式。以 data-name 的形式向元素添加自定义属性,并使用 DOM 对相关元素使用 dataset[name] 访问这些属性。

<blockquote data-machine-learning="workshop"
  data-first-name="Blendan" data-last-name="Smooth"
  data-formerly="Margarita Maker" data-aspiring="Load Balancer"
  data-year-graduated="2022">
  HAL and EVE could teach a fan to blow hot air.
</blockquote>

您可以使用完整的属性名称使用 getAttribute(),也可以使用更简单的 dataset 属性。

el.dataset["machineLearning"]; // workshop
e.dataset.machineLearning; // workshop

dataset 属性会返回每个元素的 data- 属性的 DOMStringMap 对象。<blockquote> 上有多个自定义属性。借助数据集属性,您无需知道这些自定义属性的名称和值,即可访问它们:

for (let key in el.dataset) {
  customObject[key] = el.dataset[key];
}

本文中的属性是全局属性,这意味着它们可以应用于任何 HTML 元素(但并非所有属性都会对这些元素产生影响)。接下来,我们将深入探讨链接,并介绍介绍图片中未提及的两个属性(targethref)以及其他一些特定于元素的属性。

检查您的理解情况

测试您对属性的了解程度。

id 在文档中应是唯一的。

错误
请重试。
正确
正确!

选择格式正确的自定义属性。

data-birthday
正确
birthday
请重试。
data:birthday
重试