How to Wrap Text Around SVG Shapes Using CSS Shapes
This article explains how to use CSS Shapes and Scalable Vector
Graphics (SVG) to create responsive layouts where text wraps organically
around custom vector contours. By leveraging the
shape-outside property alongside floating elements,
developers can break free from rigid rectangular bounding boxes and
craft dynamic, magazine-style web typography that scales smoothly across
different screen sizes.
The Foundation:
shape-outside and Float
Browsers render HTML elements as rectangular boxes by default. The
CSS Shapes specification changes this behavior through the
shape-outside property, which redefines the float area of
an element. For shape-outside to work, the target element
must be floated using float: left or
float: right, and it must have defined dimensions.
Using SVG to Define Complex Shapes
While basic CSS shape functions like circle() or
polygon() work well for simple geometry, SVGs provide the
precision needed for intricate curves, illustrations, and logos. There
are two primary methods to apply an SVG to
shape-outside:
- SVG Data URI or External File: Reference an SVG
file directly inside
url(). The browser derives the wrap boundary from the alpha channel of the image. - Inline
path()Function: Use the CSSshape-outside: path('...')definition, pasting raw SVG path data directly into the stylesheet.
Making SVG Text Wrapping Responsive
To ensure the text wrapping adapts to viewport changes without breaking the layout, the SVG and its container must use relative units and scalable coordinates.
- Use the
viewBoxAttribute: Ensure your SVG uses aviewBoxrather than hardcodedwidthandheightattributes, allowing the vector graphic to scale proportionally. - Fluid Dimensions: Set the floated SVG container’s
width using percentages (
%) or viewport units (vw), paired withmax-widthto prevent over-expansion on large displays. - Coordinate Mapping with
clip-path: Pairshape-outsidewithclip-pathif you need the visual background or image of the floated element to match the invisible boundary where the text is wrapping.
Practical Implementation
Here is an example demonstrating a responsive circular curve wrapping text using an SVG data structure:
<div class="shape-container">
<svg class="curved-shape" viewBox="0 0 100 100" preserveAspectRatio="none">
<!-- Visual representation matching the shape boundary -->
<path d="M0,0 Q100,50 0,100 Z" fill="#f0f0f0" />
</svg>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio.
Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at
nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec
tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget
nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra.
</p>
</div>.curved-shape {
float: left;
width: 30vw;
max-width: 250px;
min-width: 120px;
height: auto;
aspect-ratio: 1 / 1;
shape-outside: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M0,0 Q100,50 0,100 Z" fill="black"/></svg>');
shape-margin: 1.5rem;
}Controlling Spacing and Boundaries
shape-margin: Standard CSS margins only apply to the outer rectangular boundary of an element. Use theshape-marginproperty to add spacing specifically around the dynamic shape outline.shape-image-threshold: When using image or SVG alpha masks, this property sets the opacity threshold (from0.0to1.0) that defines which pixels form the wrap boundary. Pixels with an opacity greater than the threshold become part of the shape.