---
title: "票券缺口效果：伪元素遮罩、层叠顺序与 1px 像素对齐"
date: 2026-09-26
description: "票券上的缺口不是剪出来的，是盖出来的：一块同色伪元素压在卡片边框上，再算对那 1px 的对齐。本文拆穿这效果背后的层叠顺序、border-style 解析与 overflow 裁切，全程像素级、无半张遮罩图。"
canonical_url: "https://yijinlee.com/articles/article-71"
tags:
  - CSS
  - 伪元素
  - 层叠上下文
  - 盒模型
  - border-radius
  - overflow
  - 像素对齐
topic: "AI 外骨骼"
---

METRICS: 9×16px|缺口尺寸 · 8px|圆角半径 · 1px|边框对缝 · 2|伪元素 · 0|额外 DOM

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

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

### 一、缺口是盖出来的

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

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

### 二、三个小坑

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

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

### 三、像素账

```css
.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 的解析优先级、裁切上下文的边界。读完就明白，这效果一点不玄学。

## 参考文章：相关链接

- [MDN · overflow（裁切上下文与 Padding Box 裁剪）](https://developer.mozilla.org/zh-CN/docs/Web/CSS/overflow)（官方文档）— overflow: hidden 建立裁切上下文，以 Padding Box 为界裁剪子元素，是缺口被裁掉那 1px 的依据。
- [MDN · ::before / ::after 伪元素](https://developer.mozilla.org/zh-CN/docs/Web/CSS/::before)（官方文档）— 生成内容作为宿主子节点参与渲染，解释伪元素为何能覆盖卡片自身边框。
- [W3C · CSS Backgrounds and Borders Module Level 3](https://www.w3.org/TR/css-backgrounds-3/)（权威引文）— border-style: none 时不绘制边框，以及圆角半径叠加拟合的规范出处。
- [MDN · CSS 层叠上下文（Stacking context）](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_positioned_layout/Understanding_z-index/Stacking_context)（官方文档）— position: relative 创建层叠上下文后的绘制顺序，是"同色融合"错觉的机制基础。
- [Vue 样式穿透、亚像素模糊与盒模型陷阱](https://yijinlee.com/articles/article-63)（站内深度）— 同属 CSS 渲染引擎隐藏规则的像素级拆解。
- [支付按钮点完页面就"瘫痪"？一行 CSS 冻住全场](https://yijinlee.com/articles/article-12)（站内深度）— 同属样式属性覆盖与绘制行为引发的视觉"幽灵现场"。

