clip-path

Baseline 广泛可用 *

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2020 年 1 月⁩ 起,所有主流浏览器均已支持。

* 此特性的某些部分可能存在不同级别的支持。

clip-path CSS 属性创建一个裁剪区域,用于设置元素应显示的部分。区域内的部分将显示,而区域外的部分则隐藏。

试一试

clip-path: circle(40%);
clip-path: ellipse(130px 140px at 10% 20%);
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
clip-path: path("M 0 200 L 0,75 A 5,5 0,0,1 150,75 L 200 200 z");
clip-path: rect(5px 145px 160px 5px round 20%);
clip-path: xywh(0 5px 100% 75% round 15% 0);
<section class="default-example" id="default-example">
  <div class="example-container">
    <img
      class="transition-all"
      id="example-element"
      src="/shared-assets/images/examples/balloon-small.jpg"
      width="150" />
    We had agreed, my companion and I, that I should call for him at his house,
    after dinner, not later than eleven o’clock. This athletic young Frenchman
    belongs to a small set of Parisian sportsmen, who have taken up “ballooning”
    as a pastime. After having exhausted all the sensations that are to be found
    in ordinary sports, even those of “automobiling” at a breakneck speed, the
    members of the “Aéro Club” now seek in the air, where they indulge in all
    kinds of daring feats, the nerve-racking excitement that they have ceased to
    find on earth.
  </div>
</section>
section {
  align-items: flex-start;
}

.example-container {
  text-align: left;
  padding: 20px;
}

#example-element {
  float: left;
  width: 150px;
  margin: 20px;
}

语法

css
/* Keyword values */
clip-path: none;

/* <clip-source> values */
clip-path: url("resources.svg#c1");

/* <geometry-box> values */
clip-path: margin-box;
clip-path: border-box;
clip-path: padding-box;
clip-path: content-box;
clip-path: fill-box;
clip-path: stroke-box;
clip-path: view-box;

/* <basic-shape> values */
clip-path: inset(100px 50px);
clip-path: circle(50px at 0 100px);
clip-path: ellipse(50px 60px at 10% 20%);
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
clip-path: path(
  "M0.5,1 C0.5,1,0,0.7,0,0.3 A0.25,0.25,1,1,1,0.5,0.3 A0.25,0.25,1,1,1,1,0.3 C1,0.7,0.5,1,0.5,1 Z"
);
clip-path: rect(5px 5px 160px 145px round 20%);
clip-path: shape(from 0% 0%, line to 100% 0%, line to 50% 100%, close);
clip-path: xywh(0 5px 100% 75% round 15% 0);

/* Box and shape values combined */
clip-path: padding-box circle(50px at 0 100px);

/* Global values */
clip-path: inherit;
clip-path: initial;
clip-path: revert;
clip-path: revert-layer;
clip-path: unset;

clip-path 属性可以指定为以下列出的一个值或多个值的组合。

<clip-source>

引用 SVG <clipPath> 元素的 <url>

<basic-shape>

一个形状,其大小和位置由 <geometry-box> 值定义。如果未指定几何框,则将使用 border-box 作为参考框。其中之一是:

inset()

定义一个内嵌矩形。

circle()

使用半径和位置定义一个圆形。

ellipse()

使用两个半径和位置定义一个椭圆。

polygon()

使用 SVG 填充规则和一组顶点定义一个多边形。

path()

使用可选的 SVG 填充规则和 SVG 路径定义一个形状。

rect()

使用距离参考框边缘的指定距离定义一个矩形。

shape()

使用可选的 SVG 填充规则和用于线条、曲线和弧线的形状命令定义一个形状。

xywh()

使用距离参考框顶部和左侧边缘的指定距离以及矩形的指定宽度和高度定义一个矩形。

<geometry-box>

如果与 <basic-shape> 结合指定,此值定义了基本形状的参考框。如果单独指定,它将导致指定框的边缘(包括任何角部形状,例如 border-radius)作为裁剪路径。几何框可以是以下值之一:

margin-box

使用 margin box 作为参考框。

border-box

使用 border box 作为参考框。

padding-box

使用 padding box 作为参考框。

content-box

使用 content box 作为参考框。

fill-box

使用对象边框作为参考框。

stroke-box

使用描边边框作为参考框。

view-box

使用最近的 SVG 视口作为参考框。如果为创建 SVG 视口的元素指定了 viewBox 属性,则参考框位于 viewBox 属性建立的坐标系原点,并且参考框的大小尺寸设置为 viewBox 属性的宽度和高度值。

none

不创建裁剪路径。

注意: 计算值不是 none 会导致创建新的 堆叠上下文,就像 CSS opacity 对于非 1 的值一样。

正式定义

初始值none
应用于所有元素;在 SVG 中,它适用于除 <defs> 元素外的容器元素以及所有图形元素
继承性
百分比指定时参考参考框,否则为 border-box
计算值按指定,但 <url> 值变为绝对路径
动画类型是,如 <basic-shape> 所指定,否则否

正式语法

clip-path = 
<clip-source> |
[ <basic-shape> || <geometry-box> ] |
none

<clip-source> =
<url>

<geometry-box> =
<shape-box> |
fill-box |
stroke-box |
view-box

<shape-box> =
<visual-box> |
margin-box |
half-border-box

<visual-box> =
content-box |
padding-box |
border-box

示例

形状和几何框

在此示例中,通过在 <div> 元素上将 polygon() 定义为剪裁路径来创建两个三角形。每个都具有纯色背景和粗 border。第二个 <div> 元素的参考框设置为 content-box

HTML

html
<div></div>
<div></div>

CSS

