学习 CSS Nesting 原生嵌套语法 🥳

CSS 预处理器

概述/简介

CSS Houdini 提案之前,CSS 本身不属于可编程语言。当前端项目逐渐庞大之后,CSS 的维护也越来越困难,这时我们就需要 CSS 预处理器通过 工程化 的手段让 CSS 更易维护,提升开发效率。CSS 预处理器本质上是通过 变量嵌套语法逻辑函数 等为 CSS 增加一些可编程的特性。

目前主流的 CSS 预处理器主要有

  • Sass
  • Less
  • Stylus
  • PostCSS

调研/统计

据统计过使用 CSS 预处理器首要原因:

  • 嵌套语法: 35%
  • 变量: 35%
  • 函数: 25%
  • 其他: 5%
pie title "嵌套语法" : 35 "变量" : 35 "函数" : 25 "其他" : 5

如果不使用 CSS 预处理器,如何精简 CSS 样式定义?

  • :is()
  • :where()
css 复制代码
  /* Normal 样式 */
  #card img
  #footer img {
    /* 优先级权重 = (1,0,1) */
  }


  /* 使用 :is() 样式 */
  :is(#card, #footer) img {
    /* 优先级权重 = (1,0,1) */
  }


  /* 使用 :where() 样式 */
  :where(#card, #footer) img {
    /* 优先级权重 = (0,0,1) */
  }

注意 :is():where() 的 CSS 优先级权重!

CSS 原生嵌套语法

就如上个小节所述,嵌套语法是使用 Sass/Less 等 CSS 预处理器的核心原因之一。但在小型项目(HTML + CSS + JS)开发中,使用 CSS 预处理器却有些不便且过于厚重,虽然可以通过 :is():where() 进行简化,但始终无法做到嵌套语法开发时体验和效率。不过现在有了 CSS 原生嵌套语法的支持,一切都迎刃而解。

兼容性

目前主流浏览器都已支持 CSS Nesting 这个特性。查看最新

注意: 该规范的早期版本不允许在没有 &@:.>~+#[* 等选择器的情况下嵌套类型选择器。新版已更新,不再需要嵌套选择器。但是支持度如下:

  • 目前 Firefox 支持新版本的规范
  • 目前 Chrome 和 Safari 支持旧版本的规范,必须使用嵌套选择器进行类型选择器嵌套,具体后面会进行讲解

基本概念

CSS 嵌套语法

定义了嵌套选择器的语法,提供了将一个样式规则嵌套在另一个样式规则中的功能,子规则的选择器相对于父规则的选择器。

css 复制代码
  /* 使用嵌套语法,但不使用嵌套选择器,根据兼容性情况,目前只有 Firefox 支持 */
  parent {
    /* parent styles */
    
    child {
      /* child of parent styles */
    }
  }


  /* 使用嵌套语法,且使用嵌套选择器,主流浏览器都支持 */
  parent {
    /* parent styles */
    
    & child {
      /* child of parent styles */
    }
  }
  

与预处理器区别

  • CSS 嵌套语法是由浏览器解析识别
  • CSS 预处理器是前端项目在构建期间进行预编译成css

嵌套规则

  • CSS选择器
  • @media
  • @layer
  • @scope (暂不提供范例)
  • @supports (暂不提供范例)
  • @container (暂不提供范例)

范例 - CSS选择器

css 复制代码
  /* 例 1 */
  h2 {
    & p {
      /* h2 p 样式 */
    }
  }
  
  /* 例 2 */
  h2 {
    &.p {
      /* h2.p 样式 */
    }
  }
  
  /* 例 3 */
  .card { 
    & h2 {
      .featured & {
        /* .featured .card h2 */
      }
    }
  }
  

范例 - media

css 复制代码
  /* 使用嵌套语法 */
  .foo {
    display: grid;
    
    @media (orientation: landscape) {
      grid-auto-flow: column;
      
      @media (min-width > 1024px) {
        max-inline-size: 1024px;
      }
    }
  }
  
  
  /* 等效于下面的语法 */
  
  
  .foo {
    display: grid;
  }
  
  @media (orientation: landscape) {
    .foo {
      grid-auto-flow: column;
    }
  }
  
  @media (orientation: landscape) and (min-width > 1024px) {
    .foo {
      max-inline-size: 1024px;
    }
  }
  

范例 - layer

css 复制代码
  .foo {
    @layer base {
      block-size: 100%;
      
      @layer support {
        & .bar {
          min-block-size: 100%;
        }
      }
    }
  }
  
  
  /* 等效于下面的语法 */
  


  @layer base {
    .foo {
      block-size: 100%;
    }
  }
  
  @layer base.support {
    .foo .bar {
      min-block-size: 100%;
    }
  }

特异性权重

嵌套选择器的特异性是使用关联选择器列表中的最大特异性计算的。这与使用 :is() 函数时计算特异性的方式相同。

html 复制代码
  <!DOCTYPE html>
  <html lang="en">
    <head>
      <style type="text/css">
        #a,b {
          & c {
            /* 优先级权重 = (1,0,1) */
          }
        }

        .foo c {
          /* 优先级权重 = (0,1,1) */
        }
  
        /* 等效于下面的语法 */
  
        :is(#a, b) {
          & c {
            /* 优先级权重 = (1,0,1) */
          }
        }

        .foo c {
          /* 优先级权重 = (0,1,1) */
        }
      </style>
    </head>
    
    <body>
      <b class="foo">
        <c>Blue text</c>
      </b>
    </body>
  </html>

CSS 预处理器的优势还在吗?

  • CSS Nesting 原生嵌套语法,主流浏览器均已支持
  • CSS 自定义属性/变量,主流浏览器均已支持,详情
  • CSS Houdini 公开了 CSS 引擎的各个部分,允许通过JS编程,相比 CSS-In-JS 更加出色,不过目前兼容性有待提高
  • CSS 原生函数众多(如 clamp()color-mix()color-contrast() 等)。虽然离 CSS 预处理器有段距离,但是越来越稳健。

也许不久的将来,我们可以完全不再依赖 CSS 预处理器,做到更好开发体验和效率。

相关推荐
花花鱼几秒前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09334 分钟前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
EricWang135825 分钟前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
September_ning26 分钟前
React.lazy() 懒加载
前端·react.js·前端框架
web行路人35 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
超雄代码狂1 小时前
ajax关于axios库的运用小案例
前端·javascript·ajax
长弓三石1 小时前
鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
前端·网络·华为·harmonyos·鸿蒙
小马哥编程1 小时前
【前端基础】CSS基础
前端·css
嚣张农民1 小时前
推荐3个实用的760°全景框架
前端·vue.js·程序员
周亚鑫2 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf