Spec-Zone.ru › CSS

CSS-свойство `border-shape`

Базовая поддержка Ограниченная доступность

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

Экспериментальная функция: Это экспериментальная технология
Перед использованием в production тщательно изучите таблицу совместимости с браузерами.

Экспериментальная функция: Это экспериментальная технология
Перед использованием в production тщательно изучите таблицу совместимости с браузерами.

CSS-свойство border-shape определяет форму границы элемента с помощью значений CSS <basic-shape>.

Синтаксис

/* Keyword */
border-shape: none;

/* Single <basic-shape> value */
border-shape: circle(50%);
border-shape: rect(10px 460px 130px 20px round 20px);
border-shape: shape(
  from 5% 0.5rem,
  arc to 80px 1pt of 10% ccw large rotate 25deg
);

/* Two <basic-shape> values */
border-shape: circle(50%) ellipse(40% 30%);
border-shape: polygon(0% 0%, 0% 100%, 100% 0%)
  polygon(10% 10%, 10% 70%, 70% 10%);

/* <basic-shape> and <geometry-box> values */
border-shape: circle(50%) border-box ellipse(40% 30%) view-box;
border-shape: rect(5px 198px 189px 0px round 20px) view-box circle(50%);
border-shape: path(
    "M 35,95 C 35,50 60,15 100,20 C 120,5 160,5 180,22 C 200,5 250,5 270,22 C 295,5 340,5 360,22 C 395,10 440,35 440,75 C 455,90 450,120 430,128 C 400,145 360,145 330,130 C 300,145 260,145 230,130 C 200,145 160,145 130,130 C 80,142 35,120 35,95 Z"
  )
  view-box;

/* Global values */
border-shape: inherit;
border-shape: initial;
border-shape: revert;
border-shape: revert-layer;
border-shape: unset;

Свойство border-shape можно задать с помощью ключевого слова none либо одной или двух разделённых пробелами фигур, каждая из которых состоит из значения <basic-shape> или значения <basic-shape> и значения <geometry-box>.

Значения

none
Указывает, что форма границы не задана. Это начальное значение.
<basic-shape>
Задаёт форму границы с помощью одной из функций <basic-shape>.
<geometry-box> Необязательно
Задаёт опорный прямоугольник, относительно которого рисуется граница. Если он не указан, по умолчанию используется следующая геометрия опорного прямоугольника:
  • half-border-box, если задана одна базовая фигура. Это означает, что любая заданная граница рисуется поверх контура фигуры, а контур проходит по её центру.
  • border-box для первой (внешней) фигуры и padding-box для второй (внутренней) фигуры, если заданы две базовые фигуры. В этом случае граница занимает область между фигурами.

Описание

Свойство border-shape можно применять к элементам, чтобы создавать контейнеры заданной формы, например речевые облака, как показано здесь, или абстрактные всплывающие подсказки, не прибегая к обходным решениям.

<img src="https://mdn.github.io/shared-assets/images/examples/leopard.jpg" />
<p>I am a leopard</p>
html {
  height: 100%;
}

body {
  margin: 0;
  height: inherit;
  display: flex;
  justify-content: center;
  align-items: center;
}

img {
  display: block;
  width: 300px;
  anchor-name: --leopard;
  position: relative;
  top: 45px;
}

