The <basic-shape>
CSS value represents, as the name suggests, a basic shape that is defined using a shape function. A basic shape can then be passed as a value to a property such as the shape-outside
property, or the clip-path
property, which are used to apply the shape to an element in order to change the flow of content around it, or to clip the element to the defined shape, respectively.
The <basic-shape>
type can be specified using basic shape functions. See the Values section below for a list of possible shape function values and their description.
A shape’s reference box
In addition to the element’s height and width, the element’s box model boxes—margin box, content box, padding box, and border-box—are also used as a reference to specify the extent of the shape on an element. The reference box can be any of the four boxes.
When a <basic-shape>
is used to define shapes, the reference box is defined by each property that uses <basic-shape>
values (see the Examples section below). The coordinate system for the shape has its origin on the top-left corner of the reference box with the x-axis running to the right and the y-axis running downwards. All the lengths expressed in percentages are resolved from the used dimensions of the reference box. If no reference box is specified, the border-box will be used as reference box for the clip-path
property, and the margin-box is used for shapes used in the shape-outside
property.
Trivia & Notes
It is possible that in the future more CSS properties will take a <basic-shape>
as a value (for example, the upcoming shape-inside
from the second level of the CSS Shapes Module), so this value is not exclusive to the above two properties.
Values
- inset()
-
inset() = inset( [offset]{1,4} [round <border-radius>]? ) /* where.. */ offset = <length> | <percentage>
The
inset()
functions defines an inset rectangle. It takes one to four offset values, which specify the offsets from the edges of the references box inward. These specify where the inset rectangle goes inside the element.The syntax of the offsets is the same as the syntax of the
margin
shorthand property. This means that you can set all four insets with one, two or four values. If one offset value is specified (e.g15px
), it will be used as a top, right, bottom, and left offset. If two offset values are specified (e.g20px 10px
), they specify the top and bottom offsets and the right and left offsets, respectively. If three values are specified (e.g10px 15px 20px
), the first specifies the top offset, the second specifies the right and left offsets, and the third specifies the bottom offset. If four values are specified, the first is used as the top offset, the second as the right offset, the third as the bottom offset, and the fourth as the left offset.And just like with margins, the offset values can be set in absolute lengths or percentages.
In addition to the offset value(s), the
inset()
function takes an optional border-radius value that specifies the amount by which the corners of the rectangles are to be rounded. The border-radius argument uses the same syntax as the syntax of theborder-radius
property—one to eight values specifying the rounding value for the four corners in either or both horizontal and vertical dimensions. Refer to theborder-radius
property entry for more information about it if you’re not already familiar with it. The border radius specified must be preceded by theround
keyword.The following are all valid
inset()
rectangle shape declarations:inset(10% 20% round 5px); /* a rectangle with 5px rounded corners, whose edges are set inwards by 10% from the top and bottom edges of the reference box, and 20% inwards from the left and right edges of the box */ inset(15px 20px 30px); /* creates a non-rounded inset rectangle, set inwards by 15px from the top, 20px from the right and left edges of the reference box, and 30px inwards from the bottom edge of the reference box */ inset(25% round 10px 30px); /* creates a rectangle set inwards by 25% in all four directions relative to the edges of the reference box, and has top-left and bottom-right corners rounded by 10px, and the top-right and bottom-left corners rounded by 30px */ inset(10px 20px 30px 40px round 10px);
- circle()
-
circle() = circle( [<shape-radius>]? [at <position>]? ) /* where.. */ <shape-radius> = <length> | <percentage> | closest-side | farthest-side
The
circle()
function is used to define a circle. The question marks indicate that both parameters are optional and can be omitted. If you omit one, that parameter is set to its default value by the browser.If you omit the position argument, the center of the circle will be positioned at the center of the element it is used on. You can specify a position using the same syntax as that of the
background-position
property syntax. The position is preceded by theat
word.The shape-radius parameter specifies the radius of the circle. It can be set in absolute lengths or percentages. A percentage value here is resolved from the used width and height of the reference box. Negative values are not allowed.
In addition to using lengths and percentages to specify the circle’s radius, it can also be set using one of two keywords:
closest-side
orfurthest-side
.closest-side
is the default value, which means that, if you omit this argument and don’t specify a radius for the circle, the browser will use the length from the center of the element to its closest side in any dimension as the length of the radius.farthest-side
uses the length from the center to the farthest side.The following illustration explains the
closest-side
andfarthest-side
radius values visually.The following are all valid
circle()
shape declarations:circle(); /* use default values: circle with closest-side radius, positioned at the center of the element */ circle(100px at 30% 50%); /* circle of radius 100px positioned at 30% horizontally and 50% vertically */ circle(farthest-side at 25% 25%); /* defines a circle whose radius is half the length of the longest side, positioned at the point of coordinates 25% 25% on the element’s coordinate system */ circle(10em at 500px 300px); /* defines a circle whose center is positioned at 500px horizontally and 300px vertically, with a radius of 10em */
- ellipse()
-
ellipse() = ellipse( [<shape-radius>{2}]? [at <position>]? ) /* where.. */ <shape-radius> = <length> | <percentage> | closest-side | farthest-side
The
ellipse()
function defines an ellipse shape. It takes the same arguments list and values as thecircle()
function, except that instead of taking one shape radius value, it takes two radii, rx and ry, that represent the x-axis and y-axis radii of the ellipse, in that order. Also, 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.See the
circle()
function description above for more information about the possible arguments, their meanings, and possible values.Note about
closest-side
: For circles, this is the closest side in any dimension. For ellipses, this is the closest side in the radius dimension.Note about
farthest-side
: For circles, this is the farthest side in any dimension. For ellipses, this is the farthest side in the radius dimension.The following are all valid
ellipse()
shape declarations:ellipse(); /* use default values */ ellipse(100px 50px at 30% 50%); /* ellipse of x-radius 100px and y-radius 50px positioned at 30% horizontally and 50% vertically */ ellipse(farthest-side closest-side at 25% 25%); /* defines an ellipse whose x-radius is half the length of the longest side, and whose y-radius is half the length of the shorter side, positioned at the point of coordinates 25% 25% on the element’s coordinate system*/ ellipse(10em 10em at 500px 300px); /* defines a ellipse whose center is positioned at 500px horizontally and 300px vertically, with both x and y radii of 10em (this is basically a circle) */
- polygon()
-
polygon() = polygon( [<fill-rule>,]? [<shape-arg> <shape-arg>]# ) /* where.. */ <shape-arg> = <length> | <percentage>
The
polygon()
function is used to define more complex arbitrary shapes using any number of points. The function takes in a set of coordinate pairs (<shape-arg> <shape-arg>
), each pair specifying the position of a point. The first argument represents the x-position of a point, and the second argument represents the y-position. The set of points make up the shape. The browser will connect the last vertex in the list with the first vertex in the list to close the polygon, so you don’t have to do that yourself. Coordinate pairs are comma-separated, and can be set using either absolute lengths or percentages.In addition to the set of coordinate pairs, the
polygon()
function can take an optional argument called thefill-rule
. This specifies how to treat areas inside the polygonal shape that may intersect itself. Seefill-rule
property in SVG for details. Possible values arenonzero
orevenodd
. Default value when omitted isnonzero
.The following are all valid
polygon()
function declarations:polygon(0 0, 100% 100%, 0 100%); polygon(0 0, 100% 100%, 0 100%); polygon(50px 0px, 100px 100px, 0px 100px); polygon(170.67px 291.00px, 126.23px 347.56px, 139.79px 417.11px, 208.92px 466.22px, 302.50px 482.97px, 343.67px 474.47px, 446.33px 452.00px, 443.63px 246.82px, 389.92px 245.63px, 336.50px 235.26px, 299.67px 196.53px, 259.33px 209.53px, 217.00px 254.76px); polygon(evenodd, 446.33px 452.00px, 443.63px 246.82px, 389.92px 245.63px, ...);
Notes
The values in a basic shape function are computed as specified, with these exceptions:
- Omitted values are included and compute to their defaults.
-
A
<position>
value incircle()
orellipse()
is computed as a pair of offsets (horizontal then vertical) from the top left origin, each given as a combination of an absolute length and a percentage. -
A
<border-radius>
value ininset()
is computed as an expanded list of all eight<length>
or percentage values.
The reference box for the shapes is defined as part of the property that takes these shapes as values. See the Examples section next for examples.
Interpolation of Basic Shapes (Animating between Shapes)
For interpolating between one basic shape and a second, the rules below are applied. The values in the shape functions interpolate as a simple list. The list values interpolate as length, percentage, or calc where possible. If list values are not one of those types but are identical (such as finding nonzero
in the same list position in both lists) those values do interpolate.
- Both shapes must use the same reference box.
-
If both shapes are the same type, that type is
ellipse()
orcircle()
, and none of the radii use theclosest-side
orfarthest-side
keywords, interpolate between each value in the shape functions. -
If both shapes are of type
inset()
, interpolate between each value in the shape functions. -
If both shapes are of type
polygon()
, both polygons have the same number of vertices, and use the same<fill-rule>
, interpolate between each value in the shape functions. - In all other cases no interpolation is specified.
Examples
The following example defines a shape used to change the shape of the float area of an element using the shape-outside
property. Notice how the reference box of the shape is defined inside the property’s declaration.
.element { shape-outside: circle(100px at 50% 50%) margin-box; }
The result of the above code would look similar to the following image. Refer to the shape-outside
property entry for more examples on using basic shapes to change the flow of content around elements.
The following example defines a polygonal shape used with the clip-path
property to clip an element to the defined shape:
.element { clip-path: polygon(26px 111px, 222px 386px, 311px 281px, 470px 393px, 660px 293px, 604px 47px, 505px 107px, 318px 37px, 42px 107px); }
See the live demo below for a live example.
Live Demo
The following demo uses the clip-path
property to clip an element to the shape defined as the property’s value. The shape defined is a random polygonal shape using the polygon()
function.
Try changing the shape function and playing with the values to see how the element’s shape changes accordingly. Note that the demo currently only works in Webkit-based browsers, so you need to use an appropriate browser to view a working demo and be able to experiment with the values.
View this demo on the Codrops PlaygroundBrowser Support
Please refer to the browser support section for the shape-outside
property.