告别预处理器的新时代!CSS 原生嵌套语法来啦!

什么是 CSS 原生嵌套语法?

简单来说,就是允许你在一个 CSS 选择器里面再写其他选择器,就像大盒子嵌套小盒子一样。以前要实现类似效果,得借助像 Sass、Less 这样的 CSS 预处理器才行,从 2023 年开始,CSS 原生嵌套语法开始实验支持,直到现在终于落地并普及啦!

比如说,我们有一个导航栏,导航栏里有一个个的导航项,导航项里还有文字和图标。以前写 CSS 样式的时候,得这样写:

css 复制代码
.nav {
  background-color: #333;
  color: white;
}
.nav .nav-item {
  padding: 10px;
}
.nav .nav-item .nav-link {
  text-decoration: none;
  color: white;
}
.nav .nav-item .nav-link:hover {
  color: yellow;
}

而用了 CSS 原生嵌套语法后,代码就变成了这样:

css 复制代码
.nav {
  background-color: #333;
  color: white;
  .nav-item {
    padding: 10px;
    .nav-link {
      text-decoration: none;
      color: white;
      &:hover {
        color: yellow;
      }
    }
  }
}

这样书写,是不是一下子就清爽了很多?不仅减少了重复代码,而且结构更清晰,一眼就能看出样式之间的层级关系。以后维护代码的时候,也能更快找到对应的样式规则。

原生嵌套 vs 传统 CSS:代码对比

基本嵌套

先看一个简单的列表,用传统 CSS 来写,代码是这样的:

css 复制代码
ul {
  list-style-type: none;
  padding: 0;
}
ul li {
  padding: 5px;
}
ul li a {
  text-decoration: none;
  color: #007BFF;
}

要是用 CSS 原生嵌套语法呢,就变成:

css 复制代码
ul {
  list-style-type: none;
  padding: 0;
  li {
    padding: 5px;
    a {
      text-decoration: none;
      color: #007BFF;
    }
  }
}

可以看到,原生嵌套语法把相关的样式都集中在了一起,一眼就能看出来 li 是 ul 的子元素,a 又是 li 的子元素,代码结构更加清晰。

伪类与伪元素

假设我们有一个按钮,需要设置正常状态和鼠标悬停状态的样式,以及在按钮前面添加一个小图标(伪元素)。传统 CSS 代码如下:

css 复制代码
button {
  background-color: #28A745;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 5px;
}
button:hover {
  background-color: #218838;
}
button::before {
  content: "\2714";
  margin-right: 5px;
}

使用原生嵌套语法后,代码如下:

css 复制代码
button {
  background-color: #28A745;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 5px;
  &:hover {
    background-color: #218838;
  }
  &::before {
    content: "\2714";
    margin-right: 5px;
  }
}

在原生嵌套里,& 符号代表父选择器。通过这种方式,把按钮本身的样式、悬停样式以及伪元素样式都紧密联系在一起,代码更紧凑,也不容易出错。

媒体查询嵌套

比如我们要实现一个响应式布局,在大屏幕上和小屏幕上有不同的样式。用传统 CSS:

css 复制代码
.container {
  width: 80%;
  margin: 0 auto;
}
@media (max-width: 600px) {
  .container {
    width: 95%;
  }
}

用原生嵌套语法:

css 复制代码
.container {
  width: 80%;
  margin: 0 auto;
  @media (max-width: 600px) {
    width: 95%;
  }
}

原生嵌套让媒体查询的样式直接跟在元素原本的样式后面,在一个地方就能看到这个元素在不同屏幕尺寸下的所有样式变化,非常直观,也方便管理。

浏览器兼容性与使用建议

CSS 原生嵌套语法截止到目前为止,主流浏览器如:Chrome、Safari、FireFox 均已经支持,包括移动端。我们已经可以在不使用预处理器的情况下享受到一定的便利!