p {
  font-family: "Helvetica", "Arial";
  font-size: 1.3rem;
  padding: 15px 0;
  margin: 0 0 -30px -110px;
  background-color: chartreuse;
  border: 7px solid rgb(50 50 50);
  box-shadow: 5px 5px 10px rgb(0 0 0 / 0.75);

  width: 250px;
  height: 100px;
  border-shape: shape(
      from 50.08% 0%,
      curve to 97.71% 25.55% with 72.95% 0%/93.9% 8.76%,
      curve to 97.71% 62.04% with 100.76% 37.96%/100.76% 49.64%,
      curve to 50.08% 83.94% with 93.9% 75.18%/72.95% 83.94%,
      curve to 23.41% 82.48% with 36.75% 83.94%/27.22% 83.21%,
      curve to 17.7% 100% with 21.51% 87.59%/19.22% 94.16%,
      curve to 11.98% 82.48% with 16.17% 94.16%/13.89% 87.59%,
      curve to 1.31% 62.04% with 13.5% 81.75%/3.98% 76.64%,
      curve to 2.45% 25.55% with -0.59% 49.64%/-0.59% 37.96%,
      curve to 50.08% 0% with 6.26% 8.76%/27.22% 0%,
      close
    )
    content-box;

  text-align: center;
  line-height: 4;

  position: absolute;
  position-anchor: --leopard;
  bottom: anchor(top);
  left: anchor(right);
}

Обратите внимание, как применённое свойство border-shape сочетается с заданными для элемента свойствами border и box-shadow: они повторяют форму границы.

Поддерживаемые функции для задания формы

Форму border-shape элемента (в том числе строчного элемента или псевдоэлемента) можно задать с помощью одной из функций <basic-shape>. К ним относятся:

  • inset(), rect() и xywh(): позволяют по-разному задавать простые прямоугольные фигуры.
  • circle(): задаёт круги.
  • ellipse(): задаёт эллипсы.
  • path(): задаёт фигуры любого вида с помощью синтаксиса строк SVG path. Синтаксис SVG path имеет ограничения: в нём можно использовать только пиксельные значения, а контур необходимо задавать одной строкой, поэтому нельзя включать пользовательские свойства с помощью var(). Рекомендуется вместо этого использовать shape().
  • polygon(): задаёт многоугольники любого вида с помощью пар координат вершин. Если нужная фигура содержит плавные кривые, рекомендуется использовать shape().
  • shape(): задаёт фигуры любого вида. Синтаксис shape() лучше совместим с CSS, чем синтаксис path(), и устраняет его недостатки.

После каждого значения <basic-shape> можно также указать необязательное ключевое слово <geometry-box>, чтобы задать опорный прямоугольник, относительно которого будут рисоваться фигуры.

Режимы обводки и заливки

Свойство border-shape поддерживает два режима:

  • Если в значении указана одна <basic-shape>, она задаёт форму границы элемента, а заданные стили границы применяются как обводка вокруг фигуры, как показано в предыдущем примере. Это называется режимом обводки.
  • Если в значении указаны две <basic-shape>, первая фигура задаёт внешнюю границу, а вторая — внутреннюю; заданный цвет границы заполняет область между этими границами. Это называется режимом заливки.

Примечание: Не задавайте для внутренней границы фигуру, которая больше внешней. В этом случае область границы отображается некорректно: заливка границы может не отображаться вовсе или одна фигура может отображаться поверх другой.

Влияние на компоновку и отображение

Свойство border-shape создаёт только визуальный эффект: компоновка элемента по-прежнему вычисляется на основе лежащего в его основе прямоугольного блока, а поток содержимого не меняется.

Содержимое и фон элемента обрезаются свойством border-shape (внутренней фигурой в режиме заливки). Если указанная border-shape совпадает по размеру с содержимым или меньше него, корректировать опорный прямоугольник не нужно, если только вы не хотите создать смещение. Однако если указанная border-shape больше содержимого или фона, между краем фона и фигурой (фигурами) появятся промежутки. В таких случаях для корректного отображения может потребоваться другой опорный прямоугольник (подробнее см. в разделе Обработка форм границы, превышающих размер фона элемента).

Ограничения для стилей границ, применяемых к фигурным границам

