告别预处理器的新时代!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 原生嵌套语法相关的全部内容,如果对您有帮助,那是对我最好的激励!如果您感兴趣的话,点个关注吧!我会持续更新的!

相关推荐
小桥风满袖9 分钟前
Three.js-硬要自学系列4 (阵列立方体和相机适配、常见几何体、高光材质、lil-gui库)
前端·css
Danny_FD22 分钟前
前端中的浮动、定位与布局
前端·css
trust Tomorrow2 小时前
JS案例-基于Proxy的响应式数据
前端·javascript·css·html
小桥风满袖2 小时前
Three.js-硬要自学系列3 (平行光与环境光、动画渲染循环、stats状态查看器)
前端·css
爱上大树的小猪4 小时前
【前端样式】用 aspect-ratio 实现等比容器:视频封面与图片占位的终极解决方案
前端·css·面试
江城开朗的豌豆4 小时前
CSS篇:HTML与XHTML:关键区别与实际应用解析
前端·css·面试
小桥风满袖4 小时前
three.js-硬要自学系列2 (坐标系、光源对物体影响、相机控件运用)
前端·css
路上^_^4 小时前
CSS核心笔记002
css·笔记·html
nothingbutluck4645 小时前
2025.4.15学习日记 CSS、CSS盒子模型
前端·css·学习