卡片变奏 101 · 第 01 课
DraftInverted Corner内凹圆角
从网页最常见的矩形、圆形和胶囊出发,改变一小段边界;再把连续曲率延伸到 Tabs、Notch Bar 与多元素接缝。
A three-step shape variation
让卡片拥有新的轮廓
从内容关系开始,先把转角画顺,再让同一条轮廓进入响应式 DOM。
先给动作留位置
从一个真实的按钮、头像或标签开始,让凹角回应内容,而不是装饰性地贴在卡片外面。
再把转角画顺
用两段贝塞尔曲线连接直线,控制内凹半径与张力,让转弯拥有连续的切线。
最后让它响应
把固定 path 换成百分比和 CSS 变量,让边框、背景与 DOM 内容一起适应不同尺寸。
本课目录+
border-shape 是一项实验性的 CSS 形状能力,可以用 shape() 直接绘制内凹圆角和其他自由轮廓。当前浏览器中的相关示例可能显示为普通矩形;查看完整效果请换用支持该属性的浏览器,实际项目请保留 clip-path、mask 或伪元素回退。
01卡片变奏的起点
提到卡片,我们通常先想到圆角矩形
网页长期使用一套很小的形状词汇。矩形适合承载文字、图片与复杂布局,圆形常用在头像和状态上,胶囊适合按钮、标签与切换项。卡片再给矩形加上一点圆角,就成了今天最常见的界面容器。
这些几何稳定、好排版,也容易和浏览器的背景、边框、阴影配合。它们被反复使用之后,页面的轮廓也会越来越接近。Vibe Coding 让组件更快被做出来,默认组件之间的相似感同样会更快累积。
矩形
圆角矩形
圆形
胶囊
SAME CARD · NEW EDGE
只改一个角,内容结构仍然熟悉
从基础几何开始变奏
内凹圆角仍然保留卡片的主体,只在相邻元素出现的位置改变边界。它比完全自由的异形更容易替换,也更容易进入现有布局。 后面还会把同一段凹曲线从 corner 移到 edge 中段,形成状态条和标签页需要的缺口。
想给页面增加一点新意,可以先从形状语言开始。少加一层装饰,直接改变卡片怎样包住内容、怎样靠近按钮或图片,界面的节奏就会不同。
内凹圆角是一个合适的起点。它只改动一小段边界,卡片原来的文字、图片和交互都能留下;把现有圆角卡片换过来时,宽度适配与内容布局也不需要推倒重来。
那这条凹下去的边要怎么实现?如果手边正好有 Figma,第一反应多半是先把它画出来。
02先试试 SVG
先画成 SVG,放进网页后会遇到什么问题
看到右上角的缺口,最直接的做法是在 Figma 里画好轮廓,再导出一张 SVG。只看一个固定尺寸,这条路没有明显问题:曲线可以反复调,边框也能沿 path 绘制,交付时拿到的外观和画板基本一致。
问题会在它进入真实布局后出现。把同一张 SVG 放进大卡片和小卡片,viewBox 会把路径、内容与 stroke 一起缩放。按钮需要固定点击热区,缺口需要继续容纳它,边框又希望在不同尺寸下保持相近的视觉重量,这几件事开始互相牵制。
路径、文字和 6px stroke 一起保存在同一张图里。
stroke 随整体缩放,文字也快速失去可读性。
要保留固定缺口和边框,需要额外改 viewBox、path 或拆出 DOM 内容。
SVG 可以通过 vector-effect="non-scaling-stroke" 保住描边宽度,也可以作为 CSS 的 background-image 使用。不过,SVG 里面的填色和路径很难继续跟着页面状态变化;外面的 DOM 仍然是矩形,内容、背景、边框和点击区域也要另外处理。同步的问题越多,这张 SVG 就越像一份需要单独维护的资源。
所以这次实现要同时满足三件事:卡片宽度可以变化,缺口和圆角的尺寸可以单独控制,内容与背景继续使用普通 DOM。在选择 CSS 写法之前,还要先看清一件事:曲线怎样连接才会顺?
03看懂曲线
接缝没有折痕,圆角看起来才会顺
先暂时放下 CSS。沿着卡片顶部向右看,轮廓会从直线进入凹面,经过缺口内壁,再回到卡片外沿。半径调大不一定更好看,每一段曲线都要顺着上一段接下去,整个缺口才会像一笔画成。
第一层检查是方向。曲线进入凹面时要顺着顶部直线,离开时也要顺着下一段边界。端点虽然对在一起,控制柄方向却不一致,连接处仍会留下细小折痕。
第二层检查是转弯速度。两段曲线共享切线以后,如果一侧突然收紧、另一侧过分舒缓,眼睛仍会读出拼接感。控制柄长度、内外半径和两侧留白需要一起调,曲率才会自然地传下去。
下面先只看外角怎样接进内角。沿着轮廓走一遍,眼睛在哪一处被绊住,折点、细缝或曲率突变通常就藏在那里。
外角和内角各走各的
接缝可见远看轮廓相同
- 两段 DOM 各自计算圆角,连接点的斜率没有对齐
- 独立边框在 P3 / P0 收边,半像素处暴露缺口和锯齿
外角和内角连成一个整体
轮廓连续- 一个元素画完整轮廓,曲线会平滑地接进下一段
- P3 与 P0 属于同一路径,背景和边框只收边一次
三次贝塞尔
CUBIC · P0 → P1 → P2 → P3
蓝色为正在编辑的曲线
SELECTION OVERLAY
锚点
01 · P0 / P3
两个实心节点定义曲线的起点与终点。
控制点
02 · P1 / P2
两个空心节点控制进入方向与曲线张力。
控制柄与相切
03 · HANDLE
每段曲线的两端各有一根;锚点连接两段曲线时,才会显示两侧手柄。
沿轮廓观察 · FOLLOW THE EDGE
接得上,方向顺,转弯才会自然
相邻线段先在同一位置相遇,进入与离开沿着同一条切线,转弯速度也不要在接缝处突然变化。
端点决定曲线从哪里开始、在哪里结束,控制柄决定它怎样进入和离开。控制柄短,凹角会更快转向;控制柄变长,曲线会沿着直线多走一段。可以先画一个四分之一圆,再根据缺口大小、卡片比例和旁边的元素慢慢调整。
这套判断也适用于多个 DOM。元素可以拆开,视觉轮廓仍要像一条曲线连续经过它们。后面看到头像包角、Notch Bar 和 Tabs 时,都可以先找端点、切线与曲率,再看它们用了哪一种 CSS。
04用 CSS 实现
用 CSS 画出会跟着卡片伸缩的缺口
先从改动最小的情况开始。如果四条直边还在原位,只想改变矩形的四个角,corner-shape 已经提供 round、bevel、scoop、notch、squircle 与 superellipse()。四个角还可以分别设置,目标能由内置形状完成时,不需要手写整条路径。
当缺口离开角落、进入一条边,或轮廓已经不再是矩形时,再使用 shape()。会伸展的直线写成百分比,缺口尺寸、内外半径与控制柄长度保留为 CSS 变量;卡片宽度改变时,直线段重新计算,刚才学到的端点和切线关系仍然保留。
corner-shape
内置角形状corner-shape: scoop
向角落内部舀出一段圆弧。
只改变右上角的 radius 区域
border-shape
自定义轮廓SINGLE NOTCH
把缺口移到边上,净空尺寸与曲线进出可以分别调整。
一条路径同时绘制直线、外角与内凹
corner-shape只改四个角
四条边仍是矩形,直接选内置形状。
border-shape完整轮廓改变
缺口进入边上,背景和边框沿同一路径绘制。
mask / rounded-out多个元素相接
只补一小段接缝,让现有 DOM 结构继续工作。
轮廓进入边缘以后,还要决定它只裁切填充,还是让背景与边框一起服从新边界。clip-path 与 border-shape 可以使用同一条 shape(),但承担的绘制范围不同。
ORDINARY DOM
内容照常留在 DOM 里
border 仍按原来的矩形盒子绘制,再被轮廓裁掉。缺口内壁没有一条完整、连续的边框。
ORDINARY DOM
内容照常留在 DOM 里
同一条 shape() 同时描述背景与边框边界,凹面、外角和直线段可以形成连续轮廓。
05明确绘制责任
多元素接缝和单元素轮廓,分别由谁来画
先看真实 DOM 结构。多元素接缝可以让相邻元素用伪元素或 mask 补出局部曲线;单元素内凹卡片则由自身的 border-shape: shape() 定义完整轮廓,没有嵌入元素。下面把两种绘制责任放在一起比较。
01 · 多元素拼接
局部补出曲线
上方标签与下方卡片是两个元素。标签通过伪元素或 mask 在自身盒模型外补出紫色曲面,与卡片背景拼成局部接缝。
02 · 绘制结果
border-shape
border-shape: shape() 直接改写这个卡片元素的完整边界。背景和 border 都沿同一条路径绘制,内凹曲线不属于其他元素。
两种实现
多元素补局部接缝 / 单元素画完整轮廓
左侧的曲线属于标签的补面;右侧没有嵌入元素,整条可见边界由卡片自己的 border-shape 一次画完。两者外观可以相似,但 DOM 结构和绘制责任不同。
左侧是多元素方案:标签用伪元素或 mask 补出两侧曲线,再与卡片拼接。右侧是单元素方案:卡片自身的 border-shape 定义完整边界,背景和边框都沿这条路径绘制,不存在嵌入元素。
免费部分到这里
继续完成内凹圆角的实现与调试
免费部分已经讲清怎样判断曲线、怎样用 CSS 画轮廓,以及多元素接缝与单元素 border-shape 的绘制责任。解锁后可以继续选择实现方法、整理参数、复制完整代码,并用 Corner Inverter 直接调试。
解锁后从这里继续,前面的公开内容始终可以回来阅读。
学习进度
正在读取你的学习记录…