clip-path

Baseline Widely available *

This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.

* Some parts of this feature may have varying levels of support.

Thuộc tính clip-path CSS tạo vùng cắt xác định phần nào của phần tử sẽ được hiển thị. Các phần nằm trong vùng sẽ được hiển thị, còn các phần nằm ngoài sẽ bị ẩn.

Try it

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;
}

Cú pháp

css
/* Giá trị từ khóa */
clip-path: none;

/* Giá trị <clip-source> */
clip-path: url("resources.svg#c1");

/* Giá trị <geometry-box> */
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;

/* Giá trị <basic-shape> */
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);

/* Kết hợp hộp và hình dạng */
clip-path: padding-box circle(50px at 0 100px);

/* Giá trị toàn cục */
clip-path: inherit;
clip-path: initial;
clip-path: revert;
clip-path: revert-layer;
clip-path: unset;

Thuộc tính clip-path được xác định bằng một hoặc kết hợp các giá trị liệt kê bên dưới.

Giá trị

<clip-source>

Một <url> tham chiếu đến phần tử SVG <clipPath>.

<basic-shape>

Một hình dạng có kích thước và vị trí được xác định bởi giá trị <geometry-box>. Nếu không có hộp hình học nào được chỉ định, border-box sẽ được dùng làm hộp tham chiếu. Các giá trị có thể là:

inset()

Xác định một hình chữ nhật thụt vào.

circle()

Xác định một hình tròn bằng bán kính và vị trí.

ellipse()

Xác định một hình elip bằng hai bán kính và vị trí.

polygon()

Xác định một đa giác bằng quy tắc tô màu SVG và tập hợp các đỉnh.

path()

Xác định một hình dạng bằng quy tắc tô màu SVG tùy chọn và định nghĩa đường dẫn SVG.

rect()

Xác định một hình chữ nhật bằng khoảng cách từ các cạnh của hộp tham chiếu.

shape()

Xác định hình dạng bằng quy tắc tô màu SVG tùy chọn và các lệnh hình dạng cho đường thẳng, đường cong và cung tròn.

xywh()

Xác định một hình chữ nhật bằng khoảng cách từ cạnh trên và cạnh trái của hộp tham chiếu cùng chiều rộng và chiều cao của hình chữ nhật.

<geometry-box>

Nếu được chỉ định kết hợp với <basic-shape>, giá trị này xác định hộp tham chiếu cho hình dạng cơ bản. Nếu được chỉ định đơn lẻ, nó khiến các cạnh của hộp được chỉ định, bao gồm cả tạo hình góc (chẳng hạn như border-radius), trở thành đường cắt. Hộp hình học có thể là một trong các giá trị sau:

margin-box

Sử dụng hộp lề làm hộp tham chiếu.

border-box

Sử dụng hộp viền làm hộp tham chiếu.

padding-box

Sử dụng hộp padding làm hộp tham chiếu.

content-box

Sử dụng hộp nội dung làm hộp tham chiếu.

fill-box

Sử dụng hộp bao đối tượng làm hộp tham chiếu.

stroke-box

Sử dụng hộp bao nét vẽ làm hộp tham chiếu.

view-box

Sử dụng viewport SVG gần nhất làm hộp tham chiếu. Nếu có thuộc tính viewBox trên phần tử tạo viewport SVG, hộp tham chiếu được đặt tại gốc của hệ tọa độ được xác lập bởi thuộc tính viewBox và kích thước của hộp tham chiếu được đặt theo giá trị chiều rộng và chiều cao của thuộc tính viewBox.

none

Không tạo đường cắt.

Note: Giá trị được tính toán khác none dẫn đến việc tạo ra một ngữ cảnh xếp chồng mới, tương tự như opacity với giá trị khác 1.

Định nghĩa hình thức

Initial valuenone
Applies toall elements; In SVG, it applies to container elements excluding the <defs> element and all graphics elements
Inheritedno
Percentagesrefer to reference box when specified, otherwise border-box
Computed valueas specified, but with <url> values made absolute
Animation typeyes, as specified for <basic-shape>, otherwise no

Cú pháp hình thức

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

