HTML、CSS与可访问性 · KNOWLEDGE CHAPTER
K02

层叠、选择器与定位

排查 CSS 时先分清四个问题:声明为什么获胜、元素相对谁定位、整组内容在谁前面绘制、内容是否被裁掉。层叠决定属性值,包含块决定几何参照,层叠上下文限制绘制排序,裁剪决定可见边界。它们经常被同一属性同时改变,却不能互相替代。

HTML、CSS与可访问性2 道章节练习4 道主练关联
先修知识:K01 · 语义与表单

核心模型

排查 CSS 时先分清四个问题:声明为什么获胜、元素相对谁定位、整组内容在谁前面绘制、内容是否被裁掉。层叠决定属性值,包含块决定几何参照,层叠上下文限制绘制排序,裁剪决定可见边界。它们经常被同一属性同时改变,却不能互相替代。

原理与机制

层叠先决定赛道,再比较具体性

选择器具体性不是跨所有规则的统一分数。先排除不适用规则,再比较来源与重要性、层叠层等条件,接着才比较具体性;有 @scope 时还要考虑作用域接近程度,最后才是声明顺序。同一来源的普通样式表声明中,后层高于前层,未分层高于分层;important 的层顺序反转。内联声明另有位置,动画值可压过普通声明,过渡中的值还可能高于 important。继承值不拿父元素选择器与子元素自身声明比权重。

关系选择器表达结构,不拥有业务状态

:has() 根据关联元素是否匹配来选择当前元素,例如字段包含 invalid 输入时改变容器外观。其具体性取参数列表最高值,.card:has(.error,#fatal) 即使由 .error 命中也引入 ID 权重;:where() 则贡献零。DOM 状态不等于展示时机,必填框初始 invalid 不代表应立即报错,应另建 touched 或 attempted 状态。invalid 可能阻止 submit 发生,记录尝试需覆盖实际提交路径或捕获 invalid。范围过大的关系查询还会增加重新匹配的工作。

定位必须沿祖先寻找实际参照

absolute 脱离正常流,通常相对最近非 static 定位祖先的包含块;transform 等也可建立包含块。fixed 通常相对视口,但非 none 的祖先 transform 即使没有可见位移,也能改变参照。sticky 保留流中位置,达到指定轴的 inset 阈值后受最近相关滚动容器约束,并受包含块边界限制。排查时看祖先 overflow 的计算值、容器是否有滚动空间、项目是否被拉伸占满,以及 top 等阈值是否仍为 auto。

z-index 是上下文内部的相对排序

定位配合非 auto 的 z-index、fixed/sticky、opacity 小于 1、transform 等可能建立层叠上下文。一个上下文在父级排序时视为整体,低层父容器里的巨大 z-index 不能越过高层兄弟。opacity:0.99 让整组内容透明并创建上下文;背景色的 alpha 只影响背景,不会仅因此产生同样边界。还要区分遮挡与 overflow 裁剪。可修正父级层次或弹层挂载,适用时采用浏览器顶层机制,而不是继续增加数字。

最小示例

css
css
@layer vendor, app;
@layer vendor { #save { color: red; } }
@layer app { button { color: blue; } }
/* 将两条 color 都加 !important,结果会反转。 */
.parent { position: relative; z-index: 1; }
.parent .popup { position: absolute; z-index: 999999; }
.sibling { position: relative; z-index: 2; }

给按钮 id=save,普通声明下颜色是蓝色,因为先比较层;两条同时重要时红色胜出。若 popup 与 sibling 几何区域重叠,popup 仍受 parent 的层级限制。这个例子分别控制声明竞争和绘制竞争,能避免把“样式没生效”与“层级被挡”混成一个问题。

环境:支持本章相关特性的现代浏览器;CSS 片段需配合说明中的最小 HTML。

核验:未执行教学示例;说明中的结果为机制推演,不是本轮测试通过记录。

边界与取舍

边界

  • 未分层普通声明不能压过第三方 important;早层策略主要降低普通样式的覆盖成本。
  • fixed 并非永远相对视口;先临时关闭祖先 transform 验证因果。
  • 巨大 z-index 不能解除裁剪,也不能让普通元素拥有模态背景失活与焦点管理。

取舍

  • 低具体性与显式层次便于维护;important 可表达强制约束,但滥用会制造反转排序和覆盖债务。
  • :has 可减少结构状态的 class 同步;业务状态仍应显式建模,关系查询范围也需受控。

口述示范

我会从计算样式确认是哪条声明获胜,再沿祖先查包含块、滚动容器和层叠上下文。CSS 具体性只是一轮比较,定位与绘制又各有边界;用关闭单个属性的最小实验找因果,比堆 important 或 z-index 更可靠。

章节练习

练习 1

在假设的 CSSLab 中制作“高具体性仍失败”的最小演示。

展开检查点
  • 用 vendor/app 两层展示普通声明与 important 的反转。
  • 加 :has(.error,#fatal) 与 :where 对照,解释具体性来自参数列表。
练习 2

一个 sticky 工具栏不吸附,fixed 弹层又跟着局部区域滚动,怎样分开定位?

展开检查点
  • 检查 sticky 阈值、祖先 overflow 计算值与可移动空间。
  • 检查 fixed 祖先 transform;再独立检查上下文排序与裁剪。

参考来源与核验边界

按 2026-10-04 查阅的规范语义编写。:has、@scope 和相关新定位能力的落地需分别核查支持矩阵;本章不以“现代 CSS”一词承诺旧 WebView 兼容。 本章新增示例未在本轮执行,不新增测试通过声明。

内容版本:2026-10-04.2 · 题目和来源 ID 保持原样,本站不将面经标签解释为企业官方出题或高频保证。