<basic-shape>
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.
The <basic-shape>
CSS data type represents a shape used in the clip-path
, shape-outside
, and offset-path
properties.
Try it
Syntax
The <basic-shape>
data type is used to create basic shapes including rectangles by container inset, by coordinate distance, or by set dimensions, circles, ellipses, polygons, paths, and author created shapes. These basic shapes are defined using one <basic_shape>
CSS functions, with each value requiring a parameter that follows the shape's function-specific syntax.
Common parameters
The parameters common across the syntax of some basic shape functions include:
round <'border-radius'>
-
Defines rounded corners for rectangles by container insets, rectangles by distance, and rectangles with dimensions using the same syntax as the CSS
border-radius
shorthand property. <shape-radius>
-
Defines the radius for a circle or an ellipse. Valid values include
<length>
,<percentage>
,closest-side
(the default), andfarthest-side
. Negative values are invalid.The
closest-side
keyword value uses the length from the center of the shape to the closest side of the reference box to create the radius length. Thefarthest-side
keyword value uses the length from the center of the shape to the farthest side of the reference box. <position>
-
Defines the center
<position>
of a circle or an ellipse. It defaults tocenter
if omitted. <fill-rule>
-
Sets the
fill-rule
that is used to determine how the interior of the shape defined by the basic shapes polygon, path, and shape is to be filled. Possible values arenonzero
(the default) andevenodd
.Note:
<fill-rule>
is not supported inoffset-path
and using it invalidates the property.
Syntax for rectangles by container insets
The inset()
function creates an inset rectangle, with its size defined by the offset distance of each of the four sides of its container and, optionally, rounded corners.
inset( <length-percentage>{1,4} [ round <`border-radius`> ]? )
When all of the first four arguments are supplied, they represent the top, right, bottom, and left offsets from the reference box inward that define the position of the edges of the inset rectangle. These arguments follow the syntax of the margin
shorthand, which lets you set all four insets with one, two, three, or four values.
If a pair of insets for a dimension adds up to more than 100% of that dimension, both values are proportionally reduced so their sum equals 100%. For example, the value inset(90% 10% 60% 10%)
has a top inset of 90%
and a bottom inset of 60%
. These values are reduced proportionally to inset(60% 10% 40% 10%)
. Shapes such as this, that enclose no area and have no shape-margin
, do not affect wrapping.
Syntax for rectangles by distance
The rect()
function defines a rectangle using the specified distances from the top and left edges of the reference box, with optional rounded corners.
rect( [ <length-percentage> | auto ]{4} [ round <`border-radius`> ]? )
When using the rect()
function, you do not define the width and height of the rectangle. Instead, you specify four values to create the rectangle, with its dimensions determined by the size of the reference box and the four offset values. Each value can be either a <length>
, a <percentage>
, or the keyword auto
. The auto
keyword is interpreted as 0%
for the top and left values and as 100%
for the bottom and right values.
Syntax for rectangles with dimensions
The xywh()
function defines a rectangle located at the specified distances from the left (x
) and top (y
) edges of the reference box and sized by the specified width (w
) and height (h
) of the rectangle, in that order, with optional rounded corners.
xywh( <length-percentage>{2} <length-percentage [0,∞]>{2} [ round <`border-radius`> ]? )
Syntax for circles
The circle()
function defines a circle using a radius and a position.
circle( <shape-radius>? [ at <position> ]? )
The <shape-radius>
argument represents the radius of the circle defined as either a <length>
or a <percentage>
. A percentage value here is resolved from the used width and height of the reference box as sqrt(width^2+height^2)/sqrt(2)
. If omitted, the radius is defined by closest-side
.
Syntax for ellipses
The ellipse()
function defines an ellipse using two radii and a position.
ellipse( [ <shape-radius>{2} ]? [ at <position> ]? )
The <shape-radius>
arguments represent rx and ry, the x-axis and y-axis radii of the ellipse, in that order. These values are specified as either a <length>
or a <percentage>
. Percentage values here are resolved against the used width (for the rx value) and the used height (for the ry value) of the reference box. If only one radius value is provided, the ellipse()
shape function is invalid. If no value is provided, 50% 50%
is used.
Syntax for polygons
The polygon()
function defines a polygon using an SVG fill-rule
and a set of coordinates.
polygon( <`fill-rule`>?, [ <length-percentage> <length-percentage> ]# )
The function takes a list of comma-separated coordinate pairs, each consisting of two space-separated <length-percentage>
values as the xi and yi pair. These values represent the x and y axis coordinates of the polygon at position i (the vertex point where two lines meet).
Syntax for paths
The path()
function defines a shape using an SVG fill-rule
and an SVG path definition.
path( <`fill-rule`>?, ]? <string> )
The required <string>
is an SVG path as a quoted string. The path()
function is not a valid shape-outside
property value.
Syntax for shapes
The shape()
function defines a shape using an initial starting point and a series of shape commands.
shape( <fill-rule>? from <coordinate-pair>, <shape-command># )
The from <coordinate-pair>
parameter represents the starting point for the first shape command, and <shape-command>
defines one or more shape commands, which are similar to the SVG path commands. The shape()
function is not a valid shape-outside
property value.
Description
When creating a shape, the reference box is defined by the property that uses <basic-shape>
values. The coordinate system for the shape has its origin at the top-left corner of the element's margin box by default, with the x-axis running to the right and the y-axis running downwards. All the lengths expressed in percentages are resolved from the dimensions of the reference box.
The default reference box is the margin-box
, as demonstrated in the image below. The image shows a circle created using shape-outside: circle(50%)
, highlighting the different parts of the box model as seen in a browser's Developer Tools. The shape here is defined with reference to the margin-box.
Computed values of basic shapes
The values in a <basic-shape>
function are computed as specified, with the following additional considerations:
- For any omitted values, their defaults are used.
- A
<position>
value incircle()
orellipse()
is computed as a pair of offsets from the top left corner of the reference box: the first offset is horizontal, and the second is vertical. Each offset is specified as a<length-percentage>
value. - A
<border-radius>
value ininset()
is expanded into a list of eight values, each either a<length>
or a<percentage>
. inset()
,rect()
, andxywh()
functions compute to the equivalentinset()
function.
Interpolation of basic shapes
When animating between two <basic-shape>
functions, the interpolation rules listed below are followed. The parameter values of each <basic-shape>
function form a list. For interpolation to occur between two shapes, both shapes must use the same reference box and the number and type of values in both <basic-shape>
lists must match.
Each value in the lists of the two <basic-shape>
functions is interpolated based on its computed value as a <number>
, <length>
, <percentage>
, <angle>
, or calc()
where possible. Interpolation can still occur if the values are not one of those data types but are identical between the two interpolating basic shape functions, such as nonzero
.
-
Both shapes are of type
ellipse()
or typecircle()
: Interpolation is applied between each corresponding value if their radii are specified as either a<length>
or a<percentage>
(rather than keywords such asclosest-side
orfarthest-side
). -
Both shapes are of type
inset()
: Interpolation is applied between each corresponding value. -
Both shapes are of type
polygon()
: Interpolation is applied between each corresponding value if they use the same<fill-rule>
and have the same number of comma-separated coordinate pairs. -
Both shapes are of type
path()
: Interpolation is applied to each parameter as a<number>
if the path strings in both the shapes match the number, type, and sequence of path data commands. -
Both shapes are of type
shape()
: Interpolation is applied between each corresponding value if they have the identical command keyword and use the same<by-to>
keyword. Ifshape()
is used in theclip-path
property, the two shapes interpolate if they also have the same<fill-rule>
.-
If they use the
<curve-command>
or the<smooth-command>
, the number of control points must match for interpolation. -
If they use the
<arc-command>
with different<arc-sweep>
directions, the interpolated result goes clockwise (cw
). If they use different<arc-size>
keywords, the size is interpolated using thelarge
value.
-
-
One shape is of type
path()
and the other is of typeshape()
: Interpolation is applied between each corresponding value if the list of path data commands is identical in number as well as sequence. The interpolated shape is ashape()
function, maintaining the same list of path data commands.
In all other cases, no interpolation occurs and the animation is discrete.
Examples
Animated polygon
In this example, we use the @keyframes at-rule to animate a clip path between two polygons. Note that both polygons have the same number of vertices, which is necessary for this type of animation to work.
HTML
<div></div>
CSS
div {
width: 300px;
height: 300px;
background: repeating-linear-gradient(red, orange 50px);
clip-path: polygon(
50% 0%,
60% 40%,
100% 50%,
60% 60%,
50% 100%,
40% 60%,
0% 50%,
40% 40%
);
animation: 4s poly infinite alternate ease-in-out;
margin: 10px auto;
}
@keyframes poly {
from {
clip-path: polygon(
50% 0%,
60% 40%,
100% 50%,
60% 60%,
50% 100%,
40% 60%,
0% 50%,
40% 40%
);
}
to {
clip-path: polygon(
50% 30%,
100% 0%,
70% 50%,
100% 100%,
50% 70%,
0% 100%,
30% 50%,
0% 0%
);
}
}
Result
Specifications
Specification |
---|
CSS Shapes Module Level 1 # basic-shape-functions |
Browser compatibility
BCD tables only load in the browser
See also
- Properties that use this data type:
clip-path
,offset-path
,shape-outside
, - CSS shapes module
- Overview of CSS shapes
- Edit Shape Paths in CSS — Firefox Developer Tools