【译】用CSS属性选择器来拼接HTML的DNA

1,703 阅读5分钟

原文链接:www.smashingmagazine.com/2018/10/att…

CSS属性选择器非常神奇,它们可以帮你避免添加数不胜数的类名,从另一方面来指出你代码里的一些问题。但是大家不用慌,虽然属性选择器复杂且强大,但是很易于学习和使用。在这篇文章,我们将讨论它们是如何运行起来的,再教大家一些使用方面的技巧。

一般我们最普遍的使用方法是将HTML属性放进一个方括号中,称之为属性选择器。例如:

[href] {
    color: chartreuse;
}

任何具有href属性且没有更具体的选择器的html元素现在都会变成黄绿色。属性选择器的特性和类选择器一致

但是你可以使用属性选择器做更多的事情。就像你的DNA一样,它们具有嵌入式的逻辑,可帮助您选择各种属性组合和值。 它们不仅可以精确的匹配标签,类或id选择器,而且可以匹配属性中的任何属性甚至字符串值。

属性选择

属性选择器可以独立存在或更具体一点,比如我们需要选择具有title属性的所有div标签。

div[title]

也可以通过下面操作来选择具有title属性的div的子元素:

div [title]

需要明确的是,中间的空格代表着是后台选择器,即选择具有该属性的元素的子元素。我们也可以更精确一点,来选择想要的属性值:

div[title="dna"]

大多数情况下,属性选择器不需要引号,但我会使用它们,因为我相信它可以提供可读性并确保具有良好的兼容性

如果你想从经过空格分割后的列表里选择具有"dna"字符的属性值,比如“my beautiful dna”或“mutating dna is fun!”,可以在等号前添加一个波浪号`~`:

div[title~="dna"]

您可以选择“dontblamemeblamemydna”或“his-stupidity-is-from-upbringing-not-dna”之类的标题,然后使用美元符号`$`来匹配title的结尾:

[title$="dna"]

要匹配属性值的前面,例如“dnamutants”或“dna-splicing-for-all”的标题,就用插入符号`^`。

[title^="dna"]

如果你想完全匹配一个值开头的完整单词,可以使用管道符来做。比如你不想选择一个“genealogy”的title,但仍然想选择“gene”和“gene-data”:

[title|="gene"]

还有一个匹配任何子字符串的模糊搜索属性运算符`*`:

[title*="dna"]

最后要知道的是,您可以添加一个标志,让属性搜索不区分大小写。 在结束方括号之前添加`i`:

[title*="DNA" i]

使这些属性选择器更加强大的原因是它们是可堆叠的 —— 允许您选择具有多个匹配因子的元素。

比如你需要找到a标签,它有一个title属性,并且有一个以“genes”结尾的class类,该如何写呢?

a[title][class$="genes"]

我们不仅可以选择HTML元素的属性,还可以使用伪“科学”(即伪元素和内容声明)来打印出文本:

<span class="joke" title="Gene Editing!">What’s the first thing a biotech journalist does after finishing the first draft of an article?</span>
.joke:hover:after {
   content: "Answer:" attr(title);
   display: block;
}

上面的代码在鼠标悬停时将显示一串自定义的字符串。

现在我们已经看到了如何使用属性选择器进行选择,让我们看看一些用例。我把它们分为两类:一般使用技巧诊断

一般使用技巧

输入类型的设置

您可以不同地设置输入类型,例如电子邮件与电话:

input[type="email"] {
   color: papayawhip;
}
input[type="tel"] {
   color: thistle;
}

显示手机号码链接

您可以隐藏特定尺寸的电话号码并显示电话链接,以便在电话上轻松拨打电话:

span.phone {
   display: none;
}
a[href^="tel"] {
   display: block;
}

内部链接vs外部链接,安全链接vs非安全链接

您可以区别对待内部和外部链接,并将安全链接设置为与不安全链接不同:

a[href^="http"]{
   color: bisque;
}
a:not([href^="http"]) {
  color: darksalmon;
}
 
a[href^="http://"]:after {
   content: url(unlock-icon.svg);
}
a[href^="https://"]:after {
   content: url(lock-icon.svg);
}

下载图标