К элементам с заданным свойством border-shape применяются не все стили границ. В следующем списке описано, как ведёт себя каждое свойство:

  • border-color: это свойство применяется. Однако если для границ разных сторон элемента заданы разные цвета, браузер выбирает первый цвет границы в следующем порядке:

    • Начальная сторона блока
    • Начальная сторона строки
    • Конечная сторона блока
    • Конечная сторона строки

    Затем браузер применяет цвет границы выбранной стороны ко всей отображаемой border-shape.

  • border-image: не применяется.
  • border-style: не применяется. Все границы отображаются в стиле solid.
  • border-width: в режиме обводки значение border-width применяется непосредственно к отображаемой border-shape. Если для разных сторон заданы разные ширины границы, браузер выбирает ширину для всей границы так же, как описано для border-color.

    В режиме заливки область границы определяется разницей площадей внешней и внутренней фигур, поэтому border-width напрямую не влияет на ширину отображаемой границы. Однако оно влияет косвенно: это свойство по-прежнему меняет размер опорных прямоугольников, относительно которых рисуются фигуры (если для их <geometry-box> не задано значение content-box или padding-box). Поэтому при использовании режима заливки необходимо учитывать значение border-width, заданное для лежащего в основе элемента.

Например, если к элементу применены следующие объявления:

border-shape: rect(5px 198px 189px 0px round 20px);
border-bottom: 30px dashed blue;
border-left: 40px dotted hotpink;
border-right: 50px double yellow;

У отображаемого блока будет прямоугольная граница со скруглёнными углами. Стиль границы будет solid, поскольку остальные стили игнорируются. Ширина и цвет границы будут соответственно 40px и hotpink. Это связано с тем, что свойство border-left задаёт стили для начальной стороны строки (предполагается, что страница использует горизонтальный writing-mode), которая является первой стороной со стилями границы. Браузер выбирает её согласно описанному выше списку приоритетов.

Взаимодействие с border-radius и corner-shape

Свойства border-radius и corner-shape несовместимы с border-shape. Если для элемента задано border-shape, любое заданное border-radius игнорируется, поэтому corner-shape также не действует. Свойства border-shape и border-radius/corner-shape имеют разные эффекты и используются по отдельности.

Если вы хотите использовать фигурные углы в border-shape, их придётся нарисовать непосредственно как часть фигуры.

border-shape и clip-path

Свойство clip-path принимает значения, похожие на border-shape, и создаёт похожие эффекты. Оба свойства можно использовать, чтобы изменить форму элемента, а значит, и область его попадания, изменив границы области, в которой активируются :hover и события, связанные с указателем.

Однако эти свойства работают принципиально по-разному:

  • clip-path скрывает область элемента, находящуюся за пределами области, заданной указанной фигурой.
  • border-shape изменяет визуальное отображение элемента так, чтобы он находился внутри области, заданной указанной фигурой.

Это означает, что border-shape обрезает содержимое элемента, но позволяет свойству overflow управлять его отображением, тогда как clip-path полностью скрывает содержимое элемента, поэтому управлять переполнением невозможно.

Что ещё важнее, такие свойства, как box-shadow и outline, не повторяют фигуру, созданную с помощью clip-path: они отсекают внешнюю часть элемента, из-за чего такие эффекты выглядят неаккуратно или полностью пропадают. Напротив, свойство border-shape создаёт границу другой формы, которую эти эффекты аккуратно повторяют.

Обработка форм границы, превышающих размер фона элемента

Как упоминалось выше, одна из проблем border-shape заключается в том, что если заданная фигура больше содержимого или фона элемента, между фоном и границей может образоваться промежуток.

Рекомендуемый способ решения этой проблемы — задать опорному <geometry-box> значение content-box, а затем использовать padding, чтобы заполнить промежутки между содержимым и границей. Например:

border-shape: shape(
    from 0% 0%,
    hline to 33%,
    arc by 33% 0% of 16% 20% small cw,
    hline to 100%,
    line to 100% 33%,
    arc by 0% 33% of 20% 16% small cw,
    line to 100% 100%,
    hline to 66%,
    arc by -33% 0% of 16% 20% small ccw,
    hline to 0%,
    line to 0% 66%,
    arc by 0% -33% of 20% 16% small ccw,
    close
  )
  content-box;
