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:

  1. 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.
  2. Inline path() Function: Use the CSS shape-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.

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