Свойство CSS `shape-outside`
Базовая поддержка Широко доступно
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и во многих версиях браузеров. Она доступна во всех браузерах с января 2020 года.
Свойство shape-outside CSS задаёт форму, которая может быть непрямоугольной и вокруг которой должен обтекать расположенный рядом строчный контент. По умолчанию строчный контент обтекает внешнее поле элемента; shape-outside позволяет настроить это обтекание, чтобы текст мог обтекать сложные объекты, а не только прямоугольные блоки.
Попробуйте
shape-outside: circle(50%);
shape-outside: ellipse(130px 140px at 20% 20%);
shape-outside: url("/shared-assets/images/examples/round-balloon.png");
shape-outside: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
<section class="default-example" id="default-example">
<div class="example-container">
<img
class="transition-all"
id="example-element"
src="/shared-assets/images/examples/round-balloon.png"
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>
.example-container {
text-align: left;
padding: 20px;
}
#example-element {
float: left;
width: 150px;
margin: 20px;
}
Синтаксис
/* Keyword values */
shape-outside: none;
shape-outside: margin-box;
shape-outside: content-box;
shape-outside: border-box;
shape-outside: padding-box;
/* Function values */
shape-outside: circle();
shape-outside: ellipse();
shape-outside: inset(10px 10px 10px 10px);
shape-outside: polygon(10px 10px, 20px 20px, 30px 30px);
/* Shape box with basic shape */
shape-outside: circle() border-box;
shape-outside: margin-box ellipse();
/* <url> value */
shape-outside: url("image.png");
/* <gradient> value */
shape-outside: linear-gradient(45deg, white 150px, red 150px);
/* Global values */
shape-outside: inherit;
shape-outside: initial;
shape-outside: revert;
shape-outside: revert-layer;
shape-outside: unset;
Для свойства shape-outside используются значения из приведённого ниже списка, которые задают область обтекания для плавающих элементов. Область обтекания определяет форму, вокруг которой обтекает строчный контент (плавающие элементы).
Значения
-
none - Область обтекания не изменяется. Строчный контент, как обычно, обтекает внешнее поле элемента.
-
<shape-box> - Область обтекания вычисляется в соответствии с формой краёв плавающего элемента (как определено блочной моделью CSS). Это может быть
margin-box,border-box,padding-boxилиcontent-box. Форма учитывает кривизну, создаваемую свойствомborder-radius(поведение аналогично свойствуbackground-clip).-
margin-box - Задаёт форму, ограниченную внешним краем поля. Радиусы углов этой формы определяются соответствующими значениями свойств
border-radiusиmargin. Если соотношениеborder-radius / marginравно1или больше, радиус угла поля равенborder-radius + margin. Если соотношение меньше1, радиус угла поля равенborder-radius + (margin * (1 + (ratio - 1) ^ 3)). -
border-box - Задаёт форму, ограниченную внешним краем рамки. Форма следует стандартным правилам скругления внешней стороны рамки.
-
padding-box - Задаёт форму, ограниченную внешним краем внутреннего отступа. Форма следует стандартным правилам скругления внутренней стороны рамки.
-
content-box - Задаёт форму, ограниченную внешним краем содержимого. Радиус каждого угла этого блока равен большему из значений
0иborder-radius - border-width - padding.
-
-
<basic-shape> - Область обтекания вычисляется на основе формы, созданной функцией
inset(),circle(),ellipse()илиpolygon(); другие функции<basic-shape>недопустимы. Если также задано значение<shape-box>, оно определяет опорный блок для функции<basic-shape>. В противном случае опорным блоком по умолчанию являетсяmargin-box. -
<image> - Область обтекания извлекается и вычисляется на основе альфа-канала указанного
<image>, как задано свойствомshape-image-threshold.
Примечание: Если изображение недопустимо, эффект будет таким же, как если бы было указано ключевое слово none. Кроме того, изображение должно передаваться с заголовками CORS, разрешающими его использование.
Формальное определение
| Начальное значение | none |
|---|---|
| Применяется к | плавающим элементам |
| Наследуется | нет |
| Вычисленное значение | как определено для <basic-shape> (с последующим shape-box, если задано), <image> с абсолютным URI, в противном случае — как задано. |
| Тип анимации | да, как указано для <basic-shape>, в противном случае — нет |
Формальный синтаксис
shape-outside = none | [ <shape-box> || <basic-shape> ] | <image> <shape-box> = <visual-box> | margin-box <basic-shape> = <inset()> | <xywh()> | <rect()> | <circle()> | <ellipse()> | <polygon()> | <path()> | shape() <image> = <url> | <image()> | <image-set()> | <element()> | <paint()> | <cross-fade()> | <gradient> <visual-box> = content-box | padding-box | border-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> ) <image()> = image( <image-tags>? [ <image-src>? , <color>? ]! ) <image-set()> = image-set( <image-set-option># ) <element()> = element( <id-selector> ) <paint()> = paint( <ident>, <declaration-value>? ) <cross-fade()> = cross-fade( <cf-mixing-image> , <cf-final-image>? ) <gradient> = <linear-gradient()> | <repeating-linear-gradient()> | <radial-gradient()> | <repeating-radial-gradient()> | <conic-gradient()> | <repeating-conic-gradient()> <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> ] ] <image-tags> = ltr | rtl <image-src> = <url> | <string> <color> = <color-base> | currentColor | <system-color> | <light-dark()> | <deprecated-system-color> <image-set-option> = [ <image> | <string> ] [ <resolution> || type(<string>) ] <id-selector> = <hash-token> <cf-mixing-image> = <percentage>? && <image> <cf-final-image> = <image> | <color> <linear-gradient()> = linear-gradient( [ <linear-gradient-syntax> ] ) <repeating-linear-gradient()> = repeating-linear-gradient( [ <linear-gradient-syntax> ] ) <radial-gradient()> = radial-gradient( [ <radial-gradient-syntax> ] ) <repeating-radial-gradient()> = repeating-radial-gradient( [ <radial-gradient-syntax> ] ) <conic-gradient()> = conic-gradient( [ <conic-gradient-syntax> ] ) <repeating-conic-gradient()> = repeating-conic-gradient( [ <conic-gradient-syntax> ] ) <radial-extent> = closest-corner | closest-side | farthest-corner | farthest-side <color-base> = <hex-color> | <color-function> | <named-color> | <color-mix()> | transparent <system-color> = AccentColor | AccentColorText | ActiveText | ButtonBorder | ButtonFace | ButtonText | Canvas | CanvasText | Field | FieldText | GrayText | Highlight | HighlightText | LinkText | Mark | MarkText | SelectedItem | SelectedItemText | VisitedText <light-dark()> = light-dark( <color>, <color> ) <deprecated-system-color> = ActiveBorder | ActiveCaption | AppWorkspace | Background | ButtonHighlight | ButtonShadow | CaptionText | InactiveBorder | InactiveCaption | InactiveCaptionText | InfoBackground | InfoText | Menu | MenuText | Scrollbar | ThreeDDarkShadow | ThreeDFace | ThreeDHighlight | ThreeDLightShadow | ThreeDShadow | Window | WindowFrame | WindowText <linear-gradient-syntax> = [ [ <angle> | <zero> | to <side-or-corner> ] || <color-interpolation-method> ]? , <color-stop-list> <radial-gradient-syntax> = [ [ [ <radial-shape> || <radial-size> ]? [ at <position> ]? ] || <color-interpolation-method> ]? , <color-stop-list> <conic-gradient-syntax> = [ [ [ from [ <angle> | <zero> ] ]? [ at <position> ]? ] || <color-interpolation-method> ]? , <angular-color-stop-list> <color-function> = <rgb()> | <rgba()> | <hsl()> | <hsla()> | <hwb()> | <lab()> | <lch()> | <oklab()> | <oklch()> | <color()> <named-color> = aliceblue | antiquewhite | aqua | aquamarine | azure | beige | bisque | black | blanchedalmond | blue | blueviolet | brown | burlywood | cadetblue | chartreuse | chocolate | coral | cornflowerblue | cornsilk | crimson | cyan | darkblue | darkcyan | darkgoldenrod | darkgray | darkgreen | darkgrey | darkkhaki | darkmagenta | darkolivegreen | darkorange | darkorchid | darkred | darksalmon | darkseagreen | darkslateblue | darkslategray | darkslategrey | darkturquoise | darkviolet | deeppink | deepskyblue | dimgray | dimgrey | dodgerblue | firebrick | floralwhite | forestgreen | fuchsia | gainsboro | ghostwhite | gold | goldenrod | gray | green | greenyellow | grey | honeydew | hotpink | indianred | indigo | ivory | khaki | lavender | lavenderblush | lawngreen | lemonchiffon | lightblue | lightcoral | lightcyan | lightgoldenrodyellow | lightgray | lightgreen | lightgrey | lightpink | lightsalmon | lightseagreen | lightskyblue | lightslategray | lightslategrey | lightsteelblue | lightyellow | lime | limegreen | linen | magenta | maroon | mediumaquamarine | mediumblue | mediumorchid | mediumpurple | mediumseagreen | mediumslateblue | mediumspringgreen | mediumturquoise | mediumvioletred | midnightblue | mintcream | mistyrose | moccasin | navajowhite | navy | oldlace | olive | olivedrab | orange | orangered | orchid | palegoldenrod | palegreen | paleturquoise | palevioletred | papayawhip | peachpuff | peru | pink | plum | powderblue | purple | rebeccapurple | red | rosybrown | royalblue | saddlebrown | salmon | sandybrown | seagreen | seashell | sienna | silver | skyblue | slateblue | slategray | slategrey | snow | springgreen | steelblue | tan | teal | thistle | tomato | turquoise | violet | wheat | white | whitesmoke | yellow | yellowgreen <color-mix()> = color-mix( <color-interpolation-method> , [ <color> && <percentage [0,100]>? ]#{2}) <side-or-corner> = [ left | right ] || [ top | bottom ] <color-interpolation-method> = in [ <rectangular-color-space> | <polar-color-space> <hue-interpolation-method>? | <custom-color-space> ] <color-stop-list> = <linear-color-stop> , [ <linear-color-hint>? , <linear-color-stop> ]#? <radial-shape> = circle | ellipse <angular-color-stop-list> = <angular-color-stop> , [ <angular-color-hint>? , <angular-color-stop> ]#? <rgb()> = rgb( <percentage>#{3} , <alpha-value>? ) | rgb( <number>#{3} , <alpha-value>? ) | rgb( [ <number> | <percentage> | none ]{3} [ / [ <alpha-value> | none ] ]? ) <rgba()> = rgba( <percentage>#{3} , <alpha-value>? ) | rgba( <number>#{3} , <alpha-value>? ) | rgba( [ <number> | <percentage> | none ]{3} [ / [ <alpha-value> | none ] ]? ) <hsl()> = hsl( <hue>, <percentage>, <percentage>, <alpha-value>? ) | hsl( [ <hue> | none ] [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ / [ <alpha-value> | none ] ]? ) <hsla()> = hsla( <hue>, <percentage>, <percentage>, <alpha-value>? ) | hsla( [ <hue> | none ] [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ / [ <alpha-value> | none ] ]? ) <hwb()> = hwb( [ <hue> | none ] [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ / [ <alpha-value> | none ] ]? ) <lab()> = lab( [<percentage> | <number> | none] [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ / [<alpha-value> | none] ]? ) <lch()> = lch( [<percentage> | <number> | none] [ <percentage> | <number> | none] [ <hue> | none] [ / [<alpha-value> | none] ]? ) <oklab()> = oklab( [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ / [<alpha-value> | none] ]? ) <oklch()> = oklch( [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ <hue> | none] [ / [<alpha-value> | none] ]? ) <color()> = color( [ from <color> ]? <colorspace-params> [ / [ <alpha-value> | none ] ]? ) <rectangular-color-space> = srgb | srgb-linear | display-p3 | display-p3-linear | a98-rgb | prophoto-rgb | rec2020 | lab | oklab | xyz | xyz-d50 | xyz-d65 <polar-color-space> = hsl | hwb | lch | oklch <hue-interpolation-method> = [ shorter | longer | increasing | decreasing ] hue <custom-color-space> = <dashed-ident> <linear-color-stop> = <color> <color-stop-length>? <linear-color-hint> = <length-percentage> <angular-color-stop> = <color> <color-stop-angle>? <angular-color-hint> = <angle-percentage> | <zero> <alpha-value> = <number> | <percentage> <hue> = <number> | <angle> <colorspace-params> = [<custom-params> | <predefined-rgb-params> | <xyz-params>] <color-stop-length> = <length-percentage>{1,2} <color-stop-angle> = [ <angle-percentage> | <zero> ]{1,2} <angle-percentage> = <angle> | <percentage> <custom-params> = <dashed-ident> [ <number> | <percentage> | none ]+ <predefined-rgb-params> = <predefined-rgb> [ <number> | <percentage> | none ]{3} <xyz-params> = <xyz> [ <number> | <percentage> | none ]{3} <predefined-rgb> = srgb | srgb-linear | display-p3 | display-p3-linear | a98-rgb | prophoto-rgb | rec2020 <xyz> = xyz | xyz-d50 | xyz-d65
Примеры
Направление текста
HTML
<div class="main">
<div class="left"></div>
<div class="right"></div>
<p>
Sometimes a web page's text content appears to be funneling your attention
towards a spot on the page to drive you to follow a particular link.
Sometimes you don't notice.
</p>
</div>
CSS
.main {
width: 530px;
}
.left,
.right {
background-color: lightgray;
height: 12ex;
width: 40%;
}
.left {
clip-path: polygon(0 0, 100% 100%, 0 100%);
float: left;
shape-outside: polygon(0 0, 100% 100%, 0 100%);
}
.right {
clip-path: polygon(100% 0, 100% 100%, 0 100%);
float: right;
shape-outside: polygon(100% 0, 100% 100%, 0 100%);
}
p {
text-align: center;
}
Результат
Спецификации
| Спецификация |
|---|
| Модуль CSS Shapes, уровень 1 # shape-outside-property |
Совместимость с браузерами
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome для Android | Firefox для Android | Opera для Android | Safari на iOS | Samsung Internet | WebView для Android | WebView на iOS | |
shape-outside |
37 |
79 |
62 |
24 |
10.1 |
37 |
62 |
24 |
10.3 |
3.0 |
37 |
10.3 |
border-box |
37 |
79 |
62 |
24 |
10.1 |
37 |
62 |
24 |
10.3 |
3.0 |
37 |
10.3 |
circle |
37 |
79 |
62 |
24 |
10.1 |
37 |
62 |
24 |
10.3 |
3.0 |
37 |
10.3 |
content-box |
37 |
79 |
62 |
24 |
10.1 |
37 |
62 |
24 |
10.3 |
3.0 |
37 |
10.3 |
gradient |
37 |
79 |
62 |
24 |
10.1 |
37 |
62 |
24 |
10.3 |
3.0 |
37 |
10.3 |
image |
37 |
79 |
62 |
24 |
10.1 |
37 |
62 |
24 |
10.3 |
3.0 |
37 |
10.3 |
inset |
37 |
79 |
62 |
24 |
10.1 |
37 |
62 |
24 |
10.3 |
3.0 |
37 |
10.3 |
margin-box |
37 |
79 |
62 |
24 |
10.1 |
37 |
62 |
24 |
10.3 |
3.0 |
37 |
10.3 |
none |
37 |
79 |
62 |
24 |
10.1 |
37 |
62 |
24 |
10.3 |
3.0 |
37 |
10.3 |
padding-box |
37 |
79 |
62 |
24 |
10.1 |
37 |
62 |
24 |
10.3 |
3.0 |
37 |
10.3 |
path |
149 |
149 |
Нет |
133 |
Нет |
149 |
Нет |
100 |
Нет |
Нет |
149 |
Нет |
polygon |
37 |
79 |
62 |
24 |
10.1 |
37 |
62 |
24 |
10.3 |
3.0 |
37 |
10.3 |
rect |
149 |
149 |
149 |
133 |
17.2 |
149 |
149 |
100 |
17.2 |
Нет |
149 |
17.2 |
xywh |
149 |
149 |
149 |
133 |
17.2 |
149 |
149 |
100 |
17.2 |
Нет |
149 |
17.2 |
См. также
© 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/shape-outside