使用属性选择器实现响应式样式

Avatar of Jakob E
Jakob E

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

在实现基于类的 原子样式 时,我们面临的挑战之一是它通常依赖于特定的断点来提供上下文。

<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"])。此外,属性选择器的特异性与类相同,因此我们不会在那里损失任何东西。而且,与类不同,属性可以在不转义特殊字符的情况下编写,例如/+.:?

就这样!再次声明,这仅仅是一个旨在使在媒体查询中切换声明更容易编写、阅读和管理的想法。这绝对不是要废除类或任何类似内容的提议。