← 返回文章列表
所属专题:AI 外骨骼

票券缺口效果:伪元素遮罩、层叠顺序与 1px 像素对齐

by李奕锦年份:2026字数:1,000阅读时长:3 分钟

缺口不是"剪"出来的,而是被一块同色矩形盖住的——看懂层叠顺序与 1px 对齐,这个效果就不再玄学。

TL;DR · 核心结论

  • 1缺口是 cover 不是 mask:同色伪元素盖住宿主边框,看起来像被剪掉一块。
  • 2与 overflow: hidden 互斥:裁切会砍掉覆盖边框的那 1px。
  • 3尺寸定死:宽度 = 半径 + 1px、高度 = 2 × 半径、起点 = -1px。

CSS 渲染机制 · 票券缺口

9×16px

缺口尺寸

8px

圆角半径

1px

边框对缝

2

伪元素

0

额外 DOM

票券上那种"被咬掉一块"的缺口,页面上其实没有半张图,DOM 也没被真剪过。它靠的是两件小事:层叠顺序和 1px 对齐。

说人话:缺口不是剪出来的,是盖出来的。放一块和背景同色的矩形,压在卡片边框上,那一小段边框就被"擦"掉了。

交互演示

Ticket Cutout

示例票券卡片

1px 边框 + 9px × 16px 同色伪元素遮罩

当前 overflow: visible —— 伪元素延伸到 Border Box 外缘,同色覆盖形成干净的半圆缺口。

一

缺口是盖出来的

::before / ::after 是 CSS 2.1 的生成内容,在布局树里是宿主的子节点,绘制天然晚于宿主自己的背景和边框。所以给卡片 position: relative,再让伪元素绝对定位、涂成父容器底色,它就会盖住那一小段边框——看起来像凹进去一块。

记住一句:这是 cover,不是 mask。缺口处没透明,只是被一块同色矩形挡住。换句话说,你看到的"缺口",本质是一块色块,只是它和背景长成一个颜色,骗过了眼睛。

二

三个小坑

  1. 1border-left: none 比 border-left-width: 0 干净。规范说 border-style: none 时,即使宽度不为 0,Paint 阶段也不画任何像素。
  2. 2overflow: hidden 不能留。它建立裁切上下文,把子元素(含伪元素)限制在 Padding Box 内。卡片有 1px 边框,伪元素得伸到 Border Box 外缘才盖得住它;一开裁切,那 1px 被切掉,缺口两边会残留竖线。
  3. 3同色要跟父容器一致,不是跟卡片一致。卡片白、底灰,伪元素就得涂灰,涂错一秒穿帮。

所以这效果天生和 overflow: hidden 互斥。要缺口,就得放弃裁切,改成手动对齐 border-radius。

三

像素账

.ticket-card {
  position: relative;
  border: 1px solid #3b82f6;
  border-radius: 12px;
}

.ticket-card::before {
  content: '';
  position: absolute;
  top: 50%;
  left: -1px;
  width: 9px;    /* 8px 半径 + 1px 边框 */
  height: 16px;  /* 2 × 8px */
  margin-top: -8px;
  border-radius: 0 8px 8px 0;
  background: #f2f5f7;
}

三笔账背下来就行:

  • 宽度 = 半径 + 1px,多出的 1px 专门用来盖卡片边框;
  • 高度 = 2 × 半径;
  • 起点 = -1px,让左边缘贴住 Border Box 外缘。

border-radius: 0 8px 8px 0 让右上、右下各取 8px,加起来正好等于 16px 高,两段圆弧在中点相切,自然长出标准半圆,不用写任何路径。要左右两个缺口,就再写一个 ::after,半径镜像成 8px 0 0 8px,left: -1px 换成 right: -1px。

十来行 CSS 而已。难的不是代码,是背后的规范:生成内容的绘制顺序、border-style 的解析优先级、裁切上下文的边界。读完就明白,这效果一点不玄学。

本文属于 AI 实用主义流派 的第 52 篇肉身实战。

阅读时长:3 分钟


文档信息

版权声明:自由转载-非商用-非衍生-保持署名(CC BY-NC-ND 3.0)

原文链接:https://yijinlee.com/articles/article-71

作者:李奕锦

商业用途或修改衍生请联系授权。


李奕锦
李奕锦

全栈工程师,业余马拉松选手。

TL;DR

  • 缺口是 cover 不是 mask:同色伪元素盖住宿主边框,看起来像被剪掉一块。
  • 与 overflow: hidden 互斥:裁切会砍掉覆盖边框的那 1px。
  • 尺寸定死:宽度 = 半径 + 1px、高度 = 2 × 半径、起点 = -1px。
Tags:CSS伪元素层叠上下文盒模型border-radiusoverflow像素对齐

参考文章:相关链接

权威引文 · 官方文档 · 站内深度文

  1. border-style: none 时不绘制边框,以及圆角半径叠加拟合的规范出处。

  2. overflow: hidden 建立裁切上下文,以 Padding Box 为界裁剪子元素,是缺口被裁掉那 1px 的依据。

  3. 生成内容作为宿主子节点参与渲染,解释伪元素为何能覆盖卡片自身边框。

  4. position: relative 创建层叠上下文后的绘制顺序,是"同色融合"错觉的机制基础。

  5. 同属 CSS 渲染引擎隐藏规则的像素级拆解。

  6. 同属样式属性覆盖与绘制行为引发的视觉"幽灵现场"。

该专题下的阅读路径

AI Coding架构排障

常见问题 FAQ

Q1. 为什么伪元素能盖住卡片自己的边框?
伪元素是 CSS 2.1 定义的生成内容,在布局树里作为宿主元素的子节点参与渲染。卡片设置 position: relative 后成为包含块,绝对定位的伪元素背景在绘制顺序上晚于宿主自身的背景与边框,因此能把那一小段边框盖住。
Q2. 为什么移除 overflow: hidden 之后缺口才正常?
overflow: hidden 会建立新的裁切上下文,把子元素(含绝对定位伪元素)的绘制限制在 Padding Box 内。卡片自带 1px 边框,伪元素必须延伸到 Border Box 外缘才能覆盖边框,开启裁切后那 1px 会被直接裁掉,缺口两侧就会残留竖线。
Q3. border-left: none 为什么能去掉竖线?
border-left: none 会把 border-left-style 解析为 none。规范规定 border-style 为 none 时,即使 border-width 不为 0,Paint 阶段也不会绘制任何像素。相比把宽度写成 0,它更明确地表达了"这条边不画"。
Q4. 为什么缺口宽度是 9px 而不是 8px?
8px 是与卡片洞壁衔接的圆弧半径,额外的 1px 用来覆盖卡片自身的物理边框,再配合 left: -1px 让伪元素左边缘贴住 Border Box 外缘,这样圆弧与洞壁才连贯、上下边框才对得齐。
Q5. 圆角为什么会自动拟合出标准半圆?
设置 border-radius: 0 8px 8px 0 后,右上与右下两点各取 R = 8px。因为两个半径之和 16px 正好等于元素高度,两段圆角的切线在中点相切,自然拟合出标准半圆弧,不需要额外的路径或图片。

发表评论

分享你的想法和反馈

支持 Markdown 格式

0/5000