CSS / clip / 矩形裁剪与迁移到 clip-path
clip 是一个旧版 CSS 属性,用于将元素可见部分限制为矩形。它适用于具有 position: absolute 或 position: fixed 的元素,并已被弃用,因此在新代码中应优先使用 clip-path。在迁移现有代码时,需要区分 rect() 中的边界坐标与 inset() 中的内缩距离。
适用条件与主要值
裁剪隐藏区域外的图形。它不同于编辑原始图像文件或实际减小元素的宽度和高度。clip 的初始值为 auto,并且不会被继承。仅设置 position: relative 不会使传统裁剪生效。
| 数值或条件 | 含义和选择 |
|---|---|
auto |
不通过此属性应用裁剪矩形。 |
rect(top, right, bottom, left) |
使用长度或 auto 值指定上、右、下、左边界。这是传统的逗号分隔语法。 |
position: absolute / position: fixed |
裁剪的定位条件。示例使用的是绝对定位。 |
clip-path: inset(20px) |
显示一个距离每个边缘内缩20px的矩形。这也可以用于流内元素。 |
遗留的裁剪矩形不接受百分比值。完整值clip: auto也与rect(auto, auto, auto, auto)不同。后者在内部边框边缘裁剪,因此溢出的子元素可能会显示出差异。MDN clip 语法与适用条件
用完整示例比较原始区域和裁剪区域
将以下完整代码保存为 clip-example.html 并使用 UTF-8 编码,然后在浏览器中打开。不需要外部图片、库或服务器。将这些演示样式保留在此文件中,而不是粘贴到共享站点的样式表中。比较所有三个框,然后每次更改一个值,保存并重新加载。
<!doctype html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>clip 与 clip-path 比较</title>
<style>
body { margin: 0; padding: 16px; font: 16px/1.6 sans-serif; }
main { max-width: 760px; margin: auto; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1rem; }
.samples { display: flex; flex-wrap: wrap; gap: 24px; }
.frame { position: relative; width: 200px; height: 120px;
background: #e5e7eb; outline: 1px solid #666; }
.target { width: 100%; height: 100%; padding: 0; border: 0;
background: linear-gradient(135deg, #006c9c, #ffd166); }
.legacy { position: absolute; top: 0; left: 0;
clip: rect(20px, 180px, 100px, 20px); }
.modern { clip-path: inset(20px); }
</style>
</head>
<body>
<main>
<h1>clip 与 clip-path 比较</h1>
<div class="samples">
<section><h2>clip: auto</h2>
<div class="frame"><div class="target"></div></div></section>
<section><h2>clip: rect(20px, 180px, 100px, 20px)</h2>
<div class="frame"><div class="target legacy"></div></div></section>
<section><h2>clip-path: inset(20px)</h2>
<div class="frame"><div class="target modern"></div></div></section>
</div>
</main>
</body>
</html>
第一个框是参考,显示整个 200×120px 的渐变。第二个和第三个框应显示在每边排除 20px 后的 160×80px 区域。灰色背景和轮廓属于单独的框架,因此原始框的大小仍然可见。在狭窄窗口中,比较框会换行到另一行。
将 rect 坐标转换为 inset 距离
这两个声明产生相同的可见区域,因为它们的数字表示的含义不同。这些规则对应完整示例中的 .legacy 和 .modern。
.legacy {
position: absolute;
clip: rect(20px, 180px, 100px, 20px);
}
.modern {
clip-path: inset(20px);
}
在旧版 rect 中,top 和 bottom 是从内部上边框边缘开始测量的;left 和 right 是从内部左边框边缘开始测量的。右坐标为 180px 并不意味着从右侧去掉 180px。四个 inset 值是从各自边缘向内测量的,使用 border-box,除非指定了其他参考框。在此示例中,目标没有内边距或边框,因此参考框差异不会影响比较。
| 边缘 | rect 边界坐标 | inset 距离 |
|---|---|---|
| 顶部 | 20px | 20px |
| 右侧 | 180px | 200 − 180 = 20px |
| 底部 | 100px | 120 − 100 = 20px |
| 左侧 | 20px | 20px |
对于一个没有内边距或边框、宽度为 W、高度为 H 的盒子,rect(t, r, b, l) 对应 inset(t, W − r, H − b, l)。在实际 CSS 中,插入计算出的长度,而不是复制像 W − r 这样的解释性表达式。如果有边框、内边距或不同的参考盒子,先对齐坐标系统。MDN clip-path 参考盒子与形状
改变元素尺寸并比较
首先仅将完整示例中的 .frame 更改为宽度 300px、高度 180px。保留旧的 rect 坐标会留下一个 160×80px 的可见区域,而 inset(20px) 现在会通过从较大盒子的每一边排除 20px 来留下 260×140px。比较为什么相同的数字并不能保证相同的裁剪结果。
为了再次匹配这两种方法,将 .legacy 的右边界更改为 280px,底部边界更改为 160px。在完整示例中按如下方式替换这两个规则。保持 .modern 声明不变。
.frame {
width: 300px;
height: 180px;
}
.legacy {
clip: rect(20px, 280px, 160px, 20px);
}
现在两种方法都应留下一个 260×140px 的区域。比较后,将 .frame 恢复为 200×120px,rect 恢复为 20px, 180px, 100px, 20px。为了在响应式盒子中保持相同的内侧间距,inset 比反复重新计算固定边界更直接表达意图。
裁剪、布局与无障碍访问
使用 clip-path 裁剪通常不会改变元素的布局空间。示例中的 .modern 占据 200×120px,仅其绘制区域变小。由于绝对定位,.legacy 元素脱离了正常流;其父元素 .frame 保留了比较空间。要区分这种定位效果与裁剪本身的区别。
对于新代码,考虑使用 clip-path 形状,例如用于矩形的 inset 或用于圆形的 circle。当目标是隐藏溢出内容或提供滚动时,请考虑 overflow 的独立作用。clip-path 的值如果不是 none,也可能创建堆叠上下文,因此迁移后检查重叠元素。 CSS Masking:裁剪与元素几何结构
裁剪不是访问控制或隐私保护。隐藏的文本仍可能保留在文档中,其在辅助技术中的处理需要单独检查。不要以阻止用户操作界面的方式裁剪按钮、输入框、重要信息或键盘焦点指示器。提供在放大、触控和键盘导航时阅读内容的方法。
裁剪无效或显示与预期不同时
- 在开发者工具中检查所选元素的计算位置和裁剪。相对定位或静态定位不符合旧版裁剪的条件。在示例中,仅将 .legacy 的 position 改为 relative,比较裁剪是否消失,然后恢复为 absolute。
- 矩形的顺序是上、右、下、左。如果右小于左或下小于上,预期的矩形将无法保留。更改宽度或高度后,检查旧坐标是否被保留。
- 祖先元素的 overflow、clip-path 或其他裁剪规则可能进一步减少可见区域。在开发者工具中单独禁用和重新启用声明,以隔离原因。
- 在将 clip 替换为 clip-path 时,请比较定位、参考框、边框、内边距、堆叠和焦点指示器。clip 使用的旧版 rect() 与 clip-path 中较新的 rect() 形状语法不同;相同的名称并不意味着它们的值可以互换。