padding: 24px;

Так padding будет располагаться за пределами фигуры, из-за чего она станет меньше, а фон заполнит части фигуры, выступающие за пределы области содержимого. Этот приём показан в примере навигационного меню с элементами в форме неправильных пазловых деталей.

Формальное определение

Начальное значение none
Применяется к всем элементам
Наследуется нет
Вычисленное значение как задано
Тип анимации по типу вычисленного значения

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

border-shape = 
  none |
  [ <basic-shape> <geometry-box>?]{1,2}

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

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

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

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

<rect()> = 
  rect( [ <length-percentage> | auto ]{4} [ round <'border-radius'> ]? )

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

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

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

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

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

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

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

<position> = 
  [ [ left | center | right ] || [ top | center | bottom ] | [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]? | [ [ left | right ] <length-percentage> ] && [ [ top | bottom ] <length-percentage> ] ]

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

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

Примеры

Базовое использование border-shape в режиме обводки

В этом примере показано, как использовать border-shape в режиме обводки.

HTML

В разметке этого примера используется один элемент <p>.

<p>Circle</p>

CSS

html {
  height: 100%;
}

body {
  margin: 0;
  height: inherit;
  display: flex;
  justify-content: center;
  align-items: center;
}

p {
  box-sizing: border-box;
  font-family: "Helvetica", "Arial";
  font-size: 1.6rem;
  padding: 40px 50px;
  background-color: chartreuse;
  display: flex;
  align-items: center;
}

Мы задаём блоку width со значением fit-content и aspect-ratio со значением 1/1, чтобы содержимое аккуратно поместилось в квадрат. Также мы задаём толстую чёрную border и box-shadow, а затем задаём border-shape со значением circle(50%), чтобы создать круглую границу, точно повторяющую форму содержимого и фона.

p {
  width: fit-content;
  aspect-ratio: 1/1;
  border: 15px solid black;
  box-shadow: 5px 5px 10px rgb(0 0 0 / 0.5);
  border-shape: circle(50%);
}

Результат

Обратите внимание, как аккуратно border и box-shadow повторяют заданную форму.

Базовое использование border-shape в режиме заливки

Этот пример основан на предыдущем и показывает, как использовать border-shape в режиме заливки для создания границы с заливкой неправильной формы.

HTML-код такой же, как в предыдущем примере.

CSS

CSS-код такой же, как в предыдущем примере, за исключением того, что на этот раз мы задаём границе цвет hotpink и включаем два определения <basic-shape> в значение border-shape. Внешний прямоугольник покрывает всю область содержимого, а внутренний круг совпадает с кругом из предыдущего примера.

p {
  width: fit-content;
  aspect-ratio: 1/1;
  border: 15px solid hotpink;
  box-shadow: 5px 5px 10px rgb(0 0 0 / 0.5);
  border-shape: rect(0% 100% 100% 0% round 20px) circle(50%);
}

Результат

Обратите внимание: на этот раз граница покрывает область между прямоугольником и кругом и принимает цвет, заданный в объявлении border.

Сравнение значений border-shape

В этом примере можно выбирать разные значения border-shape для элемента и сравнивать их отображение.

HTML

HTML-код похож на код из предыдущего примера, но на этот раз в элемент <p> добавлено немного больше текста. Мы также добавили элемент <select>, чтобы можно было выбирать разные классы, применяемые к <p> с помощью JavaScript (для краткости мы скрыли и <select>, и JavaScript).

<p>Blessed are the cheesemakers.</p>
<form>
  <label for="shape-select">Select border-shape type:</label>
  <br />
  <select id="shape-select">
    <option>circle</option>
    <option selected>ellipse</option>
    <option>inset</option>
    <option>path</option>
    <option>polygon</option>
    <option>rect</option>
    <option>shape</option>
    <option>two-polygons</option>
    <option>xywh</option>
  </select>