<clip-source> =
<url>

<basic-shape> =
<basic-shape-rect> |
<circle()> |
<ellipse()> |
<polygon()> |
<path()> |
<shape()>

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

<basic-shape-rect> =
<inset()> |
<rect()> |
<xywh()>

<circle()> =
circle( <radial-size>? [ at <position> ]? )

<ellipse()> =
ellipse( <radial-size>? [ at <position> ]? )

<polygon()> =
polygon( <'fill-rule'>? [ round <length> ]? , [ <length-percentage> <length-percentage> ]# )

<path()> =
path( <'fill-rule'>? , <string> )

<shape()> =
shape( <'fill-rule'>? from <position> , <shape-command># )

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

<inset()> =
inset( <length-percentage>{1,4} [ round <'border-radius'> ]? )

<rect()> =
rect( <top> , <right> , <bottom> , <left> )

<xywh()> =
xywh( <length-percentage>{2} <length-percentage [0,∞]>{2} [ round <'border-radius'> ]? )

<radial-size> =
<radial-extent> |
<length [0,∞]> |
<length-percentage [0,∞]>{2}

<position> =
<position-one> |
<position-two> |
<position-four>

<fill-rule> =
nonzero |
evenodd

<length-percentage> =
<length> |
<percentage>

<shape-command> =
<move-command> |
<line-command> |
close |
<horizontal-line-command> |
<vertical-line-command> |
<curve-command> |
<smooth-command> |
<arc-command>

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

<border-radius> =
<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?

<radial-extent> =
closest-corner |
closest-side |
farthest-corner |
farthest-side

<position-one> =
left |
center |
right |
top |
bottom |
x-start |
x-end |
y-start |
y-end |
block-start |
block-end |
inline-start |
inline-end |
<length-percentage>

<position-two> =
[ left | center | right | x-start | x-end ] && [ top | center | bottom | y-start | y-end ] |
[ left | center | right | x-start | x-end | <length-percentage> ] [ top | center | bottom | y-start | y-end | <length-percentage> ] |
[ block-start | center | block-end ] && [ inline-start | center | inline-end ] |
[ start | center | end ]{2}

<position-four> =
[ [ left | right | x-start | x-end ] <length-percentage> ] && [ [ top | bottom | y-start | y-end ] <length-percentage> ] |
[ [ block-start | block-end ] <length-percentage> ] && [ [ inline-start | inline-end ] <length-percentage> ] |
[ [ start | end ] <length-percentage> ]{2}

<move-command> =
move <command-end-point>

<line-command> =
line <command-end-point>

<horizontal-line-command> =
hline [ to [ <length-percentage> | left | center | right | x-start | x-end ] | by <length-percentage> ]

<vertical-line-command> =
vline [ to [ <length-percentage> | top | center | bottom | y-start | y-end ] | by <length-percentage> ]

<curve-command> =
curve [ [ to <position> with <control-point> [ / <control-point> ]? ] | [ by <coordinate-pair> with <relative-control-point> [ / <relative-control-point> ]? ] ]

<smooth-command> =
smooth [ [ to <position> [ with <control-point> ]? ] | [ by <coordinate-pair> [ with <relative-control-point> ]? ] ]

<arc-command> =
arc <command-end-point> [ [ of <length-percentage>{1,2} ] && <arc-sweep>? && <arc-size>? && [ rotate <angle> ]? ]

<command-end-point> =
to <position> |
by <coordinate-pair>

<control-point> =
<position> |
<relative-control-point>

<coordinate-pair> =
<length-percentage>{2}

<relative-control-point> =
<coordinate-pair> [ from [ start | end | origin ] ]?

<arc-sweep> =
cw |
ccw

<arc-size> =
large |
small

Ví dụ

Hình dạng và hộp hình học

Trong ví dụ này, hai hình tam giác được tạo bằng cách định nghĩa polygon() làm đường cắt trên các phần tử <div>. Mỗi phần tử có nền màu đặc và viền dày. Phần tử <div> thứ hai có hộp tham chiếu được đặt thành 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%);
}

Kết quả

Đối với tam giác đầu tiên, chúng ta không chỉ định hộp tham chiếu; do đó mặc định là border-box, với vị trí 0% và 100% nằm ở cạnh ngoài của viền. Trong ví dụ thứ hai, chúng ta đặt <geometry-box> thành content-box, nghĩa là hộp tham chiếu cho hình dạng cơ bản là cạnh ngoài của vùng nội dung, nằm bên trong hộp padding. Vì ví dụ của chúng ta không có padding, đây là cạnh trong của viền.

Hàm shape() so với path()

Mở rộng ví dụ trước, chúng ta tạo cùng một hình tam giác với các giá trị <basic-shape> khác nhau, minh họa cách hàm shape()path() cũng có thể được dùng để tạo đường cắt, trong đó shape() là giải pháp linh hoạt hơn.

Chúng ta dùng path() để định nghĩa đường cắt cho phần tử đầu tiên và shape() cho phần tử thứ hai, cả hai đều sử dụng border-box mặc định làm hộp tham chiếu:

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);
}

Kết quả là, đường dẫn được định nghĩa bằng hàm shape() sẽ co giãn theo phần tử, còn phiên bản path() thì không:

Vì hàm shape() cho phép sử dụng giá trị <percentage> (và cả thuộc tính tùy chỉnh), nó mạnh mẽ hơn.

Chúng ta sẽ minh họa bằng cách tăng kích thước phần tử nền:

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

Khả năng hiển thị, hay ít nhất là hiển thị một phần, của bốn cạnh viền trong ví dụ đường cắt được định nghĩa bằng hàm shape() là do các giá trị phần trăm cho phép đường dẫn co giãn theo phần tử. Trong phiên bản path(), phần tử lớn hơn nhưng hình dạng thì không. Kết quả là các viền trên và trái hiển thị một phần trong khi viền phải và dưới bị cắt.

SVG làm nguồn cắt

Trong ví dụ này, chúng ta định nghĩa các phần tử SVG <clipPath> để dùng làm nguồn clip-path.

HTML

Chúng ta gồm hai phần tử <div> và một phần tử <svg> chứa hai phần tử <clipPath>. Một <clipPath> chứa bốn phần tử <rect> cùng nhau định nghĩa ô cửa sổ, tạo ra khoảng trống hình chữ thập ở giữa, và phần tử còn lại chứa hai phần tử <rect> giao nhau.

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

Chúng ta dùng flexbox để các phần tử nằm cạnh nhau với khoảng cách, nếu có không gian. Chúng ta định nghĩa nền conic-gradient() trên cả hai phần tử <div>, tạo nền thú vị để cắt, cùng với 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;
}

Sau đó chúng ta đặt id của <clipPath> làm <clip-source>. Chúng ta căn giữa văn bản theo chiều dọc trong ví dụ cross bằng align-content, nếu không văn bản sẽ bị cắt như đang xảy ra trong ví dụ window.

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

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

Kết quả

Các phần tử, bao gồm viền và văn bản, bị cắt, chỉ những phần chồng lên các phần tử <clipPath> mới được vẽ trên trang.

Các kiểu giá trị khác nhau

Ví dụ này minh họa các giá trị khác nhau của thuộc tính clip-path cắt một phần tử HTML <img>.

HTML

HTML gồm một <img> sẽ bị cắt, một <clipPath> hình ngôi sao, và một phần tử <select> để chọn giá trị thuộc tính 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

Hiển thị ban đầu gồm ngôi sao làm nguồn clip-path.

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

JavaScript

Khi bạn chọn một tùy chọn mới từ menu <select>, trình xử lý sự kiện cập nhật giá trị clip-path được đặt trên <img>.

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};`);
});

Kết quả

Chọn các tùy chọn khác nhau để thay đổi giá trị clip-path.

Note: Mặc dù có thể định nghĩa đường dẫn bằng văn bản, nếu bạn muốn cắt hình nền theo văn bản thay vì hình dạng, hãy xem thuộc tính background-clip.

Đặc tả

Specification
CSS Masking Module Level 1
# the-clip-path

Tương thích trình duyệt

Xem thêm