要是打算使用 CSS 原生嵌套语法,给大家几个小建议:

  • 避免嵌套层级超过 3 层:嵌套层级太深,代码可读性会变差,维护起来也麻烦,生成的 CSS 文件可能会变得不必要的冗长;
  • 使用 & 符号明确父选择器:在使用伪类、伪元素,或者需要明确引用父选择器时,一定要加上 & 符号 ,不然可能会选择错误的元素;
  • 优先使用类选择器,减少标签选择器嵌套:类选择器更灵活,特异性也更好控制。标签选择器嵌套可能会导致样式过于宽泛,不好维护。

注意事项与常见问题

在使用 CSS 原生嵌套语法时,有一些细节需要特别留意,不然可能会遇到一些让人头疼的问题。

选择器优先级

随着嵌套层级的增加,选择器的权重也会悄悄增加。比如下面这段代码:

css 复制代码
body {
  color: black;
}
.container {
  .content {
    color: gray;
    p {
      color: red;
    }
  }
}

这里 p 元素的样式,因为它处于多层嵌套中,选择器权重相对较高,所以它的文字颜色会是红色,而不是 body 或 .content 设置的颜色。要是不小心过度使用 ID 选择器嵌套,权重就会变得很高,之后想要覆盖这些样式就很麻烦。所以,尽量多使用类选择器,减少 ID 选择器的嵌套。

动态伪类

像 :hover、:active、:focus 这些动态伪类,在原生嵌套里必须通过 & 符号关联父元素。比如我们有个按钮,想设置鼠标悬停样式:

css 复制代码
button {
  background-color: #007BFF;
  color: white;
  /* 错误写法,:hover会被误认为是button内部元素的悬停 */
  :hover {
    background-color: #0056b3;
  }
  /* 正确写法,用&明确是button自身的悬停 */
  &:hover {
    background-color: #0056b3;
  }
}

如果不用 &,:hover 就会被当成选择 button 内部元素的悬停状态,而不是 button 本身,这样样式肯定就不对啦。

结语

CSS 原生嵌套语法的落地,让我们可以不用再额外配置预处理器环境,而是直接使用原生 CSS 就能写出结构清晰的嵌套样式,开发效率大大提高。

不过,Sass、Less 这些预处理器可不会这么容易就被淘汰。它们除了嵌套功能,还有很多 CSS 原生不具备的强大功能。因此,一定时期内 CSS 原生嵌套和预处理器会处于一种共存的状态。对于新的项目,如果目标浏览器支持度允许,不妨大胆尝试 CSS 原生嵌套语法,享受它带来的便捷;而对于需要兼容老浏览器,或者对预处理器其他功能依赖较大的项目,继续使用 Sass、Less 也没问题。

以上,就是 CSS 原生嵌套语法相关的全部内容,如果对您有帮助,那是对我最好的激励!如果您感兴趣的话,点个关注吧!我会持续更新的!

相关推荐
iCOD3R14 小时前
Skill - kill-ai-slop 解决“AI 味”样式
前端·css·ai编程
努力成为AK大王1 天前
CSS 入门完整笔记
前端·css
神明不懂浪漫1 天前
【第四章】CSS(二)——文本外观属性与复合选择器
前端·css·经验分享·笔记
H Journey2 天前
web开发学习:html、css、js
前端·css·html·js
用户059540174462 天前
AI Agent 记忆存储踩坑实录:这个问题让我排查了 3 天,最终用 pytest + Docker 实现秒级回归
前端·css
今日无bug2 天前
Emmet 语法速成指南
前端·css·html
Hello.Reader2 天前
Tailwind CSS v4.3 从入门到实战Vite 安装、响应式布局、暗黑模式与主题配置
前端·css
cxxcode3 天前
CSS Loader 与样式处理链路
前端·css
CappuccinoRose3 天前
CSS、Less、Sass(含 SCSS)、Stylus
前端·css·less·sass·stylus
用户059540174464 天前
把前端内存泄漏排查从2小时压到5分钟,我们把它集成进了CI
前端·css