第六篇_CSS进阶_深入浏览器与工程化

第六篇 CSS 进阶:深入浏览器与工程化

目标:从"能写页面"升级到"理解浏览器、写得稳、跑得快、好维护"。

看完这一篇,你应该能:

  • 更深入地理解层叠、优先级、层叠上下文与 z-index;
  • 知道哪些 CSS 写法性能更好,哪些可能拖慢渲染;
  • 理解 Sass、PostCSS 等工具处在 CSS 流程的什么位置,以及它们各自解决什么问题。

第15章 层叠与优先级的真相

这一章解决的核心问题:

  • 为什么同一个元素的颜色,在不同地方写,会"互相打架"?
  • !important、选择器特异性(优先级)、来源顺序之间到底谁说了算?
  • 元素层级(谁压在谁上面)和 z-index 的真实规则是什么?

你会发现,"调样式"时的很多迷之现象,其实都是层叠规则在发挥作用。

15.1 层叠(Cascade)与来源

15.1.1 样式从哪里来?

浏览器最终给一个元素计算样式时,要综合来自多方的规则:

  • 用户代理样式(User Agent Style)

    • 浏览器内置的默认样式
    • 例如:h1 默认字号比 p 大,a 标签默认蓝色带下划线
    • 每个浏览器都有自己的默认样式表
  • 用户样式(User Style)

    • 用户在浏览器设置中自定义的样式(现在较少使用)
    • 例如:用户设置最小字号、强制使用某种字体
  • 作者样式(Author Style) ⭐ 最重要

    • 开发者编写的样式
    • 来源:外部CSS文件、<style>标签、style属性
    • 这是我们日常工作的主要部分

大多数情况下,我们主要关心"作者样式"的层叠,但要知道:

  • 默认样式不等于"没有样式",只是你没写而已
15.1.2 当多条规则命中时的决策顺序

对于同一个属性(比如 color),如果有多条规则都命中了同一个元素,浏览器会按大致顺序做决策:

  1. 重要性(Importance) :有 !important 的优先
  2. 来源(Origin):一般作者样式 > 用户样式 > 浏览器默认(视情况而定)
  3. 特异性(Specificity):谁的选择器更"具体"
  4. 顺序(Order):写在后面的覆盖前面的

可以用一条「层叠决策线」来理解:

txt 复制代码
层叠决策顺序(优先级从高到低):

1. !important 声明  →  最高优先级
2. 来源(Origin)   →  作者样式 > 用户样式 > 浏览器默认
3. 特异性(权重)   →  ID > 类 > 标签
4. 书写顺序        →  后写的覆盖先写的

例如:
.text { color: blue; }           /* 权重:10 */
#main .text { color: red; }       /* 权重:110 */
.text { color: green !important; } /* !important 最高 */
最终生效:green(因为有!important)

第 2 章已经讲过特异性基础,这里会更结合实际场景和层叠上下文去看。

15.2 层叠上下文与 z-index 解密

在页面中,元素之间谁在上、谁在下,不完全由 DOM 顺序决定,还受到"层叠上下文(stacking context)"的影响。

15.2.1 什么是层叠上下文?

可以把层叠上下文想象为一个"局部三维空间":在这个空间里,元素可以通过 z-index 控制前后顺序;

不同层叠上下文之间,有自己的"整体层级"。

一个简单的比喻:

  • 整个页面是一个大白板
  • 某个卡片(有 position + z-index)可能自己形成一个小白板
  • 小白板内部的前后关系,不会影响到其它小白板内部的前后关系
15.2.2 什么会创建层叠上下文?

常见会创建层叠上下文的情况:

css 复制代码
/* 1. 根元素 */
html { }                            /* 页面根层叠上下文 */

/* 2. 定位元素 + z-index */
.modal {
  position: relative;               /* 或absolute/fixed/sticky */
  z-index: 100;                    /* 非auto值创建层叠上下文 */
}

/* 3. 透明度小于1 */
.fade {
  opacity: 0.9;                    /* 创建层叠上下文 */
}

