Spec-Zone.ru › CSS

Свойство CSS `clip-rule`

Базовая поддержка Широко доступно

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и в разных версиях браузеров. Она поддерживается браузерами с января 2020 года.

Свойство clip-rule CSS определяет, какие пиксели в области маски находятся внутри фигуры отсечения, заданной контуром отсечения, а какие — снаружи, если части контура перекрывают друг друга.

Свойство clip-rule применяется только к элементам SVG, содержащимся в элементе <clipPath>, и переопределяет значение атрибута clip-rule элемента, если он задан. По сути, свойство clip-rule работает так же, как свойство fill-rule, но применяется к определениям <clipPath>. Оно не влияет на CSS-фигуры <basic-shape>.

Синтаксис

/* Keywords */
clip-rule: nonzero;
clip-rule: evenodd;

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

Значения

Для этого свойства указывается одно из следующих ключевых слов:

nonzero
Для каждой точки в области маски отсечения проводится луч в случайном направлении. Каждый раз, когда луч пересекает какую-либо часть контура отсечения, счётчик увеличивается на единицу, если эта часть контура пересекает луч слева направо, и уменьшается на единицу, если часть контура пересекает луч справа налево. Если итоговое значение счётчика равно нулю, точка находится вне фигуры контура. В противном случае она находится внутри фигуры контура.
even-odd
Для каждой точки в области маски отсечения проводится луч в случайном направлении. Каждый раз, когда луч пересекает какую-либо часть контура отсечения, счётчик увеличивается на единицу. Если итоговое значение счётчика чётное, точка находится вне фигуры контура; в противном случае она находится внутри фигуры контура. Ноль считается чётным числом.

Формальный синтаксис

clip-rule = 
  nonzero |
  evenodd

Примеры

Сравнение значений

В этом примере мы применим разные значения CSS clip-rule к похожим элементам SVG <path>, чтобы продемонстрировать разницу между evenodd и non-zero.

HTML

Разметка содержит несколько контейнеров <svg>, в каждом из которых есть элемент <clipPath>, задающий форму звезды, и элемент <rect> для рисования звезды внутри. Звёзды созданы из перекрывающихся линий. Помимо id, разметка первых двух элементов SVG идентична. Третий SVG содержит только элемент <path>, показывая, как перекрываются линии контура, из которых создана звезда.

<svg>
  <clipPath id="star1">
    <path d="M50,0 21,90 98,35 2,35 79,90z" />
  </clipPath>
  <rect clip-path="url(#star1)" width="95" height="95" />
</svg>

<svg>
  <clipPath id="star2">
    <path d="M50,0 21,90 98,35 2,35 79,90z" />
  </clipPath>
  <rect clip-path="url(#star2)" width="95" height="95" />
</svg>

<svg id="star3">
  <path d="M50,0 21,90 98,35 2,35 79,90z" />
</svg>

CSS

Для <path> в первом SVG задано значение evenodd для свойства clip-rule; во втором SVG — nonzero. Для SVG только с контуром мы удалили значение fill по умолчанию и задали цвет stroke и stroke-width>, чтобы линии перекрывающихся контуров были видны:

body {
  display: flex;
  gap: 20px;
}
svg {
  width: 110px;
  height: 110px;
}
#star1 path {
  clip-rule: evenodd;
}

#star2 path {
  clip-rule: nonzero;
}

#star3 path {
  fill: none;
  stroke: black;
  stroke-width: 1;
}

Результаты

В определениях базовых фигур

В этом примере показано, что, хотя clip-rule не влияет на CSS-фигуры <basic-shape>, оно может влиять на <clipPath>, используемый в качестве источника фигуры.

HTML

Мы добавили SVG с двумя элементами <clipPath>, задающими формы звёзд. Они идентичны, за исключением значений атрибута id. Также мы добавили два элемента <div>, в которых будут размещены наши звёзды.

<svg height="0" width="0">
  <defs>
    <clipPath id="star1">
      <path d="M100,0 42,180 196,70 4,70 158,180z" />
    </clipPath>
    <clipPath id="star2">
      <path d="M100,0 42,180 196,70 4,70 158,180z" />
    </clipPath>
  </defs>
</svg>

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

CSS

Для элементов <div> заданы значения width и height, а в качестве значения background-image добавлен conic-gradient():

body {
  display: flex;
  gap: 20px;
}
div {
  height: 200px;
  width: 200px;
  background-image: conic-gradient(
    at center,
    rebeccapurple,
    green,
    lightblue,
    rebeccapurple
  );
}

Мы используем свойство clip-path, чтобы задать разные элементы <clipPath> в качестве контура отсечения для каждого <div>:

div:first-of-type {
  clip-path: url("#star1");
}
div:last-of-type {
  clip-path: url("#star2");
}

Наконец, мы задаём разные значения clip-rule для свойств <path> каждого элемента <clipPath>:

#star1 path {
  clip-rule: evenodd;
}
#star2 path {
  clip-rule: nonzero;
}

Результаты

Выбор правила для контура, состоящего из частей, направленных по часовой стрелке

