现代 CSS 三剑客:Cascade Layers、嵌套、:has() 选择器实战指南

By | 2026年7月7日

引言

CSS 近年来发展迅猛,从过去的“样式表语言”逐渐进化为拥有强大逻辑能力的“样式系统”。今天我们要聊的三个特性——Cascade Layers(层叠层)CSS 嵌套:has() 选择器——分别解决了长期困扰开发者的优先级混乱、样式冗余和父级选择缺失问题。

如果你还在用 BEM 命名法硬撑、用 !important 暴力覆盖,或者用 JS 来监听状态改变父元素样式,那么这篇文章将为你打开新世界的大门。

1. Cascade Layers:告别优先级焦虑

1.1 背景与问题

传统 CSS 的优先级基于选择器特异性(Specificity)和源码顺序。在大型项目中,第三方库(如 Bootstrap)、组件库、业务样式层层叠加,优先级计算变得极其复杂,经常需要用 !important 强行覆盖,导致样式难以维护。

1.2 什么是 Cascade Layers?

@layer 规则允许你将样式分层定义,后定义的层会覆盖先定义的层,与选择器特异性无关。这就像给样式加了“优先级层级”,让你从全局角度控制样式权重。

1.3 基本用法


/* 定义层顺序(后定义的层优先级更高) */
@layer base, components, utilities;

/* 在 base 层中定义基础样式 */
@layer base {
    button {
        padding: 8px 16px;
        border: 1px solid #ccc;
        background: #f0f0f0;
    }
}

/* 在 components 层中定义组件样式 */
@layer components {
    .btn-primary {
        background: #007bff;
        color: white;
        border-color: #007bff;
    }
}

/* 在 utilities 层中定义工具类 */
@layer utilities {
    .mt-4 {
        margin-top: 1rem;
    }
}

关键点:即使 base 层中的 button 选择器特异性更高,components 层中的 .btn-primary 也会覆盖它,因为 components 层定义在 base 之后。

1.4 实战:覆盖第三方库样式

假设你使用了 Bootstrap,并希望自定义按钮样式:


/* 先定义层:第三方库样式放在 lowest 层,自定义样式放在 higher 层 */
@layer bootstrap, custom;

/* 导入 Bootstrap */
@import url('bootstrap.min.css') layer(bootstrap);

/* 自定义样式 */
@layer custom {
    .btn {
        border-radius: 0; /* 覆盖 Bootstrap 的圆角 */
    }
}

这样,无论 Bootstrap 内部选择器特异性多高,你都可以在 custom 层中轻松覆盖,无需 !important

1.5 注意事项

  • 层顺序必须在所有 @layer 语句之前定义(可在