Beyond Scaling: A Smarter Way To Make SVGs Responsive

SVG files scale beautifully, but scaling alone doesn’t solve layout problems. A 16:9 scene that looks sharp on a desktop monitor can lose all its impact when squeezed into a portrait phone screen. Repositioning elements within the SVG to suit different aspect ratios is the hard part, because internal coordinates are locked to the original viewBox. Animations and interactions that depend on those positions break the moment the viewport changes.

Andy Clarke’s approach to this problem — which he demonstrates with a 1959 Quick Draw McGraw title card recreated as a 1920×1080 SVG — is to treat SVG artwork as a library of reusable components rather than a single monolithic file. The technique hinges on three pieces working together: the <symbol> element for defining graphics once, the <use> element for placing instances of those graphics into multiple layouts, and CSS media queries for deciding which layout is displayed at which screen size.

The Obvious Alternatives Fall Short

Two common approaches to serving different artwork at different breakpoints fail on closer inspection. The first, showing or hiding two separate inline SVGs with CSS, means both versions are downloaded even when only one is visible. For complex artwork, that is a lot of wasted bytes.

The second, swapping SVGs via JavaScript at a specified breakpoint, has similar issues: both files typically load anyway, the DOM gets heavier, and the design becomes dependent on JavaScript. Maintenance also becomes a burden — now there are two copies of the artwork to keep in sync. A small change, like altering the shape of a character’s tail, must be made twice.

The <picture> element is not a useful alternative here either. It works with external SVG files treated as images, which means CSS cannot animate or style the internal elements.

Building A Symbol Library

The core of the solution is to stop exporting a single SVG and start exporting elements individually, each with its own viewBox. That detail matters because every <symbol> must have its own viewBox to define its internal coordinate system. Rather than exporting all elements using the same viewBox size — the usual workflow — each element is exported as its own separately sized SVG.

Those individual SVGs are converted into <symbol> elements. The SVG tags are swapped for <symbol> tags, and the artwork is added to a hidden SVG library. This approach delivers a DRY codebase: a <symbol> is defined once, and any future updates automatically propagate to every instance where it is used.

Reusing Symbols Across Layouts

With a library of symbols in place, multiple visible SVGs can be created — one arranged for small screens and another for larger ones. Each of those SVGs contains <use> elements that reference the symbols by their href.

Symbols behave like <g> groups, so each <use> instance can be positioned and scaled independently using attributes such as width, height, and transform. This is a significant advantage: instead of repositioning elements inside the SVG, you reposition the references. The internal layout stays clean, and since the browser loads the artwork only once, bandwidth and rendering time are reduced.

Animation Constraints And Workarounds

Animating these adaptive SVGs introduces a complication. CSS animations targeting elements inside a <symbol> do not work because <use> creates shadow DOM clones that cannot be easily targeted. The animation must be applied to the <use> element itself, not to the internal content.

For cases where specific parts of a graphic need to move — a hat tilting, legs kicking — the fix is to make each movable part its own symbol. Inside the library SVG, a <g> wrapper is placed around the part to be animated within the <symbol>. The animation can then target the <use> element using an attribute substring selector on its href.

Controlling Display With CSS

The final step is presentation logic handled entirely by CSS media queries. The small-screen SVG is shown by default. A min-width query at 64rem and above hides that version and reveals the large-screen SVG instead.

At any given viewport width, only one visible SVG is in the DOM. The hidden symbol library ensures the artwork is downloaded once, regardless of how many layouts reference it. The result is a lightweight, maintainable system that repositions elements without duplicating content, loading extra assets, or requiring JavaScript.

The technique is a useful reminder that some of the web’s most effective solutions rely on fundamentals — in this case, a bit of SVG know-how and a clever use of the platform’s built-in capabilities.