CSS 特异性过滤器
Posted
技术标签:
【中文标题】CSS 特异性过滤器【英文标题】:CSS Specificity Filter 【发布时间】:2012-08-04 04:24:38 【问题描述】:这是一个长镜头,但是否有可用的工具通过删除不需要的特异性来优化 CSS 选择器?
我发现当我写 CSS 时,我故意让我的选择器比必要的更具体,以避免冲突和准文档。
如果有一种工具可以分析给定的一组规则,确定它们与其他规则重叠的“唯一性”,然后去除任何不必要的特殊性,那就太好了。
我什至无法想象工具开发人员会如何处理这需要的所有场景,但我之前曾被其他人在该领域的独创性所震撼,并认为值得一问。
更新:
我在这个问题上加了一个赏金,我越想它,我就越意识到 的价值。
例如,在Sass 和LESS 中使用嵌套规则/选择器时,过度嵌套 是common 和well-known 反模式,很容易导致选择器过于具体。
在优秀的 TutsPlus 课程Maintainable CSS with Sass and Compass中有一个很好的说明:
body
div.container
p
a
color: purple;
Sass 将遵循这些嵌套指令并生成以下 CSS 输出,不会对任何不必要的特殊性提出异议:
body div.container p a
color: purple;
但是,如果存在/确实存在特异性过滤器,它将为 CSS 开发人员带来潜在的好处:
您可以将样式表组织为 DOM 的 1:1 映射,类似于您在 Firebug 和 Chrome 开发工具中检查样式规则时看到的内容。智能编辑器/IDE 可以为具有共享样式/类的 DOM 元素自动填充样式。当然,这种冗余会被特异性过滤器/优化器过滤掉。
样式表的结构可以由扫描 DOM 并将其转换为 CSS 选择器/规则的工具预先填充。这意味着开发人员只需要更新 html; CSS“树”将保持同步以反映 DOM 的当前状态。智能编辑器可以让您跳转到元素/类的 CSS 定义以进行样式设置——甚至可以在单独的面板中显示其样式规则。
在某种程度上,这似乎是一种倒退——就像您在 Dreamweaver 或 WebAssist 中发现的帮助新手学习 CSS 的功能一样。但是 CSS 选择器优化工具的基本思想似乎很简单,我所描述的工作流自动化类型将是合乎逻辑的下一步——催化剂将是特异性过滤器。
我研究了一些更知名的 CSS 编辑器和 Web IDE,但除了定位单个元素并为其生成选择器之外,没有发现任何提供此类功能的东西。
更新 2:CSS 选择器性能
针对 Spliff 的评论,这里有两篇关于 CSS 选择器性能的精彩文章:
Performance Impact of CSS Selectors史蒂夫·苏德斯
Efficiently Rendering CSS by Chris Coyier
两者都同意微优化 CSS 不值得努力,但过度限定的后代选择器是“效率灾难”。我自己还没有进行基准测试,但我怀疑我建议的那种“DOM 映射”方法会在没有手动或自动优化步骤的情况下导致性能下降。
相关问题、链接和工具:
Points in CSS Specificity
Tool to See CSS Specificity
Tool for Cleaning Up CSS
Order by CSS Specificity
Top 5 Mistakes of Massive CSS
Google: Efficient CSS Selectors
Procssor
Clean CSS
CSS Tidy
【问题讨论】:
当然,这样的工具需要检查 DOM 或页面以作为样式表的基础并做出正确的观察/假设(例如,是否只有一个带有 @ 的header
元素987654341@? aside
元素是否只会出现在 section.sidebar
?) 中。否则,在不从根本上改变选择器含义的情况下,从选择器中去除特异性的唯一方法是删除重复的简单选择器,(例如,section > div.foo.foo:nth-of-type(odd)
变为 section > div.foo:nth-of-type(odd)
)。
@BoltClock:另外,如果遇到 ID,通常可以安全地消除它之前的任何内容。 html body div p#lorem span
通常可以缩写为 #lorem span
老实说,除了遵循一些简单的规则(不要将元素添加到 id/class 选择器中,不要对嵌套感到疯狂等),我认为这不值得担心关于。这几天browser vendors are optimizing for this。
这就是为什么我一开始不使用预处理器...
@Truth 它也不一定适用于动态生成的 HTML。在这种情况下,实际元素和嵌套可能取决于上下文,并且您可能只想将样式应用于该 ID,如果它在该特定上下文中遇到(它周围的元素)。但问题本身也有同样的问题。具有生成 HTML(无论是服务器端还是客户端)的高度动态页面将难以编写可靠工作的过滤器。
【参考方案1】:
您可以尝试采用不同的方法,尝试将选择器编写得尽可能小(低特异性)。并且仅在需要时使它们更加具体。 使用这种工作方式,您不需要工具。
【讨论】:
Writing efficient CSS selectors 感谢您的回复,但整个想法是避免这种方法——拥有一个允许我们编写 CSS 而无需考虑特殊性的工具。现在的工作方式是,我们必须跨多个规则设置 DOM 元素的样式——优化工具将允许我们在一个地方处理元素的所有样式。在我看来,这是一个更合乎逻辑的工作流程;我们只是对 CSS 不能以这种方式工作的事实感到麻木。 CSS 是一种“基于情境”的语言(取决于 HTML),没有全方位的 CSS 编码,否则每个人都可以做 CSS 样式。特异性是如此重要,如果有人不理解特异性,他/她肯定会写出糟糕的 CSS。我从未有过拥有工具的冲动。一个工具永远不能像你想要的那样输出代码(又名读心软件)。 CSS(面向对象)是你必须掌握的东西,就像任何其他网络语言一样。【参考方案2】:只是把它扔在那里——它不会“回答”你的问题,但它是我喜欢向从事大量 css 编程的人宣传的工具:Firebug。强>
如果您不熟悉它,它是一个用于网络浏览器的工具。安装后拉出页面,右键单击并选择“检查元素”。它将向您展示影响页面上不同元素的所有 css,并且对于创建干净、精确的 css 代码很有用。此外,只需稍作修改,即可更轻松地查看页面外观的即时更新。 它会通知您被其他 css 代码覆盖的无用 css 代码。
还有! Firebug 现在几乎可用于所有浏览器。不仅仅是火狐。就个人而言,我偏爱在 Chrome 中使用它。
【讨论】:
谢谢,我同意 Firefox 是一个很棒的工具。【参考方案3】:我们真的不能没有特异性,因为当您有两个或多个规则发生冲突时,它是唯一可以拯救您的方法。特殊性为整个混乱的 CSS 规则带来了理智,因此它更像是一种祝福而不是诅咒。你谈到的一些东西,比如 CSS 选择器,可以使用 Firefox/Firebug 来完成。我更担心浏览器的兼容性。
【讨论】:
我的想法和我在帖子中提到的完全一样——如果你想确保你写的 CSS 很好,Firebug 很棒。 您是否提前点击了提交?你的最后一句话不完整。【参考方案4】:实际上有一种方法可以使用 HTML5 和 CSS3 来实现。标准技术是使用 HTML 5 属性 "data-" 指定元素,然后为此属性进行 CSS 选择。这不是属性的目的,但您可以自定义指定一些元素,您甚至可以使用这些元素来切换站点的主题。
因此,例如,您最终可以通过指定在 CSS 中手动创建特异性过滤器
<b data-specificity=2>test</b>
其中数据特异性仅与上述父项匹配。
更新:
好的,例如,假设您有一个段落类,但您想指定段落可以从哪个父级或多少个父级继承属性。您将为每个可以继承自的潜在父母使用规则:
p[data-specificity="1"]
color:red;
font-family:verdana;
text-decoration:underline;
p[data-specificity="2"]
color:black;
font-family:arial;
div.container > *[data-specificity="2"]
font-family:impact;
color:blue;
text-decoration:underline;
因此这些规则意味着任何作为 div 容器的直接子级且具有特异性 2 的 p 标签都可以从 div 容器继承属性。 div 的蓝色被具有数据特异性 2 的 p 继承。
这是JSFiddle,您可以在其中看到这个!
这样的想法是,使用 HTML5,您可以准确控制允许哪些元素继承哪些属性。需要编写大量额外代码(针对子元素和父元素),但您可以使用它来消除一些不必要的特殊性
我从来没有真正看到有人在实践中使用过这种方法,我几乎只是为你准备了它,但我认为它可能非常有用,你觉得呢?
【讨论】:
这是一个有趣的方法,感谢您的回复。不幸的是,所需的非语义标记的数量对我来说是一个交易杀手,但这是一个非常有创意的解决方案。 好吧,我不能在接下来的几个小时内给出一个好的答案,但是如果你以某种方式延长赏金日期,我会发布一个非常干净的解决方案和示例代码 ;) 当然,我很高兴重新获得赏金(假设这是允许的)。当我这样做时,我会在此处添加评论,以便它出现在您的收件箱中。 抱歉,更新了我的答案。当我写下答案时,我想到了别的东西。我相应地编辑了答案以上是关于CSS 特异性过滤器的主要内容,如果未能解决你的问题,请参考以下文章