Creating a Dynamic, Repeating SVG Divider with CSS

Using a custom SVG pattern for a horizontal divider (<hr />) is a great way to add unique visual flair to your website. However, styling decorative dividers across dark and light themes often becomes cumbersome if you rely on static image assets.

The ideal solution should achieve two goals:

  • Color inheritance: Automatically adapt to the current text color using currentColor.
  • Maintainability: Allow you to update the graphic once in a single location and have it apply across your entire site.

Here are the modern, production-ready ways to loop an SVG as an <hr /> element.

Method 1: CSS mask-image with currentColor (Recommended)

The cleanest and most robust modern solution is using CSS masking. By combining background-color: currentColor with mask-image (or -webkit-mask-image for maximum compatibility), your <hr /> takes the inherited text color while repeating the SVG silhouette across the horizontal axis.

HTML

<div class="content-box">
  <p>Some preceding content text...</p>
  <hr class="svg-divider" />
  <p>Some subsequent content text...</p>
</div>

CSS

.svg-divider {
  border: none;
  height: 24px;
  background-color: currentColor;
  
  /* Webkit support for Safari/Chrome */
  -webkit-mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 40"><path d="M10,10 c 5.21,-7 25.61,-8.79 37.72,0.1 l 42.6,31.17 c -5.21,7 -25.61,8.79 -37.72,-0.1 z" fill="%23000" /></svg>');
  -webkit-mask-repeat: repeat-x;
  -webkit-mask-size: auto 100%;
  -webkit-mask-position: center;

  /* Standard CSS Mask */
  mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 40"><path d="M10,10 c 5.21,-7 25.61,-8.79 37.72,0.1 l 42.6,31.17 c -5.21,7 -25.61,8.79 -37.72,-0.1 z" fill="%23000" /></svg>');
  mask-repeat: repeat-x;
  mask-size: auto 100%;
  mask-position: center;

  margin: 2rem 0;
}

Why this works so well:

  • The mask shape only cares about alpha channels (transparency), meaning the SVG color in the data URI doesn't matter.
  • The actual visible color comes directly from background-color: currentColor, automatically adapting to dark and light modes.
  • You can replace the inline SVG data URI with an external file reference like url('/assets/divider-shape.svg') to keep your CSS clean and maintain a single source of truth.

Method 2: Native SVG <pattern> with currentColor

If you prefer an SVG-first approach, or need to manage complex overlaps where shapes step over each other precisely, using an SVG <pattern> element is another powerful option.

Pattern Code

<svg class="site-divider" width="100%" height="30" role="separator" aria-label="Divider">
  <defs>
    <!-- Adjust pattern width and height to control tiling distance -->
    <pattern id="swirl-pattern" width="50" height="30" patternUnits="userSpaceOnUse">
      <path
        d="m 0,5 c 5.21,-7 25.61,-8.79 37.72,0.1 l 42.6,31.17 c -5.21,7 -25.61,8.79 -37.72,-0.1 z"
        fill="currentColor"
      />
    </pattern>
  </defs>
  <rect width="100%" height="100%" fill="url(#swirl-pattern)" />
</svg>

How to Handle Overlapping Shapes in a Pattern

Inkscape calculates pattern bounding boxes based on the outer rectangular bounds of the path. To achieve overlapping tiles along an angle:

  • Ensure the <pattern> width is smaller than the bounding box width of your path (e.g., if the path is 80px wide, set the pattern width="50").
  • Duplicate or position parts of the path within the pattern cell so they overflow gracefully into the next tile.
  • Keep fill="currentColor" on the <path> so it automatically adopts the CSS color of the parent container.

Summary: Which Approach Should You Use?

  • Use CSS mask-image if you want standard semantic <hr /> elements in your HTML and want to manage the styling completely in your global stylesheet.
  • Use SVG <pattern> if your design requires complex internal SVG interactions, gradients, or strict coordinate-based multi-path tiling.