/* 4. transform变换 */
.card {
  transform: translateZ(0);        /* 任何非none值都创建 */
}

/* 5. filter滤镜 */
.blur {
  filter: blur(5px);               /* 创建层叠上下文 */
}

/* 6. mix-blend-mode混合模式 */
.overlay {
  mix-blend-mode: multiply;        /* 创建层叠上下文 */
}

示意:

txt 复制代码
页面根(层叠上下文 A)

┌─────────────────────────────┐
│ div#modal-root  (z-index: 1000)   ← 层叠上下文 B │
│   └─ modal 内部元素                         │
│                                           │
│ div#page          (z-index: auto)  ← 层叠上下文 C │
│   └─ header / main / footer              │
└─────────────────────────────┘

B 整体永远压在 C 之上;
C 内部再决定各自元素的前后顺序。
15.2.3 z-index 的比较只在"同一个层叠上下文"里有效

一个常见坑:

html 复制代码
<div class="parent-a">
  <div class="box-a">A</div>
</div>
<div class="parent-b">
  <div class="box-b">B</div>
</div>
css 复制代码
/* 层叠上下文的常见误区示例 */

/* 父容器A:创建层叠上下文,层级1 */
.parent-a {
  position: relative;   /* 定位元素 */
  z-index: 1;          /* 创建层叠上下文,整体层级为1 */
}

/* 父容器B:创建层叠上下文,层级2 */
.parent-b {
  position: relative;   /* 定位元素 */
  z-index: 2;          /* 创建层叠上下文,整体层级为2 */
}

/* 子元素A:虽然z-index很大,但受限于父容器 */
.box-a {
  position: absolute;   /* 绝对定位 */
  z-index: 9999;       /* 再大也只在parent-a内部生效 */
                       /* 整体仍然在parent-b下面! */
}

/* 子元素B:z-index小但父容器层级高 */
.box-b {
  position: absolute;
  z-index: 1;          /* 虽然只有1,但parent-b整体在上 */
                       /* 所以box-b会覆盖box-a */
}

很多人会以为:box-az-index: 9999 一定压过 box-b

但实际上:整个 parent-b(z=2)层叠上下文都压在 parent-a(z=1)之上

可以用图示理解:

txt 复制代码
层叠上下文树状结构:

页面根(层叠上下文0)
│
├─ parent-a (z-index: 1) ──────┐ 层级1:整体在下
│   └─ box-a (z-index: 9999)   │ 9999只在parent-a内部有效
│                              │ 无法突破父容器层级限制
│
└─ parent-b (z-index: 2) ──────┐ 层级2:整体在上  
    └─ box-b (z-index: 1)      │ 虽然只有1,但父容器赢了
                               │ 所以box-b覆盖box-a

记住:子元素的z-index再大,也无法超越父容器的层叠上下文!

结论:不要指望用"极大值 z-index"解决所有层级问题,更重要的是理解层叠上下文结构,并在合适的容器上设置正确的 z-index。

15.3 浏览器渲染顺序(简化版)

理解浏览器如何渲染,有助于你写出更高效、可预期的 CSS。这里给出一个简化流程:

txt 复制代码
浏览器渲染流程详解:

1. 解析 HTML → 构建 DOM 树
   将HTML标签转换为树状结构的对象

2. 解析 CSS → 构建 CSSOM 树
   将CSS规则转换为样式对象树

3. 合并 DOM + CSSOM → 渲染树(Render Tree)
   只包含可见元素,display:none的不在其中

4. 布局(Layout/Reflow):计算位置和大小
   确定每个元素的精确位置和尺寸
   ⚠️ 改变width/height/margin等会触发

5. 绘制(Paint):填充像素
   填充颜色、边框、文字、阴影等视觉效果
   ⚠️ 改变color/background/box-shadow等会触发

6. 合成(Composite):图层合并
   将多个图层合成最终图像显示到屏幕
   ✅ transform/opacity只触发这一步,性能最好

ASCII 示意:

