在实现基于类的 原子样式 时,我们面临的挑战之一是它通常依赖于特定的断点来提供上下文。
<div class="span-12"></div> <!-- we want this for small screens -->
<div class="span-6"></div> <!-- we want this for medium screens -->
<div class="span-4"></div> <!-- we want this for large screens -->
通常使用前缀来定位每个断点
<div class="sm-span-12 md-span-6 lg-span-4"></div>
这在开始添加多个类之前效果很好。但当我们开始添加多个类时,就会难以跟踪哪些内容与哪些内容相关,以及在哪里添加、删除或更改内容。
<div class="
sm-span-12
md-span-6
lg-span-4
sm-font-size-xl
md-font-size-xl
lg-font-size-xl
md-font-weight-500
lg-font-weight-700">
</div>
我们可以尝试通过重新分组使其更具可读性
<div class="
sm-span-12
sm-font-size-xl
md-span-6
md-font-size-xl
md-font-weight-500
lg-span-4
lg-font-size-xl
lg-font-weight-700">
</div>
我们可以添加奇特的分割符(无效的类名将被忽略)
<div class="
[
sm-span-12
sm-font-size-xl
],[
md-span-6
md-font-size-xl
md-font-weight-500
],[
lg-span-4
lg-font-size-xl
lg-font-weight-700
]">
</div>
但这仍然感觉很混乱且难以理解,至少对我来说是这样。
我们可以通过对属性选择器进行分组而不是实际的类来获得更好的概览并避免实现前缀
<div
data-sm="span-12 font-size-lg"
data-md="span-6 font-size-xl font-weight-500"
data-lg="span-4 font-size-xl font-weight-700"
>
</div>
这些不是类丢失,而是我们可以使用[attribute~="value"]
选择的一系列属性(以空格分隔),其中~=
要求在属性值中找到完全匹配的单词才能匹配。
@media (min-width: 0) {
[data-sm~="span-1"] { /*...*/ }
[data-sm~="span-2"] { /*...*/ }
/* etc. */
}
@media (min-width: 30rem) {
[data-md~="span-1"] { /*...*/ }
[data-md~="span-2"] { /*...*/ }
/* etc. */
}
@media (min-width: 60rem) {
[data-lg~="span-1"] { /*...*/ }
[data-lg~="span-2"] { /*...*/ }
/* etc. */
}
它可能看起来有点奇怪,但我认为将原子类转换为属性非常简单(例如,.sm-span-1
变为[data-sm~="span-1"]
)。此外,属性选择器的特异性与类相同,因此我们不会在那里损失任何东西。而且,与类不同,属性可以在不转义特殊字符的情况下编写,例如/+.:?
。
就这样!再次声明,这仅仅是一个旨在使在媒体查询中切换声明更容易编写、阅读和管理的想法。这绝对不是要废除类或任何类似内容的提议。
是的,它可能更容易阅读,但它不是有效的 HTML。对于像 CSS Tricks 这样拥有大量读者和巨大影响力的网站,此类内容应该附带某种警告或免责声明,以便受众在不知情的情况下不会实施它。
嗯,是的,这些应该是
data-*
属性。抱歉,会修复。你为什么认为它不是有效的 HTML?
规范说数据属性甚至在 XML 中都是有效的
https://www.w3.org/TR/2011/WD-html5-20110525/elements.html#attr-data
虽然我认为 HTML 是有效的,但我不知道是否明智地这样使用它。使用查找属性选择器而不是特定类是否有任何性能方面的不利影响?
此外,我发现属性选择器 CSS 比普通的旧类读起来不那么令人愉快。也许这仅仅是习惯了那些类。
@J.T.: 当文章首次发布时,它们不是
data
属性——Chris 在我的评论后非常迅速地添加了这些属性,所以向他致敬 :)如果 HTML 属性(如
myAttribute="value"
)不在 WC3 规范中,则浏览器会忽略它们,但它们将作为 CSS 选择器工作。添加data-
前缀可确保在将来引入myAttribute
作为官方属性时不会发生冲突。我希望这有助于将注意力重新集中到文章的意图上 :)
~ Jakob
太棒了,我喜欢它!
今天很棒的想法,我也将在我的项目中使用它。
这确实是在响应式设计中应用动态模板的好方法。感谢分享。
从特异性的角度来看,这绝对可以用基于默认类的网格替换,因为属性选择器等于类选择器。
但考虑到原子样式方法来构建网页会导致类变得过于庞大(在我看来)。
这就是为什么我自己更喜欢 BEM 方法,因为 DOM 中的类不像原子样式中那么多,并且 DOM 更具可读性和语义性。
请注意,~=’span-1′ 也会匹配 span-10、span-11 和 span-12。因此,如果您使用此方法,请注意可能会出现一些重叠,并注意是否有任何奇怪的情况。
嗨,Shea,
只有在使用
*=
时才会出现这种情况。~=
需要完全值匹配(没有空格)。示例
~ Jakob
非常好。很高兴看到其他人也开始使用属性选择器。我最近一直在使用它们进行原型设计,即使没有 data- 前缀。这是一个例子:https://codepen.io/mikemai2awesome/pen/58903b18084725268a30609ff6528cd3
我很好奇,这些类型的选择器是否会造成任何明显的性能损失?我原本以为类名匹配得到了高度优化。