В этом изображении SVG есть два прямоугольника, к которым применено отсечение: к одному — по каждому из правил отсечения. Здесь есть два элемента <clipPath>: для одного задано ненулевое правило отсечения, а для другого — правило чётности. Все части обоих контуров, как внутренние, так и внешние, нарисованы по часовой стрелке.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 50">
  <g stroke="#112233" fill="#bbccdd">
    <!-- basic rectangle and clipping path visualization follow -->
    <rect x="10" y="10" width="30" height="30" />
    <path
      d="M 65,5 l 20,20 -20,20 -20,-20 20,-20 m 0,10 l 10,10 -10,10 -10,-10 10,-10 z"
      fill="none"
      stroke-width="0.5" />
    <!-- rectangles to be clipped follow -->
    <rect x="110" y="10" width="30" height="30" clip-path="url(#clipper1)" />
    <rect x="160" y="10" width="30" height="30" clip-path="url(#clipper2)" />
  </g>
  <!-- clipping paths follow -->
  <clipPath id="clipper1" clipPathUnits="objectBoundingBox">
    <path
      d="M 0.5 -0.15 l 0.65 0.65 -0.65,0.65 -0.65,-0.65 0.65,-0.65 m 0,0.33 l 0.33,0.33 -0.33,0.33 -0.33,-0.33 0.33,-0.33 z"
      clip-rule="evenodd" />
  </clipPath>
  <clipPath id="clipper2" clipPathUnits="objectBoundingBox">
    <path
      d="M 0.5 -0.15 l 0.65 0.65 -0.65,0.65 -0.65,-0.65 0.65,-0.65 m 0,0.33 l 0.33,0.33 -0.33,0.33 -0.33,-0.33 0.33,-0.33 z"
      clip-rule="nonzero" />
  </clipPath>
</svg>

Для контуров отсечения, применяемых к прямоугольникам, CSS-свойство clip-rule задаёт для одного контура правило nonzero, а для другого — правило evenodd. Эти значения переопределяют значения атрибутов clip-path в SVG, которые намеренно заданы противоположными значениям, установленным с помощью CSS.

#clipper1 {
  clip-rule: nonzero;
}
#clipper2 {
  clip-rule: evenodd;
}

Поскольку внутренние и внешние части контура направлены по часовой стрелке (слева направо), форма отсечения будет различаться в зависимости от выбранного правила. При использовании nonzero значение счётчика для любого луча внутри внешней части фигуры будет больше нуля, поскольку он пересечёт один или несколько фрагментов контура, направленных слева направо. При использовании even-odd для точек между двумя частями контура счётчик будет иметь нечётное значение, а для точек внутри внутреннего контура или за пределами внешней части — чётное.

Выбор правила для контура с частями, имеющими разное направление

В этом примере используется тот же SVG, что и в предыдущем, но внутренняя часть контура отсечения направлена против часовой стрелки.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 50">
  <g stroke="#112233" fill="#bbccdd">
    <!-- basic rectangle and clipping path visualization follow -->
    <rect x="10" y="10" width="30" height="30" />
    <path
      d="M 65,5 l 20,20 -20,20 -20,-20 20,-20 m 0,10 l 10,10 -10,10 -10,-10 10,-10 z"
      fill="none"
      stroke-width="0.5" />
    <!-- rectangles to be clipped follow -->
    <rect x="110" y="10" width="30" height="30" clip-path="url(#clipper1)" />
    <rect x="160" y="10" width="30" height="30" clip-path="url(#clipper2)" />
  </g>
  <!-- clipping paths follow -->
  <clipPath id="clipper1" clipPathUnits="objectBoundingBox">
    <path
      d="M 0.5 -0.15 l 0.65 0.65 -0.65,0.65 -0.65,-0.65 0.65,-0.65 m 0,0.33 l -0.33,0.33 0.33,0.33 0.33,-0.33 -0.33,-0.33 z" />
  </clipPath>
  <clipPath id="clipper2" clipPathUnits="objectBoundingBox">
    <path
      d="M 0.5 -0.15 l 0.65 0.65 -0.65,0.65 -0.65,-0.65 0.65,-0.65 m 0,0.33 l 0.33,0.33 -0.33,0.33 -0.33,-0.33 0.33,-0.33 z" />
  </clipPath>
</svg>

Применим тот же CSS, что и раньше.

#clipper1 {
  clip-rule: nonzero;
}
#clipper2 {
  clip-rule: evenodd;
}

В этом случае внешняя часть контура направлена по часовой стрелке (слева направо), а внутренняя — против часовой стрелки (справа налево), поэтому форма отсечения будет одинаковой независимо от выбранного правила.

Спецификации

Спецификация
Модуль маскирования CSS уровня 1
# the-clip-rule

Совместимость с браузерами

Настольные компьютеры Мобильные устройства
Chrome Edge Firefox Opera Safari Chrome Android Firefox для Android Opera Android Safari на iOS Samsung Internet WebView Android WebView на iOS
clip-rule
≤15
79
3.5
15
≤5
18
4
14
≤4.2
1.0
4.4
≤4.2
evenodd
≤15
79
3.5
15
≤5
18
4
14
≤4.2
1.0
4.4
≤4.2
nonzero
≤15
79
3.5
15
≤5
18
4
14
≤4.2
1.0
4.4
≤4.2

См. также

  • fill-rule
  • clip-path
  • Введение в отсечение в CSS
  • Модуль маскирования CSS
  • Атрибут SVG clip-rule
  • Элемент SVG <clipPath>
  • Атрибут SVG fill-rule

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/clip-rule

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API