shape-outside

shape-outside

The shape-outside property controls how content will wrap around a floated element’s bounding-box. Typically this is so that text can reflow over a shape such as a circle, ellipse or a polygon:

.element {  
  float: left;
  shape-outside: circle(50%);
  width: 200px;
  height: 200px;
}

It’s important to note that this property will only work on floated elements for now, although this is likely to change in the future. The shape-outside property can also be manipulated with transitions or animations.

Values

  • circle(): for making circular shapes.
  • ellipse(): for making elliptical shapes.
  • inset(): for making rectangular shapes.
  • polygon(): for creating any shape with 3 or more vertices.
  • url(): identifies which image should be used to wrap text around.
  • initial: the float area is unaffected.
  • inherit: inherits shape-outside value from parent.

The following values identify which reference of the box model should be used for positioning the shape within:

  • margin-box
  • padding-box
  • border-box

These values should be appended to the end, for instance: shape-outside: circle(50% at 0 0) padding-box. By default the margin-box reference will be used.

ellipse()

.element {
  shape-outside: ellipse(150px 300px at 50% 50%);
}

The ellipse() function requires the radii values for the x, y axis of the ellipse followed by the coordinates to position the center of the shape within its bounding box. For instance the example above will position the center of the ellipse in the vertical and horizontal center of the .element div:

See the Pen 7fa99015d63597648d5e312c5b73ac25 by CSS-Tricks (@css-tricks) on CodePen.

Although the demo above may suggest that we’re changing the shape of the div itself, if we add borders and a background-image we’ll find that the bounding box is in fact still rectangular:

See the Pen 5e47a80626dfa27a42dd18a0e2b8450b by CSS-Tricks (@css-tricks) on CodePen.

It might be better to think of it this way: with the shape-outside property we’re changing the relationship of other elements around an element, not the geometry of the element itself. To fix that we’ll need to use shape-outside alongside the clip-path() property, such as in this example:

See the Pen 4e5420d8c1a2766b25dd3c98f684bf9c by CSS-Tricks (@css-tricks) on CodePen.

circle()

.element {
  shape-outside: circle(50%);
}

This function creates a circle, and in the code example above it will create a circle with a radius that is half the height and width of .element. The circle() function can also use the same syntax for positioning the shape within.

url()

.element {
  shape-outside: url('circle.png'); 
}

In this instance, we have two floated images, one on either side of a block of text. Since both images have the shape-outside property set then the text beneath will avoid those two floats.

See the Pen CSS Shapes by CSS-Tricks (@css-tricks) on CodePen.

It’s also possible to set the shape-image-threshold property which will inform the browser which pixels, depending on their transparency, should create the shape. For example:

.element {  
  shape-outside: url('image.png'); 
  shape-image-threshold: 0.5;
}

In this example the only pixels that will create the shape must have 50% transparency and above. Values from 0.0 (transparent) to 1.0 (opaque) are valid.

polygon()

.element {
  shape-outside: polygon(0 0, 0 200px, 300px 600px);
}

This function creates any shape that has three or more vertices, for example:

See the Pen 22b25bc2fdbcf4f1adf6f3822ff28156 by CSS-Tricks (@css-tricks) on CodePen.

It’s important to note that if this property is going to be animated it requires the same number of vertices when you declare the animated state:

.element {  
  shape-outside: polygon(0 0, 100% 0, 100% 100%, 0 100%);
  transition: shape-outside 1s;
}
.element:hover {  
	shape-outside: polygon(0 0, 100% 50%, 100% 50%, 0 100%);
}

inset()

.element {
  shape-outside: inset(100px 100px 100px 100px 10px);
  /* shape-outside: inset(top right bottom left border-radius); */
}

inset() is a function for making rectangular shapes, it takes five parameters but the fifth, for border-radius is optional. The other arguments are offsets inwards from edge of .element:

See the Pen b2da5018d8f20ac3a2ccc26edb724db6 by CSS-Tricks (@css-tricks) on CodePen.

Above we have an element that is 200px wide by 200px tall and we’re offsetting the shape within to 50px in every direction except the left side. This way the text will wrap above the shape even though the div extends to the top.

Related properties

Other resources

Browser support

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeOperaFirefoxIEEdgeSafari
3724NoNoNo7.1*

Mobile / Tablet

iOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox
8*37No6262No
icon-anchoricon-closeicon-emailicon-linkicon-logo-staricon-menuicon-nav-guideicon-searchicon-staricon-tag