WebCraft

shape-outside

Type that wraps to a curve, not a box

A circle set into a column of text used to mean an image with the whitespace baked into it. These lines find the curve because the float carries a shape of its own, and nothing here has been cropped, traced or measured.

CaveatThe lines follow the circle because the float carries a shape — and only because of that. shape-outside applies to floats and to nothing else, so the same declaration on a grid item, a flex item or a positioned box does exactly nothing, silently. What it does not do is change the element it sits on: that box is still a rectangle, its background still paints square, and the circle you see is border-radius doing separate work on the same numbers. Keep the two descriptions in step by hand or the text wraps a curve that is not there. The trap is margin: the shape resolves against the margin box by default, so adding margin: 10px grows the reference box and circle(50%) grows with it — the wrap drifts wider than the painted circle and the gap opens unevenly. Name the box and it stops moving: circle(50%) border-box pins the shape to the circle you drew, which is what lets the −5px margin here hang the disc past the text edge — a round form on the same vertical as flat type always reads a little inset — without dragging the wrap out with it. For a gap that follows the curve, use shape-margin, which is measured from the shape itself.

FallbackAn engine without shapes floats the box and wraps the text around its rectangle: the layout the web has had since it had floats, one degree less elegant, with nothing lost but the curve. Safe to add, then — but wasted on short text, because under four or five lines nobody reads a wrap they only see once. And it clips nothing, so it is not a substitute for clip-path when the shape belongs to the picture rather than to the text beside it.

HTML + CSS
<div class="orb"></div>
<p>A circle set into a column of text…</p>

.orb {
  float: left;
  width: 94px;
  height: 94px;
  /* this one is only paint */
  border-radius: 50%;
  /* what the text obeys, pinned to the
     drawn circle so margin cannot move it */
  shape-outside: circle(50%) border-box;
  /* the gap, measured from the curve */
  shape-margin: 9px;
  /* optical overhang: paint only */
  margin-left: -5px;
}

Published

Questions

<details name>

Why is shape-outside not working?

Because the element is not floated. shape-outside applies to floats and to nothing else — on a grid item, a flex item or an absolutely positioned box the declaration parses fine and does nothing at all.

Does shape-outside clip the element to the shape?

No. It only describes the area adjacent text wraps around; the element's own box stays rectangular and its background still paints square. Draw the visible shape separately with border-radius or clip-path and keep the two in step by hand.

How do I put a gap between the shape and the text?

Use shape-margin, which is measured out from the shape itself. Plain margin does something different: the shape resolves against the margin box by default, so a margin grows the reference box and circle(50%) grows with it, moving the wrap away from the circle you painted.