txt 复制代码
HTML      CSS
  ↓        ↓
 DOM     CSSOM
   \      /
    Render Tree
        ↓
      Layout
        ↓
      Paint
        ↓
    Composite

我们后面讲性能优化,会尽量避免那些会频繁触发布局和重绘的写法。


第15章从"谁的规则生效"到"谁在谁上面",把层叠与层级关系梳理了一遍。接下来第16章,我们会更关注"写得快不快、渲染累不累",深入 CSS 性能优化的一些实际建议。

第16章 CSS 性能优化

这一章解决的核心问题:

  • 哪些 CSS 写法对性能影响大,应该尽量避免?
  • 如何减少不必要的重排(reflow)和重绘(repaint)?
  • 在复杂页面中,如何用 DevTools 粗略判断性能问题?

16.1 避免昂贵选择器

浏览器在应用 CSS 时,需要对每个元素判断"这个选择器是否命中"。大多数现代浏览器已经对这块做了大量优化,但极端复杂的选择器仍然会增加匹配成本。

16.1.1 选择器匹配的基本策略

浏览器通常是从选择器的"最右边那一段"开始匹配的:

css 复制代码
/* 浏览器从右往左匹配选择器 */
.sidebar ul li a.active { 
  color: #2563eb; 
}
/*          ↑ 第一步:找所有 a.active
        ↑   第二步:检查是否在 li 中
     ↑      第三步:检查是否在 ul 中
  ↑         第四步:检查是否在 .sidebar 中
*/

这里会先找所有满足 a.active 的元素,然后再回头检查它们是否处在 .sidebar ul li 的结构中。

css 复制代码
/* ✖ 不推荐:过度复杂的选择器 */
body > main > section > div.container ul li a span.text {
  /* 层级太深,匹配效率低 */
  /* DOM结构一变就失效 */
}

/* ✖ 不推荐:脆弱的标签选择器 */
ul li a span { 
  /* 依赖HTML结构 */
  /* 可能匹配太多不想要的元素 */
}

/* ✔ 推荐:简洁的类名选择器 */
.nav__link--active {
  /* 直接命中,效率高 */
  /* 不依赖DOM结构 */
  color: #2563eb;
}

/* ✔ 推荐:适度的组合 */
.sidebar .nav__link {
  /* 只有必要时才加父级限定 */
  /* 保持简洁 */
}
16.1.2 避免使用万能选择器组合大范围匹配

例如:

css 复制代码
/* ✖ 不推荐:万能选择器组合 */
div[class^="col-"] * {
  /* * 会匹配所有子元素 */
  /* 如果嵌套很深,会匹配成百上千个元素 */
  padding: 10px;
}

/* ✖ 不推荐:复杂属性选择器 */
*[data-*] {
  /* 扫描页面所有元素的所有data属性 */
  /* 极其低效 */
}

/* ✔ 推荐:精确指定 */
.col > .col-item {
  /* 只匹配直接子元素 */
  /* 范围明确,效率高 */
  padding: 10px;
}

如果不是特别必要,避免在高频区域大量使用 * 作为后代选择器,因为它会匹配所有嵌套元素,增加匹配范围。

在现代浏览器中,性能瓶颈更多来自布局和绘制,而不是选择器本身,但养成写"干净选择器"的习惯,可以减少潜在问题,也提升可维护性。

16.2 动画性能:尽量用 transform / opacity

动画与过渡是性能敏感区域,如果处理不当,会出现卡顿、掉帧。

16.2.1 哪些属性对性能更友好?

一般建议:优先用 transformopacity 做动效

原因:

  • 它们通常只触发"合成层更新"(Composite),不需要重新布局
  • 在 GPU 加速下,能以较低成本实现平滑动画
css 复制代码
/* 性能影响分级 */

/* 第一级:最优 (只触发合成) */
.best-performance {
  transform: translateX(100px);    /* 位移 */
  opacity: 0.8;                    /* 透明度 */
  /* GPU加速,性能最佳 */
}

