用 CSS 属性选择器拼接 HTML 的 DNA
已发表: 2022-03-10在我职业生涯的大部分时间里,属性选择器比科学更神奇。 我会盯着 CSS 以在打印样式表中输出链接,目瞪口呆,什么也不懂。 我会尽职尽责地复制,并将其粘贴到我的打印样式表中,然后跑出去扔掉任何项目是最大的燃烧垃圾堆。
但是你不必再盯着 CSS 属性选择器了。 在本文结束时,您将使用它们在您的站点上运行诊断程序,修复其他无法解决的问题,并生成如此先进的技术体验,它们就像魔术一样。 你可能认为我的承诺太多了,你是对的,但是一旦你了解了属性选择器的强大功能,你可能会觉得自己在夸大其词。
在最基本的层面上,您将 HTML 属性放在方括号中,并将其称为属性选择器,如下所示:
[href] { color: chartreuse; }
任何具有href
且没有更具体选择器的元素的文本现在都会神奇地变成黄绿色。 属性选择器的特异性与类相同。
注意:有关 CSS 特异性的笼式比赛的更多信息,您可以阅读“CSS 特异性:您应该知道的事情”,或者如果您喜欢星球大战:“CSS 特异性战争”。
但是你可以用属性选择器做更多的事情。 就像您的 DNA 一样,它们具有内置逻辑来帮助您选择各种属性组合和值。 它们不仅可以像标签、类或 id 选择器那样精确匹配,还可以匹配任何属性,甚至是属性中的字符串值。
属性选择
属性选择器可以独立存在或更具体,即如果您需要选择所有具有title
属性的div
标签。
div[title]
但是您也可以通过执行以下操作来选择具有标题的 div 的子级:
div [title]
需要明确的是,它们之间没有空格意味着属性在同一个元素上(就像没有空格的元素和类一样),它们之间的空格意味着后代选择器,即选择具有该属性的元素的子元素。
您可以更精细地选择属性,包括属性值。
div[title="dna"]
上面选择了所有具有“dna”确切标题的 div。 不会选择“dna is awesome”或“dnamutation”的标题,尽管有选择器算法可以处理每种情况(以及更多)。 我们很快就会讲到这些。
注意:在大多数情况下,属性选择器中不需要引号,但我会使用它们,因为我相信它可以提高清晰度并确保边缘情况正常工作。
如果您想从空格分隔的列表中选择“dna”,例如“my beautiful dna”或“mutating dna is fun!” 您可以在等号前面添加一个波浪号或“波浪线”,我喜欢这样称呼它。
div[title~="dna"]
您可以选择诸如“dontblameblamemydna”或“his-stupidity-is-from-upbringing-not-dna”之类的标题,然后您可以使用美元符号 $ 来匹配标题的结尾。
[title$="dna"]
要匹配属性值的前面,例如“dnamutants”或“dna-splicing-for-all”的标题,请使用插入符号。
[title^="dna"]
虽然精确匹配很有帮助,但选择可能太紧,并且插入符号前面的匹配可能太宽而无法满足您的需求。 例如,您可能不想选择“genealogy”的标题,但仍然选择“gene”和“gene-data”。 管道字符(或竖线)就是这样; 它进行完全匹配,但包括完全匹配后跟破折号的情况。
[title|="gene"]
最后,有一个完整的搜索属性运算符可以匹配任何子字符串。
[title*="dna"]
但要明智地使用它,因为上面会匹配“I-like-my-dna-like-my-meat-rare”以及“edna”、“kidnapping”和“echidnas”(这是 Edna 真的不应该做的事情。 )
使这些属性选择器更加强大的是它们是可堆叠的——允许您选择具有多个匹配因子的元素。
但是你需要找到a
有标题并且有一个以“genes”结尾的类的标签吗? 这是如何做:
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; }
上面的代码将显示悬停时写的最糟糕的笑话之一的答案(是的,我自己写的,是的,称它为“笑话”是慷慨的)。
最后要知道的是,您可以添加一个标志来使属性搜索不区分大小写。 在右方括号之前添加一个i
。
[title*="DNA" i]
因此它将匹配“dna”、“DNA”、“dna”和任何其他变体。
唯一的缺点是i
仅适用于 Firefox、Chrome、Safari、Opera 和少数移动浏览器。
现在我们已经了解了如何使用属性选择器进行选择,让我们看一些用例。 我将它们分为两类:一般用途和诊断。
一般用途
按输入类型的样式
您可以设置不同的输入类型,例如电子邮件与电话。
input[type="email"] { color: papayawhip; } input[type="tel"] { color: thistle; }
显示电话链接
您可以隐藏特定大小的电话号码并改为显示电话链接,以便在电话上更轻松地拨打电话。
span.phone { display: none; } a[href^="tel"] { display: block; }
内部链接与外部链接,安全与不安全
您可以区别对待内部和外部链接,并将安全链接的样式与不安全的链接区别开来。
a[href^="http"]{ color: bisque; } a:not([href^="http"]) { color: darksalmon; } a[href^="https://"]:after { content: url(unlock-icon.svg); } a[href^="https://"]:after { content: url(lock-icon.svg); }
下载图标
HTML5 给我们的一个属性是“下载”,它告诉浏览器,你猜对了,下载那个文件而不是试图打开它。 这对于您希望人们访问但不希望他们现在打开的 PDF 和 DOC 很有用。 它还简化了连续下载大量文件的工作流程。 download
属性的缺点是没有默认视觉效果可以将其与更传统的链接区分开来。 通常这是您想要的,但如果不是,您可以执行以下操作。
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; }
覆盖特定的内联样式
有时您会遇到使作品变得混乱的内联样式,但它们来自您无法控制的代码。 应该说,如果您可以更改它们,那将是理想的,但如果您不能,这里有一个解决方法。
注意:如果您知道要覆盖的确切属性和值,并且希望在它出现的任何地方覆盖它,则此方法效果最佳。
对于这个例子,元素的边距以像素为单位设置,但需要扩展并以em
为单位设置,以便在用户更改默认字体大小时元素可以重新正确调整。
<divTeenage Mutant Ninja Myrtle</div> div[style*="margin: 8px"] { margin: 1em !important; }
注意:使用此方法时应格外小心,因为如果您需要覆盖此样式,您将陷入!important
战争并且小猫会死去。
显示文件类型
默认情况下,文件输入的可接受文件列表是不可见的。 通常,我们会使用伪元素来公开它们,尽管您不能在大多数input
标签(或根本在 Firefox 或 Edge 中)上使用伪元素,但您可以在文件输入中使用它们。
<input type="file" accept="pdf,doc,docx"> [accept]:after { content: "Acceptable file types: " attr(accept); }
HTML 手风琴菜单
未广为人知的details
和summary
标签二重奏是一种仅使用 HTML 来制作可扩展/手风琴菜单的方法。 详细信息包含summary
标记和您想要在手风琴打开时显示的内容。 单击摘要会展开detail
标签并添加一个打开属性。 open 属性可以轻松地为打开的details
标签设置与关闭的details
信息标签不同的样式。
<details> <summary>List of Genes</summary> Roddenberry Hackman Wilder Kelly Luen Yang Simmons </details>
details[open] { background-color: hotpink; }
打印链接
以打印样式显示 URL 使我走上了理解属性选择器的道路。 您现在应该知道如何自己构建它。 您只需选择所有带有href
a
标签,添加一个伪元素,然后使用attr()
和content
打印它们。
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; }
访问密钥
网络的一大优点是它为访问信息提供了许多不同的选项。 一个很少使用的属性是设置accesskey
的能力,以便可以通过组合键和accesskey
设置的字母直接访问该项目(确切的组合键取决于浏览器)。 但是没有简单的方法可以知道网站上设置了哪些密钥。
以下代码将在:focus
上显示这些键。 我不使用hover
,因为大多数时候需要访问accesskey
的人是那些使用鼠标有困难的人。 您可以将其添加为第二个选项,但请确保它不是唯一的选项。
a[accesskey]:focus:after { content: " AccessKey: " attr(accesskey); }
诊断
这些选项用于帮助您在构建过程中或在尝试修复问题时在本地识别问题。 将这些放在您的生产站点上会使错误暴露给您的用户。
没有控制的音频
我不经常使用audio
标签,但是当我使用它时,我经常忘记包含controls
属性。 结果:什么都没有显示。 如果您在 Firefox 中工作,则此代码可以帮助您确定是否隐藏了音频元素,或者语法或其他问题阻止它出现(它仅适用于 Firefox)。
audio:not([controls]) { width: 100px; height: 20px; background-color: chartreuse; display: block; }
没有替代文字
没有替代文字的图像是物流和可访问性的噩梦。 仅通过查看页面很难找到它们,但是如果您添加它,它们会立即弹出。
注意:我使用outline
而不是border
,因为边框可能会增加元素的宽度并弄乱布局。 outline
不增加宽度。
img:not([alt]) { /* no alt attribute */ outline: 2em solid chartreuse; } img[alt=""] { /* alt attribute is blank */ outline: 2em solid cadetblue; }
异步 Javascript 文件
网页可以是内容管理系统、插件、框架和代码的集合体,Ted(坐在三个小隔间里)在度假时写的,因为网站宕机了,他害怕你的老板。 弄清楚哪些 JavaScript 异步加载以及哪些不能异步加载可以帮助您专注于提高页面性能的地方。
script[src]:not([async]) { display: block; width: 100%; height: 1em; background-color: red; } script:after { content: attr(src); }
Javascript 事件元素
您还可以突出显示具有 JavaScript 事件属性的元素,以将它们重构到您的 JavaScript 文件中。 我在这里关注的是OnMouseOver
属性,但它适用于任何 JavaScript 事件属性。
[OnMouseOver] { color: burlywood; } [OnMouseOver]:after { content: "JS: " attr(OnMouseOver); }
隐藏物品
如果您需要查看隐藏元素或隐藏输入的位置,您可以通过以下方式显示它们:
[hidden], [type="hidden"] { display: block; }
但是,有了所有这些惊人的功能,您认为一定有一个问题。 当然,属性选择器只能在 Chrome 中标记或在 Safari 边缘的 Fiery Foxes 的夜间版本中工作。 这太好了,令人难以置信。 而且,不幸的是,有一个问题。
如果您想在最受欢迎的浏览器(即 IE6)中使用属性选择器,您将无法做到。 (没关系;让眼泪掉下来。不要评判。)几乎所有其他地方你都可以去。 属性选择器是 CSS 2.1 规范的一部分,因此已经在浏览器中使用了十年的大部分时间。
所以这些选择器对你来说应该不再是神奇的,而是作为一种足够先进的技术来揭示的。 它们比魔法更科学,现在你知道了它们最深的秘密,这取决于你。 走出去,在网络上创造神秘的科学奇迹。