css
div {
  height: 200px;
  width: 200px;
  box-sizing: border-box;
  background-color: rebeccapurple;
  border: 20px solid magenta;

  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

div:last-of-type {
  clip-path: content-box polygon(50% 0, 100% 100%, 0 100%);
}

结果

对于第一个三角形,我们没有指定参考框;因此它默认为 border-box,0% 和 100% 的位置位于边框的外边缘。在第二个示例中,我们将 <geometry-box> 设置为 content-box,这意味着基本形状的参考框是内容区域的外边缘,它位于内边距框内部。因为我们的示例没有 padding,所以这是边框的内边缘。

shape()path() 函数

在前面的示例的基础上,我们使用不同的 <basic-shape> 值创建相同的三角形,演示 shape()path() 函数也可以用于创建裁剪路径,其中 shape() 是一个更灵活的解决方案。

我们使用 path() 定义第一个元素的裁剪路径,并使用 shape() 定义第二个元素的裁剪路径,两者都使用默认的 border-box 作为它们的参考框

css
div {
  clip-path: path("M100 0 L200 200 L0 200 Z");
}

div:last-of-type {
  clip-path: shape(from 50% 0, line to 100% 100%, line to 0 100%, close);
}

结果是,使用 shape() 函数定义的路径会随元素增长,而 path() 版本则不会

因为 shape() 函数允许使用 <percentage> 值(以及 自定义属性),所以它更健壮。

我们将通过增加底层元素的大小来证明这一点

css
div {
  width: 250px;
  height: 250px;
}

在由 shape() 函数定义的裁剪路径示例中,四个边框的可见性,或者至少是部分可见性,是由于百分比值允许路径随元素增长。在 path() 版本中,元素增长了,但形状没有。结果,顶部和左侧边框部分可见,而右侧和底部边框被剪裁掉了。

SVG 作为裁剪源

在此示例中,我们定义 SVG <clipPath> 元素用作 clip-path 源。

HTML

我们包含两个 <div> 元素和一个包含两个 <clipPath> 元素的 <svg> 元素。其中一个 <clipPath> 包含四个 <rect> 元素,它们共同定义了窗格,在中间留下了一个空白的十字形,另一个包含两个交叉的 <rect> 元素。

html
<svg height="0" width="0">
  <defs>
    <clipPath id="window">
      <rect y="0" x="0" width="80" height="80" />
      <rect y="0" x="120" width="80" height="80" />
      <rect y="120" x="0" width="80" height="80" />
      <rect y="120" x="120" width="80" height="80" />
    </clipPath>
    <clipPath id="cross">
      <rect y="0" x="80" width="40" height="200" />
      <rect y="80" x="0" width="200" height="40" />
    </clipPath>
  </defs>
</svg>

<div class="window">Window</div>
<div class="cross">Cross</div>

CSS

我们使用 弹性盒布局,如果空间允许,使我们的元素并排排列,并留有间隙。我们在两个 <div> 元素上定义了一个 conic-gradient() 背景图像,提供了一个有趣的视觉效果来裁剪,并带有 border

css
body {
  display: flex;
  gap: 20px;
  flex-flow: row wrap;
  font: 2em sans-serif;
}

div {
  width: 200px;
  height: 200px;
  background-image: conic-gradient(
    at center,
    rebeccapurple,
    green,
    lightblue,
    rebeccapurple
  );

  border: 5px solid;
  box-sizing: border-box;
}

然后我们将 <clipPath>id 设置为 <clip-source>。在 cross 示例中,我们使用 align-content 垂直居中文本,否则文本将被裁剪,就像在 window 示例中发生的那样。

css
.window {
  clip-path: url("#window");
}

.cross {
  clip-path: url("#cross");
  align-content: center;
}

结果

元素,包括它们的边框和文本,都被裁剪,只有与 <clipPath> 元素重叠的部分被绘制到页面上。

各种值类型

此示例演示 clip-path 属性的各种值裁剪 HTML <img>

HTML

HTML 包含一个将被裁剪的 <img>、一个星形 <clipPath> 和一个 <select> 元素,用于选择 clip-path 属性值。

html
<img
  id="clipped"
  src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg"
  alt="Pride flag" />
<svg height="0" width="0">
  <defs>
    <clipPath id="star">
      <path d="M100,0 42,180 196,70 4,70 158,180z" />
    </clipPath>
  </defs>
</svg>

<select id="clipPath">
  <option value="none">none</option>
  <option value="circle(100px at 110px 100px)">circle</option>
  <option value="url(#star)" selected>star</option>
  <option value="inset(20px round 20px)">inset</option>
  <option value="rect(20px 150px 200px 20px round 10%)">rect</option>
  <option value="xywh(0 20% 90% 67% round 0 0 5% 5px)">xywh</option>
  <option value="path('M 0 200 L 0,110 A 110,90 0,0,1 240,100 L 200 340 z')">
    path
  </option>
</select>

CSS

初始渲染包括星形作为 clip-path 源。

css
#clipped {
  margin-bottom: 20px;
  clip-path: url("#star");
}

JavaScript

当您从 <select> 菜单中选择一个新选项时,事件处理程序会更新 <img> 上设置的 clip-path 值。

js
const clipPathSelect = document.getElementById("clipPath");
clipPathSelect.addEventListener("change", (evt) => {
  const path = evt.target.value;
  document.getElementById("clipped").style.clipPath = path;
  log(`clip-path: ${path};`);
});

结果

选择不同的选项以更改 clip-path 值。

注意: 虽然可以定义文本路径,但如果您想将背景图像裁剪到文本而不是形状,请参阅 background-clip 属性。

规范

规范
CSS 蒙版模块 Level 1
# the-clip-path

浏览器兼容性

另见