/* 第二级:中等 (触发重绘) */
.medium-performance {
  color: red;                      /* 颜色 */
  background: blue;                /* 背景 */
  box-shadow: 0 2px 4px rgba(0,0,0,0.1); /* 阴影 */
  /* 需要重绘,但不用重新布局 */
}

/* 第三级:最差 (触发布局重排) */
.worst-performance {
  width: 200px;                    /* 宽度 */
  height: 100px;                   /* 高度 */
  padding: 20px;                   /* 内边距 */
  margin: 10px;                    /* 外边距 */
  left: 50px;                      /* 位置 */
  /* 整个页面可能都要重新计算 */
}
16.2.2 把位置动画改成 transform
css 复制代码
/* ✖ 不推荐:使用left/top做动画 */
.box {
  position: relative;
  transition: left 0.3s ease;     /* left会触发布局重计算 */
}

.box.move {
  left: 100px;                    /* 每帧都要重新计算布局 */
}                                 /* 性能较差,可能卡顿 */

/* ✔ 推荐:使用transform做动画 */
.box {
  transition: transform 0.3s ease; /* transform只触发合成层更新 */
  will-change: transform;          /* 提示浏览器做优化 */
}

.box.move {
  transform: translateX(100px);    /* GPU加速,性能优异 */
}                                  /* 不重新布局,非常流畅 */

示意对比:

txt 复制代码
浏览器渲染流程对比:

left/top 动画:
  改变位置 → 重新布局(Layout) → 重新绘制(Paint) → 合成(Composite)
            每一帧都要走完整流程,昂贵!

transform 动画:
  改变变换 → → → 合成(Composite)
            跳过布局和绘制,直接GPU合成,高效!

opacity 动画:
  改变透明度 → → → 合成(Composite)
             同样只需要合成阶段,性能优异!
16.2.3 避免大面积、频繁的阴影变化

box-shadow 在大面积区域频繁变化会比较耗费绘制性能。

建议:

  • 避免对非常大的元素做频繁阴影动画
  • 尽量使用较柔和、半透明的阴影,而不是极大范围的高斯阴影

16.3 精简 CSS 与压缩策略

16.3.1 删除无用样式

在真实项目中,随着迭代,CSS 常常出现"死代码":某些类已经不再被使用。

可以借助工具:

  • PurgeCSS、unCSS 等,用于分析哪些选择器在 HTML/模板中未被引用

原理大致是:

txt 复制代码
扫描模板 → 记录用到的 class/id/tag
与 CSS 中选择器做对比 → 剔除未使用的部分

在前端构建流程中集成这类工具,可以显著减少产物 CSS 体积。

16.3.2 压缩与拆分