</form>

Классы задают разные значения border-shape для элемента <p>. Изначально для элемента <p> задаётся class со значением ellipse, поэтому у него есть ellipse() border-shape.

const box = document.querySelector("p");
const select = document.querySelector("select");

select.addEventListener("change", selectClass);

function selectClass() {
  box.className = select.value;
}

selectClass();

CSS

В CSS мы задаём блоку width со значением 550px, толстую чёрную border и box-shadow.

p {
  width: 550px;
  border: 15px solid black;
  box-shadow: 5px 5px 10px rgb(0 0 0 / 0.5);
}

Затем мы задаём правила для каждого класса, который будет применяться при выборе разных параметров в элементе <select>:

.circle {
  border-shape: circle(60%);
}

.ellipse {
  border-shape: ellipse(50% 40%);
}

.inset {
  border-shape: inset(10px 20px 10px 20px round 20px);
}

.path {
  border-shape: path(
      "M 35,95 C 35,50 60,15 100,20 C 120,5 160,5 180,22 C 200,5 250,5 270,22 C 295,5 340,5 360,22 C 460,10 477,35 496,75 C 515,157 450,120 430,128 C 400,145 360,145 330,130 C 300,145 260,145 230,130 C 200,145 160,145 130,130 C 80,142 35,120 35,95 Z"
    )
    view-box;
}

.polygon {
  border-shape: polygon(0% 60%, 0% 85%, 8% 100%, 18% 88%, 30% 100%, 42% 88%, 55% 100%, 68% 88%, 80% 100%, 86% 88%, 90% 75%, 100% 60%, 90% 30%, 85% 5%, 75% 18%, 65% 3%, 52% 16%, 40% 3%, 27% 16%, 15% 3%, 5% 18%) view-box;
}

.rect {
  border-shape: rect(10px 500px 130px 20px round 20px);
}

.shape {
  border-shape: shape(
    from 0% 64.5%,
    curve to 15.71% 8.26% with 0% 30.76%/6.04% 4.51%,
    curve to 35.05% 9.76% with 20.55% -2.99%/30.21% -2.99%,
    curve to 56.8% 9.76% with 39.88% -2.99%/51.97% -2.99%,
    curve to 78.56% 9.76% with 62.84% -2.99%/73.72% -2.99%,
    curve to 97.89% 49.5% with 87.02% 0.76%/97.89% 19.51%,
    curve to 95.47% 89.25% with 101.52% 60.75%/100.31% 83.25%,
    curve to 71.3% 90.75% with 88.22% 102%/78.56% 102%,
    curve to 47.13% 90.75% with 64.05% 102%/54.38% 102%,
    curve to 22.96% 90.75% with 39.88% 102%/30.21% 102%,
    curve to 0% 64.5% with 10.88% 99.75%/0% 83.25%,
    close
  );
}

.two-polygons {
  border-shape: polygon(0% 60%, 0% 85%, 8% 100%, 18% 88%, 30% 100%, 42% 88%, 55% 100%, 68% 88%, 80% 105%, 86% 88%, 91% 75%, 101% 60%, 93% 30%, 86% 5%, 75% 18%, 65% 3%, 52% 16%, 40% 3%, 27% 16%, 15% 3%, 5% 18%)
    polygon(0% 55%, 0% 90%, 6% 104%, 17% 93%, 30% 100%, 43% 93%, 56% 102%, 69% 93%, 81% 102%, 88% 93%, 94% 78%, 100% 58%, 94% 24%, 88% -2%, 76% 13%, 64% -4%, 51% 11%, 39% -4%, 26% 11%, 13% -4%, 3% 13%);
}

.xywh {
  border-shape: xywh(5% 5% 90% 90% round 20px);
}
form {
  position: absolute;
  border: 2px solid black;
  background: white;
  padding: 5px;
  bottom: 0;
  right: 0;
}

