1. 引言
本规范扩展了 CSS 背景与边框模块 3 级 [CSS3BG] 中与边框和盒子装饰相关的部分。目前是差异规范;有关边框和盒子装饰的其他特性,请参见 [CSS3BG]。
本规范详细说明了新增的 corner-*-shape 及 border-shape 属性,以及 border-*-radius、box-shadow-* 长属性的逻辑速记写法,以及通过 border-limit 和 border-*-clip 属性实现的部分边框。
2. 边框
边框可以是预定义样式(实线、双线、点状线、伪3D边框等),也可以是图片。前者通过不同属性定义其样式(border-style)、颜色(border-color)和粗细(border-width)。
2.1. 线条颜色:border-color 属性
| 名称: | border-top-color, border-right-color, border-bottom-color, border-left-color, border-block-start-color, border-block-end-color, border-inline-start-color, border-inline-end-color |
|---|---|
| 值: | <color> | <image-1D> |
| 初始值: | currentcolor |
| 适用元素: | 除 ruby base containers 和 ruby annotation containers 外的所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 已计算的颜色和/或一维图片函数 |
| 规范顺序: | 遵循语法 |
| 动画类型: | 见正文 |
| 逻辑属性组: | border-color |
| 名称: | border-color |
|---|---|
| 值: | [ <color> | <image-1D> ]{1,4} |
| 初始值: | 见单独属性 |
| 适用元素: | 见单独属性 |
| 继承性: | 见单独属性 |
| 百分比: | 见单独属性 |
| 计算值: | 见单独属性 |
| 动画类型: | 见单独属性 |
| 规范顺序: | 遵循语法 |
这些属性设置由 border-style 属性指定的边框前景色。
由 <image-1D> 定义的条纹会沿其所应用侧的边框形状绘制,并以自 内边距边缘 向外的方式分带绘制。每一点的边框宽度决定了该点条纹的 总宽度。
.foo{ border : 30 px solid; border-color : stripes ( dodgerblue, skyblue) stripes ( yellow, gold) stripes ( lightgreen, limegreen) stripes ( indianred, orange); }
示例渲染:
同样的边框颜色搭配 border-style: dotted 效果:

border-color 是四个 border-*-color 属性的速记写法。四个值分别设置上、右、下、左边框颜色。缺少的 left 取 right 的值,缺少的 bottom 取 top 的值,缺少的 right 也取 top 的值。每个列表项分别解析。
流向相关属性 border-block-start-color、border-block-end-color、border-inline-start-color 和 border-inline-end-color 分别对应 物理属性 border-top-color、border-bottom-color、border-left-color 和 border-right-color。映射关系取决于元素的 writing-mode、direction 和 text-orientation。
| 名称: | border-block-color, border-inline-color |
|---|---|
| 值: | <'border-top-color'>{1,2} |
| 初始值: | 见单独属性 |
| 适用元素: | 见单独属性 |
| 继承性: | 见单独属性 |
| 百分比: | 见单独属性 |
| 计算值: | 见单独属性 |
| 动画类型: | 见单独属性 |
| 规范顺序: | 遵循语法 |
这两个 速记属性分别设置 border-block-start-color & border-block-end-color 和 border-inline-start-color & border-inline-end-color。第一个值表示 start 边颜色,第二个值表示 end 边颜色。如果只指定一个值,则同时应用于 start 和 end 边。
2.2. 线条样式:border-style 属性
| 名称: | border-top-style, border-right-style, border-bottom-style, border-left-style, border-block-start-style, border-block-end-style, border-inline-start-style, border-inline-end-style |
|---|---|
| 值: | <line-style> |
| 初始值: | none |
| 适用元素: | 除 ruby base containers 和 ruby annotation containers 外的所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 指定的关键字 |
| 规范顺序: | 遵循语法 |
| 动画类型: | 离散 |
| 逻辑属性组: | border-style |
流向相关属性 border-block-start-style、border-block-end-style、border-inline-start-style 和 border-inline-end-style 分别对应 物理属性 border-top-style、border-bottom-style、border-left-style 和 border-right-style。映射关系取决于元素的 writing-mode、direction 和 text-orientation。
| 名称: | border-block-style, border-inline-style |
|---|---|
| 值: | <'border-top-style'>{1,2} |
| 初始值: | 见单独属性 |
| 适用元素: | 见单独属性 |
| 继承性: | 见单独属性 |
| 百分比: | 见单独属性 |
| 计算值: | 见单独属性 |
| 动画类型: | 见单独属性 |
| 规范顺序: | 遵循语法 |
这两个 速记属性分别设置 border-block-start-style & border-block-end-style 和 border-inline-start-style & border-inline-end-style。第一个值表示 start 边样式,第二个值表示 end 边样式。如果只指定一个值,则同时应用于 start 和 end 边。
2.3. 线条粗细:border-width 属性
| 名称: | border-top-width, border-right-width, border-bottom-width, border-left-width, border-block-start-width, border-block-end-width, border-inline-start-width, border-inline-end-width |
|---|---|
| 值: | <line-width> |
| 初始值: | medium |
| 适用元素: | 除 ruby 基础容器 和 ruby 注释容器 外的所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 绝对长度,作为边框宽度对齐;若边框样式为 none 或 时为零 |
| 规范顺序: | 遵循语法 |
| 动画类型: | 按计算值 |
| 逻辑属性组: | border-width |
流向相关属性 border-block-start-width、border-block-end-width、border-inline-start-width 和 border-inline-end-width 分别对应 物理属性 border-top-width、border-bottom-width、border-left-width 和 border-right-width。映射关系取决于元素的 writing-mode、direction 和 text-orientation。
| 名称: | border-block-width, border-inline-width |
|---|---|
| 值: | <'border-top-width'>{1,2} |
| 初始值: | 见单独属性 |
| 适用元素: | 见单独属性 |
| 继承性: | 见单独属性 |
| 百分比: | 见单独属性 |
| 计算值: | 见单独属性 |
| 动画类型: | 见单独属性 |
| 规范顺序: | 遵循语法 |
这两个 速记属性分别设置 border-block-start-width & border-block-end-width 和 border-inline-start-width & border-inline-end-width。第一个值表示 start 边宽,第二个值表示 end 边宽。如果只指定一个值,则同时应用于 start 和 end 边。
2.4. 边框速记属性
| 名称: | border-top, border-right, border-bottom, border-left, border-block-start, border-block-end, border-inline-start, border-inline-end |
|---|---|
| 值: | <line-width> || <line-style> || <color> |
| 初始值: | 见单独属性 |
| 适用元素: | 除 ruby 基础容器 和 ruby 注释容器 外的所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 见单独属性 |
| 动画类型: | 见单独属性 |
| 规范顺序: | 遵循语法 |
流向相关属性 border-block-start、border-block-end、border-inline-start 和 border-inline-end 分别对应 物理 属性 border-top、border-bottom、border-left 和 border-right。映射关系取决于元素的 writing-mode、direction 和 text-orientation。
| 名称: | border-block, border-inline |
|---|---|
| 值: | <'border-block-start'> |
| 初始值: | 见单独属性 |
| 适用元素: | 见单独属性 |
| 继承性: | 见单独属性 |
| 百分比: | 见单独属性 |
| 计算值: | 见单独属性 |
| 动画类型: | 见单独属性 |
| 规范顺序: | 遵循语法 |
这两个 速记属性分别将 border-block-start 和 border-block-end 或 border-inline-start 和 border-inline-end 均设置为相同样式。
3. 圆角
3.1. 圆角尺寸:border-*-*-radius 属性
| 名称: | border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-start-start-radius, border-start-end-radius, border-end-start-radius, border-end-end-radius |
|---|---|
| 值: | <length-percentage [0,∞]>{1,2} |
| 初始值: | 0 |
| 适用元素: | 所有元素(但见正文说明) |
| 继承性: | no |
| 百分比: | 参考 border box 的对应维度 |
| 计算值: | 一对已计算的 <length-percentage> 值 |
| 规范顺序: | 遵循语法 |
| 动画类型: | 按计算值 |
| 逻辑属性组: | border-radius |
流向相关属性 border-start-start-radius、border-start-end-radius、border-end-start-radius 和 border-end-end-radius 分别对应 物理属性 border-top-left-radius、border-bottom-left-radius、border-top-right-radius 和 border-bottom-right-radius。映射关系取决于元素的 writing-mode、direction 和 text-orientation,第一个 start/end 为块轴侧,第二个为行内轴侧(即 'border-block-inline-radius' 形式)。
3.2. 圆角尺寸速记:border-radius 和 border-*-radius 速记属性
3.2.1. 单侧圆角尺寸: border-top-radius、border-right-radius、border-bottom-radius、border-left-radius、border-block-start-radius、border-block-end-radius、border-inline-start-radius、border-inline-end-radius 速记
| 名称: | border-top-radius, border-right-radius, border-bottom-radius, border-left-radius, border-block-start-radius, border-block-end-radius, border-inline-start-radius, border-inline-end-radius |
|---|---|
| 值: | <length-percentage [0,∞]>{1,2} [ / <length-percentage [0,∞]>{1,2} ]? |
| 初始值: | 0 |
| 适用元素: | 所有元素(但见正文说明) |
| 继承性: | no |
| 百分比: | 参考 border box 的对应维度 |
| 计算值: | 见单独属性 |
| 规范顺序: | 遵循语法 |
| 动画类型: | 见单独属性 |
border-*-radius 速记设置相关边的两个 border-*-*-radius 长属性。如果斜杠前后都给定了值,则斜杠前的值设置水平半径,斜杠后的值设置垂直半径。如果没有斜杠,则该值同时设置两个半径。半径的两个值顺序如下: border-top-radius:左上、右上, border-right-radius:右上、右下, border-bottom-radius:左下、右下, border-left-radius:左上、左下, border-block-start-radius:start-start、start-end, border-block-end-radius:end-start、end-end, border-inline-start-radius:start-start、end-start, border-inline-end-radius:start-end、end-end。 如果省略第二个值,则复制第一个值。
3.2.2. 一次性设置所有圆角尺寸: border-radius 速记
| 名称: | border-radius |
|---|---|
| 值: | <length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]? |
| 初始值: | 0 |
| 适用元素: | 所有元素,除了 border-collapse 为 collapse 的 table 元素 |
| 继承性: | no |
| 百分比: | n/a |
| 计算值: | 按指定 |
| 规范顺序: | 遵循语法 |
| 动画类型: | 见单独属性 |
参见 [CSS3BG]。
3.3. 圆角形状:corner-shape 属性
默认情况下,非零的 border-radius 值定义了一个四分之一椭圆的 圆角形状,用于圆滑处理受影响的角,并填充由该角 border-radius 定义的 圆角区域。 但在某些情况下,可能需要其他 圆角形状。 corner-shape 属性(及其长属性)可精确指定盒子在其 border-radius 区域内使用的 圆角形状。
不同的 圆角形状 都可以用 超椭圆 的不同参数表达。 超椭圆是椭圆的广义形式,根据其 `k` 参数可以表现出方形、椭圆和缺口之间的所有形状。
超椭圆如何工作?
单位圆由以下方程定义:
满足该方程的所有点 (x,y) 构成圆。通过在 X 和/或 Y 轴缩放该形状可得到椭圆。
单位超椭圆方程只需将指数 2 替换为变量。 在本规范中用 2K 表示:
该方程中的 K 是 superellipse() 的参数。
K 可以为任意值; K 为 1 时就是常见的圆/椭圆方程, 其它值可定义整个超椭圆曲线族:
-
大于 1 的值更“方”:传统的“squircle”用 K 为 2,无穷大为完美正方形。 (K 仅为 10 时已经几乎与正方形无异;增长非常快。)
-
0 和 1 之间的值让其变得“扁平”;K 为 0 时就是一颗边完全平直的菱形。
-
负值定义凹曲线,是正值的“反转”:K 为 -1 时是近似椭圆的“凹角”,与 K 为 1 的曲线大致相反; K 为 -2 时是“凹squircle”,负无穷大为凹正方形,等等。
(注意,绝大多数超椭圆相关文献用更简单的 指数。 这里采用 形式, 是为了便于参数区间统一处理:所有值都是合法的,正负对称,0 为中间态(斜切),等等。)
为便于完整表达和插值, corner-shape 属性可直接通过 superellipse() 函数传参, 或使用预设关键字表示常用参数。 详情见 <corner-shape-value> 定义。
3.3.1. corner-shape 速记
| 名称: | corner-shape |
|---|---|
| 值: | <corner-shape-value>{1,4} |
| 初始值: | round |
| 适用元素: | 所有可应用 border-radius 的元素 |
| 继承性: | no |
| 百分比: | 见单独属性 |
| 计算值: | 见单独属性 |
| 动画类型: | 见单独属性 |
| 规范顺序: | 遵循语法 |
corner-shape 属性用来指定盒子的圆角形状,仅作用于由 border-radius 所定义的区域内。
<corner-shape-value> = round | scoop | bevel | notch | square | squircle |
<superellipse()>
superellipse() = superellipse(<number [-∞,∞]> | infinity | -infinity)
- round
-
圆角形状为凸椭圆的四分之一。
等价于 superellipse(1)。
注: 这是 corner-shape 属性的初始值, 也是 border-radius 未有 corner-shape 属性前的默认行为。
- squircle
- 圆角形状为“squircle”的四分之一,即介于 round 和 square 之间的凸曲线。 等价于 superellipse(2)。
- square
-
圆角形状为凸的90度直角。
等价于 superellipse(infinity)。
注: 这与 border-radius: 0 的“正常”直角效果一样, 但可与其他 corner-shape 值平滑过渡动画。
- bevel
- 圆角形状为一条直对角线,不凸也不凹。 等价于 superellipse(0)。
- scoop
- 圆角形状为凹的四分之一椭圆。等价于 superellipse(-1)。
- notch
- 圆角形状为凹的90度直角。等价于 superellipse(-infinity)。
- superellipse(K)
-
圆角形状为超椭圆的四分之一。
参数 K 是 超椭圆参数,
用 2K 为指数定义超椭圆。
具体数学定义和 K 的意义参见 § 3.3 圆角形状:corner-shape 属性 注释。 超椭圆的精确计算和绘制见 § 3.3.3 圆角形状渲染。
注: 若 border-radius 未指定 (或为 0), 圆角区域 也为零大小, corner-shape 不会产生效果。
corner-shape 并不改变 overflow 对 border-radius 的裁剪规则, 除非改变了圆角形状; 元素仍然会按新的边框形状裁剪。
corner-shape 所指定的曲线定义边框的外边缘。 内边缘会跟随外边缘曲线 (但未必是超椭圆曲线), 并与外边缘保持几乎恒定的距离 (如两条边的 border-width 不一致,则距离线性变化)。
corner-shape 也会影响 box-shadow 的渲染,以及 overflow clip edge 扩展时的形状,但它们并非直接沿用 corner-shape 路径,而是轴对齐缩放该路径。
3.3.2. corner-*-shape 速记与长属性
| 名称: | corner-top-left-shape, corner-top-right-shape, corner-bottom-right-shape, corner-bottom-left-shape, corner-start-start-shape, corner-start-end-shape, corner-end-start-shape, corner-end-end-shape |
|---|---|
| 值: | <corner-shape-value> |
| 初始值: | round |
| 适用元素: | 所有可应用 border-radius 的元素 |
| 继承性: | no |
| 百分比: | n/a |
| 计算值: | 对应的 superellipse() 值 |
| 规范顺序: | 遵循语法 |
| 动画类型: | 见 superellipse 插值 |
| 逻辑属性组: | corner-shape |
corner-*-*-shape 长属性用于设置指定角的圆角形状。
流向相关长属性 (如 corner-start-start-shape 等) 会根据元素的 writing-mode、direction 和 text-orientation 对应到 物理长属性 (如 corner-top-left-shape 等)。 第一个 start/end 表示块轴侧,第二个表示行内轴侧 (即 corner-block-inline-shape 形式)。
| 名称: | corner-top-shape, corner-right-shape, corner-bottom-shape, corner-left-shape, corner-block-start-shape, corner-block-end-shape, corner-inline-start-shape, corner-inline-end-shape |
|---|---|
| 值: | <corner-shape-value>{1,2} |
| 初始值: | 见单独属性 |
| 适用元素: | 见单独属性 |
| 继承性: | 见单独属性 |
| 百分比: | 见单独属性 |
| 计算值: | 见单独属性 |
| 动画类型: | 见单独属性 |
| 规范顺序: | 遵循语法 |
corner-*-shape/等速记设置相关边的两个 corner-*-*-shape 属性。 只给一个值时,第二个值与第一个相同。
对于物理速记(如 corner-top-shape 等), 值为左/右或上/下顺序,具体取决于属性所在的轴。 即 corner-top-shape: round square 相当于 corner-top-left-shape: round; corner-top-right-shape: square;。
对于逻辑速记(如 corner-block-start-shape 等), 值始终为另一轴的 start/end 顺序。 即 corner-block-start-shape: round square 相当于 corner-start-start-shape: round; corner-start-end-shape: square;。
3.3.3. 渲染 corner-shape
当渲染具有特殊圆角的元素时,元素的路径需要根据 边框、轮廓、box-shadow、overflow-clip-margin 等进行偏移。
渲染边框或轮廓时,偏移是沿着元素形状的曲线对齐的;而渲染 box-shadow 或对 overflow-clip-margin 做偏移时,偏移则是沿轴对齐的。
元素 element 的 外轮廓 是给定 element 和 element 的 边框边缘 的 边框轮廓路径。
元素 element 的 内轮廓 是给定 element 和 element 的 边框轮廓路径,以及 内边距边缘。
元素 的 轮廓 跟随 外轮廓,并使用 使用值的 outline-width 及 outline-offset。其具体渲染方式由实现决定。
元素 的 overflow 区域由其 内轮廓 形状决定。 元素 的 overflow 剪裁边缘 则由 边框轮廓路径(给定 element、element 的 内边距边缘 和 element 的 使用值 overflow-clip-margin)决定。
每一个 元素 的 box-shadow 阴影都由 边框轮廓路径(给定 element、element 的 边框边缘 及阴影的 使用值 box-shadow-spread)确定其形状。
-
令 outerLeft、outerTop、outerRight、outerBottom 为 element 的 未变形 边框边缘。
-
令 topLeftHorizontalRadius、topLeftVericalRadius、topRightHorizontalRadius、topRightVerticalRadius、bottomRightHorizontalRadius、bottomRightVerticalRadius、bottomLeftHorizontalRadius 和 bottomLeftVerticalRadius 为 element 边框边缘的半径,按 element 的 对角圆角缩放因子 缩放。
-
令 topLeftShape、topRightShape、bottomRightShape、bottomLeftShape 为 element 的 最终计算 corner-*-shape 值。
-
令 targetLeft、targetTop、targetRight、targetBottom 为 未变形 targetEdge。
-
令 path 为新路径 [SVG2]。
-
对 path,添加圆角到路径,参数为: 矩形
(outerRight - topRightHorizontalRadius, outerTop, topRightHorizontalRadius, topRightVerticalRadius), targetEdge, 0, targetTop - outerTop, outerRight - targetRight, topRightShape。 -
对 path,添加圆角到路径,参数为: 矩形
(outerRight - bottomRightHorizontalRadius, outerBottom - bottomRightVerticalRadius, bottomRightHorizontalRadius, bottomRightVerticalRadius), targetEdge, 1, outerRight - targetRight, outerBottom - targetBottom, bottomRightShape。 -
对 path,添加圆角到路径,参数为: 矩形
(outerLeft, outerBottom - bottomLeftVerticalRadius, bottomLeftHorizontalRadius, bottomLeftVerticalRadius), targetEdge, 2, outerBottom - targetBottom, targetLeft - outerLeft, bottomLeftShape。 -
对 path,添加圆角到路径,参数为: 矩形
(outerLeft, outerTop, topLeftHorizontalRadius, topLeftVericalRadius), targetEdge, 3, targetLeft - outerLeft, targetTop - outerTop, topLeftShape。 -
如果 spread 不为 0,则:
-
按
1 + (spread * 2) / (targetEdge 的 宽度), 1 + (spread * 2) / (targetEdge 的 高度)缩放 path。 -
将 path 平移
-spread, -spread。
注: 这样会让结果路径与原路径形状一致,仅缩放以适应 spread。
-
-
返回 path。
要 添加圆角到路径,参数为 path path,矩形 cornerRect,矩形 trimRect, 以及数字 orientation、startThickness、endThickness、curvature:
-
如果 cornerRect 为空,或 curvature 为 ∞:
-
令 innerQuad 为 trimRect 的 顺时针四边形。
-
延展 path,画线到 innerQuad[
(orienation + 1) % 4]。 -
返回。
-
-
令 cornerQuad 为 cornerRect 的 顺时针四边形。
-
如果 curvature 为 -∞:
-
延展 path,画线从 cornerQuad[0] 到 cornerQuad[3],并修剪于 trimRect。
-
延展 path,画线从 cornerQuad[3] 到 cornerQuad[2],并修剪于 trimRect。
-
返回。
-
-
令 clampedNormalizedHalfCorner 为 归一化超椭圆半角(传入
clamp(curvature, -1, 1))。 -
令 equivalentQuadraticControlPointX 为
clampedNormalizedHalfCorner * 2 - 0.5。 -
令 curveStartPoint 为 对齐圆角点(参数 cornerQuad[orienation]、向量 (equivalentQuadraticControlPointX,
1 - equivalentQuadraticControlPointX)、startThickness、orientation + 1)。 -
令 curveEndPoint 为 对齐圆角点(参数 cornerQuad[(orientation + 2) % 4]、向量 (
equivalentQuadraticControlPointX - 1,-equivalentQuadraticControlPointX)、endThickness、orientation + 3)。 -
令 alignedCornerRect 为包含 curveStartPoint 和 curveEndPoint 的 矩形。
-
令 projectionToCornerRect 为 变换矩阵,依次进行如下操作: 平移
(alignedCornerRect 的 x 坐标, alignedCornerRect 的 y 坐标), 缩放(alignedCornerRect 的 宽度, alignedCornerRect 的 高度), 再平移(0.5, 0.5), 旋转90deg * orientation, 最后平移(-0.5, -0.5)。 -
令 K 为
0.5abs(curvature)。 -
对 0 到 1 之间每个 T:
-
令 A 为
TK。 -
令 B 为
1 - (1 - T)K。 -
令 normalizedPoint 为
(A, B)(若 curvature 为正),否则(B, A)。 -
令 absolutePoint 为 normalizedPoint,经过 projectionToCornerRect 变换。
-
如果 absolutePoint 在 trimRect 内,则延展 path,经过 absolutePoint。
注: 用户代理可以近似该算法,例如使用拼接 Bezier 曲线,以平衡性能与渲染精度。
-
要计算 对齐圆角点,参数为点 originalPoint、二维向量 offsetFromControlPoint、数字 thickness、数字 orientation:
-
令 length 为
hypot(offsetFromControlPoint.x, offsetFromControlPoint.y)。 -
将 offsetFromControlPoint 旋转
90deg * orientation,并缩放 thickness。 -
将 originalPoint 平移
offsetFromControlPoint.x / length, offsetFromControlPoint.y / length, 并返回。
顺时针四边形,给定 矩形 rect,是一个 四边形,其点为 (rect 的 x 坐标, rect 的 y 坐标), (rect 的 x 坐标 + rect 的 宽度, rect 的 y 坐标), (rect 的 x 坐标 + rect 的 宽度, rect 的 y 坐标 + rect 的 高度), (rect 的 x 坐标, rect 的 y 坐标 + rect 的 高度).
3.3.4. 约束对角半径
当存在凹形 corner-shape 值时(superellipse 参数为负),对角线相对的圆角可能会相互重叠。
下例如果不约束会产生重叠圆角。
div{ corner-shape : scoop; border-top-left-radius : 80 % ; border-bottom-right-radius : 80 % ; }
为防止这种情况,会对四个半径进行约束以避免重叠。做法是为每对对角圆角计算外壳多边形,找到一个最大缩放因子,使得同时作用于两圆角时,这两个多边形不会相交。
-
令 rect 为 element 的 border box。
-
令 topRightHull 为 归一化内圆角外壳,参数为 element 的 最终计算 corner-top-right-shape, 映射到矩形 (rect 的 宽度 - element 的 最终计算 水平 border-top-right-radius, 0, rect 的 最终计算 border-top-right-radius)。
-
令 bottomRightHull 为 归一化内圆角外壳,参数为 element 的 最终计算 corner-bottom-right-shape, 以 (0.5, 0.5) 为原点旋转 90 度,映射到矩形 (rect 的 宽度 - element 的 最终计算 水平 border-bottom-right-radius, rect 的 高度 - element 的 最终计算 垂直 border-bottom-right-radius, element 的 最终计算 border-bottom-right-radius)。
-
令 bottomLeftHull 为 归一化内圆角外壳,参数为 element 的 最终计算 corner-bottom-right-shape, 以 (0.5, 0.5) 为原点旋转 180 度,映射到 (0, rect 的 高度 - element 的 最终计算 垂直 border-bottom-left-radius, element 的 最终计算 border-bottom-left-radius)。
-
令 topLeftHull 为 归一化内圆角外壳,参数为 element 的 最终计算 corner-top-left-shape, 以 (0.5, 0.5) 为原点旋转 270 度,映射到 (0, 0, element 的 最终计算 border-top-left-radius)。
-
令 scaleFactorA 为最大数,使得 topLeftHull 和 bottomRightHull 同时以各自第一个点为原点缩放时,两多边形不会相交。
-
令 scaleFactorB 为最大数,使得 topRightHull 和 bottomLeftHull 同时以各自第一个点为原点缩放时,两多边形不会相交。
-
返回
min(1, scaleFactorA, scaleFactorB)。
3.3.5. 圆角形状插值
由于<corner-shape-value>总可以用带有superellipse()的superellipse
参数变量来表示,所以在插值两个<corner-shape-value>时,就是插值
superellipse 参数本身。
由于这里用到了log2,如果线性插值,会导致凹形圆角的插值速度远大于凸形圆角。
为了平衡,superellipse
插值公式描述了如何将superellipse 参数转换为 0 到 1
之间的值,以及逆向转换的方法:
- -∞
-
返回 0。
- ∞
-
返回 1。
- 其他
-
-
令 k =
0.5abs(s)。 -
令 convexHalfCorner =
0.5k。 -
如果 s 小于 0,返回
1 - convexHalfCorner。 -
返回 convexHalfCorner。
-
-
如果 curvature 大于等于 0,返回三角形 « (1, 1), (1, 0), (0, 1) »。
-
令 axisLineA 为连接
(1, 0)和(1, 1)的直线。 -
令 axisLineB 为连接
(0, 1)和(1, 1)的直线。 -
令 normalizedHalfCorner 为归一化超椭圆半角,参数为 curvature。
-
令 halfCornerPoint =
(normalizedHalfCorner, 1 - normalizedHalfCorner)。 -
令 lineFromCenterToHalfCorner 为连接
(0, 0)和 halfCornerPoint 的直线。 -
令 tangentLine 为 halfCornerPoint 处,垂直于 lineFromCenterToHalfCorner 的直线。
-
令 intersectionA 为 axisLineA 与 tangentLine 的交点。
-
令 intersectionB 为 axisLineB 与 tangentLine 的交点。
-
返回五边形,顶点依次为 « (1, 1), (1, 0), intersectionA, intersectionB, (0, 1), (1, 1) »。
要将 superellipse 参数 s 插值为 0 到 1 之间的值,返回归一化超椭圆半角,参数为 s。
- 0
-
返回 -∞。
- 0.5
-
返回 0。
- 1
-
返回 ∞。
- 其他
-
-
令 convexHalfCorner = interpolationValue。
-
如果 interpolationValue 小于 0.5,则 convexHalfCorner 设为 1 - interpolationValue。
-
令 k =
ln(0.5) / ln(convexHalfCorner)。 -
令 s =
log2(k)。 -
如果 interpolationValue 小于 0.5,返回 -s。
-
返回 s。
-
3.4. 圆角形状速记:corners 属性
该属性的具体名称和语法待定。[Issue #11623]
4. 部分边框
尚未准备好实现
本节尚未准备好实现,仅记录想法并促进讨论。
在尝试实现本节内容前,请联系 CSSWG(www-style@w3.org)。
CSS 边框通常会覆盖整个边框边缘。但有时,隐藏边框的某些部分会更有用。
这里有两种提案: 第二种来自 GCPM,第一种尝试让其更易读。命名很糟糕,已知问题,欢迎提案。 把此问题当作裁剪来看是不合适的:如果是点状边框,应始终保留完整点,而不是点的一部分。 因此应是绘制限制而不是裁剪。
4.1. 部分边框:border-limit 属性
| 名称: | border-limit |
|---|---|
| 值: | all | [ sides | corners ] <length-percentage [0,∞]>? | [ top | right | bottom | left ] <length-percentage [0,∞]> |
| 初始值: | all |
| 适用元素: | 所有元素,除了 border-collapse 为 collapse 的 table 元素 |
| 继承性: | no |
| 百分比: | 相对于 border-box |
| 计算值: | 按指定 |
| 规范顺序: | 遵循语法 |
| 动画类型: | 离散 |
默认情况下,将绘制整个边框。不过,边框渲染可以仅限于部分边框。关键字指定哪一部分,长度或百分比则指定具体范围。
- all
- 绘制整个边框。
- sides
- 仅绘制边,不包含圆角(由圆角半径定义)。长度或百分比从每条边的中心开始测量:50% 绘制边的中间 50%;默认绘制整个边。
- corners
- 绘制圆角及指定距离内的边。长度从圆角区域最近的边缘测量,百分比从 border box 的绝对圆角处测量。
- left
- right
- 对于左侧和右侧(垂直)边,绘制整个边及圆角。对于上侧和下侧(水平)边,绘制指定的左/右部分。距离测量方式同corners。
- top
- bottom
- 对于上侧和下侧(水平)边,绘制整个边及圆角。对于左侧和右侧(垂直)边,绘制指定的上/下部分。距离测量方式同corners。
4.2. border-clip 属性
| 名称: | border-clip, border-clip-top, border-clip-right, border-clip-bottom, border-clip-left |
|---|---|
| 值: | normal | [ <length-percentage [0,∞]> | <flex> ]+ |
| 初始值: | normal |
| 适用元素: | 所有元素 |
| 继承性: | no |
| 百分比: | 参考边框边长度 |
| 计算值: | normal,或由绝对长度或指定百分比组成的列表 |
| 规范顺序: | 遵循语法 |
| 动画类型: | 按计算值 |
这些属性将各自的边框沿边框边拆分为若干部分。第一个部分可见,第二个不可见,第三个可见,依此类推。每个部分可以用长度、百分比或弹性长度表示(fr 单位,见 [CSS3GRID])。 normal 表示不拆分,正常显示边框。
border-clip 是这四个独立属性的速记写法。
如果指定部分比边框短,剩余边框会按指定弹性长度比例分配。如果没有弹性长度,则相当于末尾加 1fr。
如果指定部分比边框长,则显示到边框末尾为止,所有弹性长度为零。
对于水平边框,部分从左到右排列;对于垂直边框,从上到下排列。
具体边框部分的确定方法为:先将所有弹性长度设为零,布局指定部分,剩余长度按弹性长度比例分配。
border-clip-top: 10px 1fr 10px; border-clip-bottom: 10px 1fr 10px; border-clip-right: 5px 1fr 5px; border-clip-left: 5px 1fr 5px;
让第一个部分长度为 0,可以很容易地实现上例的反向边框:
border-clip-top: 0 10px 1fr 10px; border-clip-bottom: 0 10px 1fr 10px; border-clip-right: 0 5px 1fr 5px; border-clip-left: 0 5px 1fr 5px;
border: thin solid black; border-clip: 0 1fr; /* 隐藏边框 */ border-clip-top: 10px 1fr 10px; /* 仅显示部分边框 */ border-clip-bottom: 10px 1fr 10px;
border-top: thin solid black; border-bottom: thin solid black; border-clip-top: 10px; border-clip-bottom: 10px;
如下渲染:
A sentence consists of words¹.
¹ Most often.
@footnote {
border-top: thin solid black;
border-clip: 4em;
}
border: 4px solid black; border-clip-top: 40px 20px 0 1fr 20px 20px 0 1fr 40px;
本例中,顶部边框两端各有 40px 可见边框,内部有至少 20px 的不可见边框。在这些不可见部分之间,是 20px 可见边框和 20px 不可见边框交替。
红色为示意,实际合规 UA 不应显示。
border: 4px solid black; border-clip-top: 3fr 10px 2fr 10px 1fr 10px 10px 10px 1fr 10px 2fr 10px 3fr;
本例除了一个可见边框部分,其他都是弹性长度。随着元素宽度变化,这些边框部分长度也会变化。下面是 1fr = 10px 时的渲染:
下面是 1fr = 30px 时的渲染:
红色为示意,实际合规 UA 应为黑色。
5. 投影阴影
5.1. 阴影着色:box-shadow-color 属性
| 名称: | box-shadow-color |
|---|---|
| 值: | <color># |
| 初始值: | currentcolor |
| 适用元素: | 所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 列表,每项为已计算颜色 |
| 规范顺序: | 按语法顺序 |
| 动画类型: | 按计算值 |
box-shadow-color 属性定义一个或多个投影阴影的颜色。 该属性接受逗号分隔的多个阴影颜色。
关于 box-shadow-color 如何与其他逗号分隔的阴影属性共同形成每一层阴影,详见 “图层、布局和其他细节”。
5.2. 阴影偏移:box-shadow-offset 属性
| 名称: | box-shadow-offset |
|---|---|
| 值: | [ none | <length>{2} ]# |
| 初始值: | none |
| 适用元素: | 所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 列表,每项为 none 或一对从元素盒子出发的水平、垂直偏移 |
| 规范顺序: | 按语法顺序 |
| 动画类型: | 按计算值, 当与非 none 插值时,将 none 视为 0 0 |
box-shadow-offset 属性定义一个或多个投影阴影的偏移量。 接受逗号分隔的列表。 每项可以是 none, 表示无阴影,或是一对水平和垂直偏移,二者均为 <length>。
- none
- 阴影不被渲染。 该阴影对应的其他 box-shadow 属性值无效。
- 第1个 <length>
- 指定阴影的水平偏移。 正值向右偏移,负值向左偏移。
- 第2个 <length>
- 指定阴影的垂直偏移。 正值阴影向下偏移,负值向上。
关于 “图层、布局和其他细节” 中 box-shadow-offset 如何与其他逗号分隔的阴影属性共同形成每一层阴影的详细说明。
5.3. 阴影模糊:box-shadow-blur 属性
| 名称: | box-shadow-blur |
|---|---|
| 值: | <length [0,∞]># |
| 初始值: | 0 |
| 适用元素: | 所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 列表,每项为<length> |
| 规范顺序: | 按语法顺序 |
| 动画类型: | 按计算值 |
box-shadow-blur 属性定义一个或多个阴影的模糊半径。 该属性接受逗号分隔的 <length>。
负值无效。 当模糊值为零时,阴影边缘为锐利。 否则,值越大,阴影边缘越模糊。 详见下文 阴影模糊。
关于 “图层、布局和其他细节” 中 box-shadow-blur 如何与其他逗号分隔的阴影属性共同形成每一层阴影的详细说明。
5.4. 阴影扩展:box-shadow-spread 属性
| 名称: | box-shadow-spread |
|---|---|
| 值: | <length># |
| 初始值: | 0 |
| 适用元素: | 所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 列表,每项为<length> |
| 规范顺序: | 按语法顺序 |
| 动画类型: | 按计算值 |
box-shadow-spread 属性定义一个或多个阴影扩展距离。 该属性接受逗号分隔的 <length>。
正值会使阴影向四周扩展指定半径,负值会使阴影收缩。 详见下文 阴影形状。
注意,对于内阴影,扩展阴影(即增加阴影面积)意味着阴影轮廓收缩。
关于 “图层、布局和其他细节” 中 box-shadow-spread 如何与其他逗号分隔的阴影属性共同形成每一层阴影的详细说明。
5.5. 阴影位置:box-shadow-position 属性
| 名称: | box-shadow-position |
|---|---|
| 值: | [ outset | inset ]# |
| 初始值: | outset |
| 适用元素: | 所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 列表,每项为关键字之一 |
| 规范顺序: | 按语法顺序 |
| 动画类型: | 按计算值 |
box-shadow-position 属性定义一个或多个投影阴影的位置。 接受逗号分隔的 outset 和 inset 关键字列表。
- outset
- 使投影阴影成为外部 box-shadow。 即效果是盒子漂浮在画布上并投下阴影。
- inset
- 使投影阴影成为内部 box-shadow。 即效果是盒子相当于被从画布上切掉一块后向下移,画布在盒子内部投射阴影。
关于 “图层、布局和其他细节” 中 box-shadow-position 如何与其他逗号分隔的阴影属性共同形成每一层阴影的详细说明。
5.6. 阴影速记:box-shadow 属性
| 名称: | box-shadow |
|---|---|
| 值: | <spread-shadow># |
| 初始值: | none |
| 适用元素: | 所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 见单独属性 |
| 规范顺序: | 按语法顺序 |
| 动画类型: | 见单独属性 |
box-shadow 属性为盒子添加一个或多个投影阴影。 该属性接受逗号分隔的阴影列表, 按前后顺序绘制(前面的在上)。
每个阴影为一个 <spread-shadow>, 包含 box-shadow-offset,以及可选的 box-shadow-blur、box-shadow-spread、box-shadow-color、box-shadow-position。 省略的长度为 0; 省略的颜色,当指定偏移为 transparent 时为透明,否则为 currentcolor。
<spread-shadow> = <'box-shadow-color'>? && [ <'box-shadow-offset'> [ <'box-shadow-blur'> <'box-shadow-spread'>? ]? ] && <'box-shadow-position'>?
5.7. 图层、布局及其他细节
投影阴影声明在由 box-shadow-* 属性组成的协调值列表上, 它与 box-shadow-offset 组成一个协调列表属性组,其中 box-shadow-offset 是协调列表基属性。 详见 CSS Values 4 § A 协调值属性。
阴影效果自上而下叠加: 首个阴影在最上层,其余依次在下。 阴影不影响布局,可能与其他盒子、文本或其阴影重叠。 在堆叠上下文和绘制顺序上, 元素的外部阴影绘于该元素背景之下, 内部阴影绘于该元素背景之上(但在边框及 border-image 下方,如有)。
除非另有说明,投影阴影只应用于主盒。 如果受影响盒子有多个片段,则阴影应用规则,详见 box-decoration-break。
阴影不会触发滚动或增加可滚动区域的大小。
外部阴影对于表格折叠边框模型内的表格内部元素无效。 如果在折叠边框模型下,为单个边界定义了阴影(如表格某行边框比其他行厚,或单元格跨行且相邻单元格边框厚度不同), 其阴影位置与渲染不做要求。
6. 边框形状
虽然 corner-shape 和 border-radius 提供了一些边框样式表现力, 但它们仍然假定边框是矩形。
border-shape 函数增强了这些能力, 允许作者用任意基本形状 指定边框路径。
6.1. border-shape 属性
| 名称: | border-shape |
|---|---|
| 值: | none | [ <basic-shape> <geometry-box>?]{1,2} |
| 初始值: | none |
| 适用元素: | 所有元素 |
| 继承性: | no |
| 百分比: | 相对于给定的 <geometry-box>,或未指定时为 border box |
| 计算值: | 列表,每项为已计算颜色 |
| 规范顺序: | 按语法顺序 |
| 动画类型: | 按计算值 |
border-shape 属性可指定一个 <basic-shape> 或两个 <basic-shape>, 分别生成一条或两条路径。 单路径边框形状模式使用元素现有 border 属性描边给定 <basic-shape> 解析的路径, 双路径边框形状模式则填充两条路径间的区域作为边框。
border-shape 属性与 border-radius 和 corner-shape 不兼容。 当元素的 最终计算值的 border-shape 非 none 时, 其 border-radius 被忽略,视为 0。corner-shape 也隐式忽略,因为它只能与 border-radius 配合使用。
box-shadow 会分别跟随内外边框路径。
border-shape 不影响几何或布局, 布局依然按 border-width 属性计算。
border-shape 不影响盒内内容流动。 注:作者可结合 border-shape 和 shape-inside 实现盒子装饰和文本流动联动效果。
内侧 border-shape 会裁剪元素的 overflow 内容,方式同 border-radius, 具体见 角裁剪。
填充和描边颜色,以及描边宽度,取自对应的 border-color 和 border-width 属性。
border-style 怎么办?它未必适用于任意形状。
隐私注意事项
本规范尚未报告新的隐私注意事项。
安全性注意事项
本规范尚未报告新的安全性注意事项。
变更
自 [CSS3BG] 以来的新增内容
-
<image-1D> 作为 border-color 及其长属性的值
-
新增物理和逻辑方向的 border-*-radius 速记属性
-
新增 corner-shape 及 corner-*-shape 速记属性,并新增相关的 corners 速记
-
新增 border-shape
-
通过 partial borders 增加了部分边框功能,通过 border-limit 和 border-*-clip 属性实现
-
新增 box-shadow-* 长属性,并将 box-shadow 转为速记属性
-
将逻辑边框属性从 [CSS-LOGICAL-1] 移入本规范。
致谢
除了本模块前身中对 [CSS1]、[CSS21] 和 [CSS3BG] 作出贡献的众多人员外, 编辑们还要感谢下列人员针对本 Level 4 提出的建议与反馈: Tab Atkins, Noam Rosenthal, Håkon Wium Lie, 以及 Oriol Brufau。