HTML 数据属性指南

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 免费信用额度!

介绍

HTML 元素可以具有用于各种目的的属性,从辅助功能信息到样式控制。

<!-- We can use the `class` for styling in CSS, and we've also make this into a landmark region -->
<div class="names" role="region" aria-label="Names"></div>

不鼓励的是自己发明属性,或将现有属性用于无关的功能。

<!-- `highlight` is not an HTML attribute -->
<div highlight="true"></div>
<!-- `large` is not a valid value of `width` -->
<div width="large">

这样做有很多不好的理由。 您的 HTML 将变得无效,这可能不会造成任何实际的负面影响,但会剥夺您拥有有效 HTML 的温暖模糊的感觉。 最有说服力的理由是 HTML 是一种不断发展的语言,即使今天没有作用的属性和值并不意味着它们将来永远不会有作用。

不过,好消息是:您可以自己发明属性。 您只需要在它们前面加上 data-* 前缀,然后就可以随心所欲地使用它们了!

语法

能够自己发明 HTML 属性并将自己的信息放入其中非常方便。 幸运的是,您可以做到! 这正是数据属性的作用。 它们是这样的

<!-- They don't need a value -->
<div data-foo></div>
<!-- ...but they can have a value -->
<div data-size="large"></div>
<!-- You're in HTML here, so careful to escape code if you need to do something like put more HTML inside -->
<li data-prefix="Careful with HTML in here."><li>
<!-- You can keep dashing if you like -->
<aside data-some-long-attribute-name><aside>

数据属性通常被称为 data-* 属性,因为它们总是以这种格式出现。 data 这个词,然后是一个连字符 -,然后是您可以自己定义的其他文本。

您可以单独使用 data 属性吗?

<div data=""></div>

这可能不会造成任何伤害,但您将无法使用我们将在本指南后面介绍的 JavaScript API。 您实际上是在为自己定义一个属性,正如我在介绍中提到的,这样做是不鼓励的。

数据属性的当用法

存储应该可访问的内容。 如果内容应该在页面上显示或读取,不要只将它们放入数据属性中,还要确保这些内容在 HTML 内容中也存在。

<!-- This isn't accessible content -->
<div data-name="Chris Coyier"></div>
<!-- If you need programmatic access to it but shouldn't be seen, there are other ways... -->
<div>
  <span class="visually-hidden">Chris Coyier</span>
</div>

以下内容更多地介绍了如何隐藏事物。

使用数据属性进行样式设置

CSS 可以根据属性及其值选择 HTML 元素。

/* Select any element with this data attribute and value */
[data-size="large"] {
  padding: 2rem;
  font-size: 125%;
}
/* You can scope it to an element or class or anything else */
button[data-type="download"] { }
.card[data-pad="extra"] { }

这很有吸引力。 HTML/CSS 中的主要样式挂钩是类,虽然类很棒(它们具有中等特异性,并且通过 classList 提供不错的 JavaScript 方法),但元素要么存在要么不存在(本质上是)。 使用 data-* 属性,您获得了开/关功能以及在同一特异性级别上根据属性值进行选择的能力。

/* Selects if the attribute is present at all */
[data-size] { }
/* Selects if the attribute has a particular value */
[data-state="open"],
[aria-expanded="true"] { }
/* "Starts with" selector, meaning this would match "3" or anything starting with 3, like "3.14" */
[data-version^="3"] { }
/* "Contains" meaning if the value has the string anywhere inside it */
[data-company*="google"] { }

属性选择器的特异性

它与类完全相同。 我们通常将特异性视为一个四部分值

内联样式、ID、类/属性、标签

因此,单个属性选择器本身的特异性为 0, 0, 1, 0。 类似于这样的选择器

div.card[data-foo="bar"] { }

…的特异性为 0, 0, 2, 1。 2 是因为有一个类(.card)和一个属性([data-foo="bar"]),1 是因为有一个标签(div)。

Illustration of a CSS selector including a data attribute.

属性选择器的特异性低于 ID,高于元素/标签,与类相同。

不区分大小写的属性值

如果您需要校正数据属性中可能存在的大小写不一致,属性选择器为此提供了一个不区分大小写的变体。

/* Will match
<div data-state="open"></div>
<div data-state="Open"></div>
<div data-state="OPEN"></div>
<div data-state="oPeN"></div>
*/
[data-state="open" i] { }

它是在方括号选择器中的小 i

在视觉上使用数据属性

CSS 允许您提取数据属性值,并在需要时显示它。

/* <div data-emoji="✅"> */
[data-emoji]::before {
  content: attr(data-emoji); /* Returns '✅' */
  margin-right: 5px;
}

样式设置示例用例

您可以使用数据属性来指定网格容器要包含多少列。

<div data-columns="2"></div>
<div data-columns="3"></div>
<div data-columns="4"></div>

在 JavaScript 中访问数据属性

与任何其他属性一样,您可以使用通用方法 getAttribute 访问其值。

let value = el.getAttribute("data-state");
// You can set the value as well.
// Returns data-state="collapsed"
el.setAttribute("data-state", "collapsed");

但数据属性也有自己的特殊 API。 假设您有一个具有多个数据属性的元素(这完全没问题)

<span 
  data-info="123" 
  data-index="2" 
  data-prefix="Dr. "
  data-emoji-icon="🏌️‍♀️"
></span>

如果您对该元素有引用,您可以像这样设置和获取属性

// Get
span.dataset.info; // 123
span.dataset.index; // 2
// Set
span.dataset.prefix = "Mr. ";
span.dataset.emojiIcon = "🎪";

请注意最后一行中的 camelCase 用法。 它会自动将 HTML 中的 kebab 样式属性(例如 data-this-little-piggy)转换为 JavaScript 中的 camelCase 样式(例如 dataThisLittlePiggy)。

从某种意义上说,这个 API 不如 classList 那样好用,后者具有清晰的 addremovetogglereplace 方法,但它也比没有好。

您还可以访问内联数据集

<img src="spaceship.png"
  data-ship-id="324" data-shields="72%"
  onclick="pewpew(this.dataset.shipId)">
</img>

数据属性中的 JSON 数据

<ul>
  <li data-person='
    {
      "name": "Chris Coyier",
      "job": "Web Person"
    }
  '></li>
</ul>

为什么不呢? 它只是一个字符串,并且可以将其格式化为有效的 JSON(注意引号等)。 您可以提取这些数据,并根据需要对其进行解析。

const el = document.querySelector("li");
let json = el.dataset.person;
let data = JSON.parse(json);
console.log(data.name); // Chris Coyier
console.log(data.job); // Web Person

JavaScript 用例

其概念是您可以使用数据属性将 JavaScript 可能需要访问的信息放入 HTML 中,以执行某些操作。

一个常见的用例与数据库功能有关。 假设您有一个“点赞”按钮

<button data-id="435432343">♡</button>

该按钮可以在其上设置一个单击处理程序,该处理程序执行一个 Ajax 请求到服务器,以在单击时递增数据库中的点赞次数。 它知道要更新哪个记录,因为它从数据属性中获取了该信息。

规格

浏览器支持

此浏览器支持数据来自 Caniuse,其中包含更多详细信息。数字表示浏览器从该版本开始支持该功能。

桌面

ChromeFirefoxIEEdgeSafari
7611125.1

移动/平板电脑

Android ChromeAndroid FirefoxAndroidiOS Safari
12712735.0-5.1