form select {
  width: 100%;
  padding: 2px 5px;
  margin-top: 10px;
}

Результат

Выбирайте разные параметры в раскрывающемся меню, чтобы увидеть, как отображаются границы разной формы. В любой момент можно воспользоваться инструментами разработчика браузера, чтобы посмотреть значения border-shape, применённые к элементу <p>, и изменить их, чтобы понять, как они работают.

Анимация border-shape

В этом примере показано, как анимировать свойство border-shape.

HTML

Используется тот же элемент <p>, что и в предыдущем примере, но на этот раз добавлен атрибут tabindex, позволяющий перевести элемент в фокус с помощью клавиатуры.

<p tabindex="0">Blessed are the cheesemakers.</p>

CSS

В этом примере мы применяем к <p> polygon() border-shape.

p {
  width: 550px;
  border: 15px solid black;
  box-shadow: 5px 5px 10px rgb(0 0 0 / 0.5);
  border-shape: polygon(0% 60%, 0% 85%, 8% 100%, 18% 88%, 30% 100%, 42% 88%, 55% 100%, 68% 88%, 80% 100%, 86% 88%, 90% 75%, 100% 60%, 90% 30%, 85% 5%, 75% 18%, 65% 3%, 52% 16%, 40% 3%, 27% 16%, 15% 3%, 5% 18%) view-box;
}

Мы также задаём animation для состояний :hover и :focus элемента <p>. Поэтому при наведении указателя на элемент или переводе его в фокус он плавно и бесконечно переключается между двумя многоугольными формами границы.

p:hover,
p:focus {
  animation: morph 1s ease-in-out infinite alternate;
}

@keyframes morph {
  from {
    border-shape: polygon(0% 60%, 0% 85%, 8% 100%, 18% 88%, 30% 100%, 42% 88%, 55% 100%, 68% 88%, 80% 100%, 86% 88%, 90% 75%, 100% 60%, 90% 30%, 85% 5%, 75% 18%, 65% 3%, 52% 16%, 40% 3%, 27% 16%, 15% 3%, 5% 18%) view-box;
  }
  to {
    border-shape: polygon(0% 55%, 0% 90%, 6% 104%, 17% 93%, 30% 100%, 43% 93%, 56% 102%, 69% 93%, 81% 102%, 88% 93%, 94% 78%, 100% 58%, 94% 24%, 88% -2%, 76% 13%, 64% -4%, 51% 11%, 39% -4%, 26% 11%, 13% -4%, 3% 13%) view-box;
  }
}

Результат

Наведите указатель на абзац или переведите его в фокус, чтобы увидеть анимацию.

@supports not (border-shape: circle(50%)) {
  body::before {
    content: "Your browser does not support the 'border-shape' property.";
    font-family: sans-serif;
    background-color: wheat;
    padding: 1rem 0;
    text-align: center;

    z-index: 1;
    position: fixed;
    inset: 40% 0 auto;
  }
}

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

Спецификация
Модуль CSS Borders and Box Decorations, уровень 4
# border-shape

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

Компьютеры Мобильные устройства
Chrome Edge Firefox Opera Safari Chrome для Android Firefox для Android Opera для Android Safari на iOS Samsung Internet WebView для Android WebView на iOS
border-shape
147
147
Нет
131
Нет
147
Нет
98
Нет
Нет
147
Нет
none
147
147
Нет
131
Нет
147
Нет
98
Нет
Нет
147
Нет

См. также

  • border
  • corner-shape
  • Создание навигационного меню с границей неправильной формы с помощью border-shape
  • Модуль границ и декоративных элементов блоков CSS
  • Модуль фонов и границ CSS
  • border-shape: будущее непрямоугольного веба, автор Una Kravets (2026)
  • Приготовьтесь к мощному CSS-свойству border-shape! на CSS Tricks (2026)

© 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/border-shape

Spec-Zone.ru

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