构建阶段常见优化:

  • 压缩:移除空格、注释、简化颜色写法(如 #ffffff#fff
  • 拆分:按路由或模块拆分 CSS,首屏只加载必要部分

示意:

txt 复制代码
styles.bundle.css   → 基础 + 全局组件
home.css            → 首页特定样式
dashboard.css       → 后台页面特定样式

在 SPA 框架(React/Vue 等)中,这通常由构建工具自动完成,你重点是要"有这个意识":

  • 尽量让页面只加载它需要的那部分 CSS
16.3.3 避免过度嵌套与重复

样式编写时尽量避免:

  • Sass 里层层嵌套太深,生成类似 .a .b .c .d .e { ... } 的选择器
  • 同一组样式出现多次而不抽取到公共类

这不仅影响性能,更直接影响可维护性。

16.4 使用 DevTools 粗略观察性能

Chrome DevTools 提供了若干对 CSS/渲染性能有帮助的工具:

  • Rendering 面板中的 Paint flashing:高亮重绘区域
  • Performance 面板:录制一段用户操作,查看帧率和主要耗时

你可以做一个简单的实验:

  1. 写一个用 left/top 动画的位置移动效果
  2. 打开 Paint flashing
  3. 再改成 transform: translate 动画,对比重绘区域

不需要成为性能专家,但要有"性能嗅觉":当页面卡顿时,优先检查是否有大面积布局变化或复杂动画。


第16章从选择器、动画到 CSS 体积,给出了性能优化的一些实践建议。接下来第17章,我们会把视角拉长,看看 Sass、PostCSS 这些工具是如何协助我们管理复杂 CSS 的。

第17章 预处理与后处理

这一章解决的核心问题:

  • Sass 这样的预处理器在现代前端中扮演什么角色?
  • PostCSS、Autoprefixer 这些"后处理"工具主要做什么?
  • 什么时候该用预处理器,什么时候用原生 CSS 变量和现代特性?

17.1 Sass 基础

Sass 是最流行的 CSS 预处理器之一,常见语法后缀有 .scss.sass,其中 .scss 与 CSS 语法更接近(分号、大括号等都保留)。

预处理器的核心思想:在编译阶段扩展 CSS 的能力,比如:

  • 变量
  • 嵌套
  • Mixin(可复用片段)
  • 函数、循环等
17.1.1 变量与嵌套示例

SCSS 示例:

scss 复制代码
/* SCSS:Sass的主流语法,兼容CSS写法 */

// 变量定义:$开头
$primary: #2563eb;        // 主色变量
$radius-md: 12px;         // 圆角变量

.btn {
  padding: 0.6em 1.4em;
  border-radius: $radius-md;    // 使用变量
  background: $primary;          // 使用变量
  color: #fff;

  // &代表父选择器(.btn)
  &:hover {                      // 等同于 .btn:hover
    // ⚠️ darken() 在 Dart Sass 1.79+ 已废弃,会产生警告
    // 旧写法(不推荐):background: darken($primary, 8%);
    // 新写法:使用 color.adjust() 或 color.scale()
    @use 'sass:color';
    background: color.adjust($primary, $lightness: -8%); // 亮度降低8%
  }
  
  // 嵌套修饰符
  &--large {                     // 等同于 .btn--large
    font-size: 1.2rem;
  }
}

编译后生成的 CSS 大致为:

css 复制代码
/* 编译后的普通CSS */
.btn {
  padding: 0.6em 1.4em;
  border-radius: 12px;      /* $radius-md 被替换为 12px */
  background: #2563eb;      /* $primary 被替换为 #2563eb */
  color: #fff;
}

.btn:hover {               /* 嵌套被展开 */
  background: #1d4ed8;     /* darken()函数被计算为具体值 */
}

.btn--large {              /* BEM嵌套被展开 */
  font-size: 1.2rem;
}

你可以看到:

  • 变量 $primary 在编译时被替换为实际颜色值
  • &:hover 嵌套被展开为 .btn:hover
17.1.2 Mixin 与函数

Mixin:

scss 复制代码
/* Mixin:可复用的样式片段 */

// 定义mixin
@mixin flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

// 带参数的mixin
@mixin button-size($padding-y, $padding-x, $font-size) {
  padding: $padding-y $padding-x;
  font-size: $font-size;
}

// 使用mixin
.badge {
  @include flex-center;          // 引入flex-center的所有样式
  padding: 0.1rem 0.55rem;
}

.btn-large {
  @include button-size(0.8rem, 1.5rem, 1.1rem); // 传参
}

函数示例(简化):

scss 复制代码
/* Sass函数:计算和返回值 */

// 定义函数,$base有默认值16
@function px-to-rem($px, $base: 16) {
  @return ($px / $base) * 1rem;   // 返回计算结果
}

// 颜色处理函数
@function tint($color, $percentage) {
  @return mix(white, $color, $percentage);
}

// 使用函数
body {
  font-size: px-to-rem(18);       // 编译为 1.125rem
  line-height: px-to-rem(28);     // 编译为 1.75rem
}

.light-blue {
  background: tint($primary, 80%); // 80%白色 + 20%主色
}

这些都在"编译阶段"被算好,输出普通 CSS。

17.2 嵌套、变量、Mixin 的利与弊

预处理器带来便利的同时,也有一些需要注意的地方。

17.2.1 优点
scss 复制代码
/* 预处理器的优点 */

// 1. 变量管理
$colors: (
  primary: #2563eb,
  success: #10b981,
  danger: #ef4444
);                          // 集中管理颜色

// 2. 代码复用
@mixin card-style {
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  padding: 1rem;
}                          // 一处定义,多处使用

// 3. 嵌套结构清晰
.nav {
  ul {                     // 视觉上符合HTML结构
    li {
      a { }
    }
  }
}

// 4. 计算能力
$base-font: 16px;
$scale: 1.25;
h1 { font-size: $base-font * $scale * $scale; }  // 25px
h2 { font-size: $base-font * $scale; }           // 20px
17.2.2 潜在问题
scss 复制代码
/* 潜在问题和注意事项 */

// ✖ 过度嵌套问题
.page {
  .container {
    .content {
      .article {
        .paragraph {
          a { }  // 编译后:.page .container .content .article .paragraph a
                 // 太长了!难维护!
        }
      }
    }
  }
}

// ✔ 限制嵌套层级(最多3层)
.article {
  &__title { }      // .article__title
  &__content {
    a { }          // .article__content a,适度即可
  }
}

// ✖ Mixin膨胀问题
@mixin complex-style {
  // 50行代码...
}
.item1 { @include complex-style; }  // 复制50行
.item2 { @include complex-style; }  // 再复制50行
                                    // CSS体积翻倍!

// ✔ 用extend或公共类
%card-base {                       // placeholder选择器
  // 公共样式
}
.card { @extend %card-base; }      // 继承,不重复代码

一个经验法则:

用预处理器"补足"当前项目所需的能力,而不是把它当成"越复杂越好"的玩具。

17.3 PostCSS 与 Autoprefixer

PostCSS 更像是一个"CSS 处理平台",Autoprefixer 是其中最常用的插件之一。

17.3.1 Autoprefixer:自动补全厂商前缀

过去我们常常需要手动写:

css 复制代码
/* Autoprefixer 自动添加厂商前缀 */

/* 你写的代码 */
.box {
  border-radius: 12px;
  user-select: none;
  display: flex;
}

/* Autoprefixer处理后 */
.box {
  -webkit-border-radius: 12px;  /* 旧版Safari */
  -moz-border-radius: 12px;     /* 旧版Firefox */
  border-radius: 12px;          /* 标准属性 */
  
  -webkit-user-select: none;    /* Safari */
  -moz-user-select: none;       /* Firefox */
  -ms-user-select: none;        /* IE/Edge */
  user-select: none;            /* 标准 */
  
  display: -webkit-box;         /* 旧版Safari */
  display: -webkit-flex;        /* Safari */
  display: -ms-flexbox;         /* IE10 */
  display: flex;                /* 标准 */
}
js 复制代码
/* browserslist 配置文件 */

// package.json 中配置
"browserslist": [
  "> 1%",                  // 全球使用率 > 1%
  "last 2 versions",       // 每个浏览器最新两个版本
  "not dead",              // 排除已停止维护的浏览器
  "not ie 11"              // 排除IE11
]

// 或者 .browserslistrc 文件
> 0.5%                     # 使用率大于0.5%
last 2 Chrome versions     # Chrome最新两版
last 2 Firefox versions    # Firefox最新两版
last 2 Safari versions     # Safari最新两版
not dead                   # 排除死掉的浏览器

// Autoprefixer会根据这个列表决定:
// - 需要添加哪些前缀
// - 可以删除哪些不再需要的前缀
17.3.2 其它常见 PostCSS 插件
js 复制代码
/* 常见PostCSS插件及作用 */

// postcss.config.js
module.exports = {
  plugins: [
    // 1. Autoprefixer:自动添加厂商前缀
    require('autoprefixer'),
    
    // 2. CSSnano:压缩优化CSS
    require('cssnano')({
      preset: 'default',   // 移除注释、压缩空格
                          // 合并规则、简化颜色等
    }),
    
    // 3. postcss-preset-env:使用未来CSS特性
    require('postcss-preset-env')({
      stage: 0,           // 启用实验性特性
      features: {
        'nesting-rules': true,      // CSS嵌套
        'custom-properties': false, // 禁用(已有原生支持)
      }
    }),
    
    // 4. purgecss:移除未使用的CSS
    require('@fullhuman/postcss-purgecss')({
      content: ['./src/**/*.html'],  // 扫描这些文件
      safelist: ['active', 'hidden'] // 保留这些类
    })
  ]
}

在现代前端工程里,PostCSS 通常集成在构建链路中(如 webpack、Vite),你配置好插件后,它在打包时自动处理 CSS。

17.4 构建工具与现代前端中的位置

把整个链路简化成一张图:

txt 复制代码
CSS 工程化流程图:

开发阶段:
    开发者编写
         ↓
  Sass/Less/Stylus      ← 预处理器
  (变量、嵌套、Mixin)       提供开发便利
         ↓ 编译
    标准 CSS 
         ↓
构建阶段:
      PostCSS           ← 后处理器
    │                      处理兼容性
    ├─ Autoprefixer       (自动前缀)
    ├─ CSSnano           (压缩优化)
    └─ PurgeCSS          (移除无用)
         ↓
   打包工具
  (Webpack/Vite)       ← 模块化管理
         ↓                 代码分割
    最终CSS产物
   (压缩、优化、兼容)
         ↓
   部署到生产环境

现代原生 CSS 的能力越来越强:

css 复制代码
/* 现代CSS原生特性 🆕 */

/* 1. CSS变量(已广泛支持) */
:root {
  --primary: #2563eb;      /* 运行时变量 */
}                         /* 可动态修改! */

/* 2. CSS嵌套(正在普及) */
.card {
  &__title { }            /* 原生支持嵌套 */
  &:hover { }             /* 不再需要Sass */
}

/* 3. @layer 层叠层(2022年已全面落地,Chrome 99+/Firefox 97+/Safari 15.4+) */
@layer base, components, utilities;
@layer components {
  .btn { }                /* 明确控制层级 */
}

/* 4. @container 容器查询(2023年已全面落地,Chrome 105+/Firefox 110+/Safari 16+) */
.card {
  container-type: inline-size;
}
@container (min-width: 400px) {
  .card__title { }        /* 基于容器而非视口 */
}

/* 5. :is() / :where() 选择器 */
:is(h1, h2, h3) {        /* 简化多选择器 */
  color: var(--primary);
}

因此,新的项目可以考虑:

  • 优先使用现代 CSS 原生特性
  • 在确实需要时,引入少量预处理器能力

工具的目标是"让你的 CSS 更易维护、更好适配浏览器",而不是增加复杂度本身。理解它们的角色之后,你可以针对项目规模、团队情况来选择合适的组合。


第六篇从层叠与优先级、到性能优化,再到预处理与后处理工具,带你从"会写 CSS"更进一步,理解浏览器与工程化的基础。到这里,你已经具备了构建中大型 CSS 代码库的核心知识储备,接下来可以把更多精力放在"真实项目实践"与"团队协作规范"上。

相关推荐
Cache技术分享6 小时前
397. Java 文件操作基础 - 创建常规文件与临时文件
前端·后端
Daybreak6 小时前
Vercel Serverless 调国内 AI 接口 504?Edge Runtime 救了我
前端
zubylon6 小时前
Ollama 本地起一个开发助手
前端·人工智能
遇见~未来6 小时前
第五篇_构建真实页面_组件_响应式_维护性
前端·css3
魔士于安6 小时前
Unity完整小球迷宫项目
前端·unity·游戏引擎·贴图·模型
irpywp6 小时前
苦于AI生成的网页千篇一律且粗糙?design-md-chrome :一款网页样式提取插件 ,将任意网站的视觉规范转化为大模型可读的代码指令!
前端·人工智能·chrome·开源·github
skilllite作者6 小时前
Warp 终端效能与交互体验全景展示
人工智能·后端·架构·rust
xingpanvip6 小时前
星盘接口开发文档:日运语料接口指南
android·开发语言·前端·css·php·lua