Escaping the rectangular layout
Web layout has long been bound by the rectangle. Floated images, block elements, and inline content all default to boxy boundaries, and traditional wrapping around irregular shapes typically required hacks or JavaScript. CSS Shapes, available in Chrome 37 and later, changes that by letting designers define custom wrap paths around which content flows. These paths can be declared directly, using shape functions like circle() or polygon(), or inferred from an image's transparency.
Consider the common case of a floated image with transparent areas. By default, text wraps around the element's rectangular bounding box, not the visible art. CSS Shapes corrects this.
To extract a shape from an image, use the shape-outside: url(image.png) declaration. The browser analyzes the image's alpha channel and constructs a shape from it. The shape-image-threshold property controls the cutoff point: only pixels with an opacity at or above the specified value—between 0.0 and 1.0—contribute to the shape. For instance, a threshold of 0.5 keeps pixels that are at least 50% opaque.
The float property is essential for this to work. Shapes apply to the float area, meaning the region on the side opposite to the float direction. A left-floated image creates its wrap shape on the right; a right-floated image does the reverse. Content cannot wrap on both sides of a floated element simultaneously, even if the source image has gaps on both sides. This limitation will be addressed in the future by CSS Exclusions, which will allow shape-outside on non-floated elements.
Declaring shapes directly
Manual shape definitions are also available through four functional values: circle(), ellipse(), inset(), and polygon(). Each function takes coordinate arguments and uses a reference box as its coordinate system.
The circle notation is circle(r at cx cy), where r is the radius and cx and cy are the horizontal and vertical coordinates of the center. Those coordinates are optional; if omitted, the center defaults to the element's midpoint. So shape-outside: circle(50%) renders a circular wrap path with a radius equal to half the element's width or height, making it inherently responsive. When dimensions aren't equal, percentage radius values follow the formula sqrt(width^2 + height^2) / sqrt(2), which is worth recalling when anticipating the resulting shape.
Any CSS unit type—px, em, rem, vw, vh, and others—can be used for coordinates, offering control over how rigidly the shape tracks viewport or font scaling. For instance, setting the center at circle(50% at 0 0) places the circle's center at the top-left origin.
Understanding reference boxes
Shapes are drawn relative to a reference box: a conceptual bounding area whose upper-left corner serves as the coordinate origin, with the X-axis extending right and the Y-axis down. By default, shape-outside uses the margin-box, which is the area extending to the outer edge of the element's margin. Consequently, the declarations shape-outside: circle(50%) and shape-outside: circle(50%) margin-box behave identically when no margin is set.
Adding margins moves the reference box and, in turn, the entire shape. A declaration like shape-outside: circle(50% at 0 0); margin: 100px; shifts both the coordinate origin and the circle's center 100 pixels up and to the left. The circle's radius also grows, because the coordinate system now encompasses the larger margin-box area.
A note on clipping
CSS Shapes only influences the wrap area around the element; it does not clip the element's own background or borders. That behavior is handled by CSS Masking properties, such as clip-path or mask-image. The former is particularly convenient, as it shares its syntax with CSS Shapes, allowing a single shape value to be reused for both wrapping and visual clipping.