HTML5给我们的一个属性是“下载”,它告诉浏览器,你猜对了,下载该文件而不是试图打开它。这对于您希望人们访问但不希望它们立即打开的PDF和DOC非常有用。它还使得连续下载大量文件的工作流程更加容易。下载属性的缺点是没有默认的视觉效果将其与更传统的链接区分开来。通常这是你想要的,但如果不是,你可以做类似下面的事情:

a[download]:after { 
   content: url(download-arrow.svg);
}

您还可以使用不同的图标(如PDF与DOCX与ODF等)来传达文件类型:

a[href$="pdf"]:after {
   content: url(pdf-icon.svg);
}
a[href$="docx"]:after {
   content: url(docx-icon.svg);
}
a[href$="odf"]:after {
   content: url(open-office-icon.svg);
}

您还可以通过堆叠属性选择器确保这些图标仅在可下载链接上:

a[download][href$="pdf"]:after {
   content: url(pdf-icon.svg);
}

覆盖或重新使用已废弃/弃用的代码

我们都遇到了过时代码的旧网站,在HTML5之前,您可能需要覆盖甚至重新应用作为属性实现的样式:

<div bgcolor="#000000" color="#FFFFFF">Old, holey genes</div>
 
div[bgcolor="#000000"] { /*override*/
   background-color: #222222 !important;
}
div[color="#FFFFFF"] { /*reapply*/
   color: #FFFFFF;
}

显示文件类型

默认情况下,文件类型输入标签的可接受文件列表是不可见的。通常,我们使用伪元素来公开它们,虽然你不能在大多数输入标签上(或者在Firefox或Edge中)使用伪元素,但是你可以在文件输入上使用它们:

<input type="file" accept="pdf,doc,docx">
 
[accept]:after {
   content: "Acceptable file types: " attr(accept);
}

html手风琴菜单

detailssummary标签是一种只用HTML做扩展/手风琴菜单的方法,details包括了summary标签和手风琴打开时要展示的内容。点击summary会展开details标签并添加open属性,我们可以通过open属性轻松地为打开的details标签设置样式:

<details>
  <summary>List of Genes</summary>
    Roddenberry
    Hackman
    Wilder
    Kelly
    Luen Yang
    Simmons
</details>
details[open] {
   background-color: hotpink;
}

打印链接

a[href]:after {
   content: " (" attr(href) ") ";
}

自定义工具

使用属性选择器创建自定义工具提示既有趣又简单:

[title] {
  position: relative;
  display: block;
}
[title]:hover:after {
  content: attr(title);
  color: hotpink;
  background-color: slateblue;
  display: block;
  padding: .225em .35em;
  position: absolute;
  right: -5px;
  bottom: -5px;
}

诊断

这些选项用于帮助我们在构建过程中或在尝试修复问题时在本地识别问题。将这些内容放在我们的生产网站上会使用户产生错误。

没有controls属性的audio

我不经常使用音频标签,但是当我使用它时,我经常忘记包含controls属性。 结果:没有显示任何内容。如果您在Firefox中工作,如果您隐藏了音频元素,或者语法或其他一些问题阻止它出现(仅适用于Firefox),此代码可以帮助您解决问题:

audio:not([controls]) {
  width: 100px;
  height: 20px;
  background-color: chartreuse;
  display: block;
}

没有alt替代文字

没有alt属性的图片是可访问性的噩梦,只需查看页面就很难找到它们,但如果添加它们,它们就会弹出来(当页面图片加载失败时,alt文字可以更好的解释图片的作用):

img:not([alt]) { /* no alt attribute */ 
  outline: 2em solid chartreuse; 
}
img[alt=""] { /* alt attribute is blank */ 
  outline: 2em solid cadetblue; 
}

异步Javascript文件

web页面可以是内容管理系统和插件,框架和代码的集合,Ted 在度假时写道,确定哪些JavaScript异步加载以及哪些不加载可以帮助您专注于提高页面性能:

script[src]:not([async]) {
  display: block;
  width: 100%;
  height: 1em;
  background-color: red;
}
script:after {
  content: attr(src);
}

Javascript事件

您还可以突出显示具有JavaScript事件属性的元素,我在这里举例OnMouseOver属性,但它适用于任何JavaScript事件属性:

[OnMouseOver] {
   color: burlywood;
}
[OnMouseOver]:after {
   content: "JS: " attr(OnMouseOver);
}