{"id":1080,"date":"2025-10-06T13:00:00","date_gmt":"2025-10-06T13:00:00","guid":{"rendered":"https:\/\/computercoursesonline.com\/?p=1080"},"modified":"2025-10-09T21:01:56","modified_gmt":"2025-10-09T21:01:56","slug":"smashing-animations-part-5-building-adaptive-svgs-with-and-css-media-queries","status":"publish","type":"post","link":"https:\/\/computercoursesonline.com\/index.php\/2025\/10\/06\/smashing-animations-part-5-building-adaptive-svgs-with-and-css-media-queries\/","title":{"rendered":"Smashing Animations Part 5: Building Adaptive SVGs With “, “, And CSS Media Queries"},"content":{"rendered":"

Smashing Animations Part 5: Building Adaptive SVGs With `<symbol>`, `<use>`, And CSS Media Queries<\/title><\/p>\n<article>\n<header>\n<h1>Smashing Animations Part 5: Building Adaptive SVGs With `<symbol>`, `<use>`, And CSS Media Queries<\/h1>\n<address>Andy Clarke<\/address>\n<p> 2025-10-06T13:00:00+00:00<br \/>\n 2025-10-09T20:32:45+00:00<br \/>\n <\/header>\n<p>I\u2019ve written quite a lot recently about how I <a href=\"https:\/\/www.smashingmagazine.com\/2025\/06\/smashing-animations-part-4-optimising-svgs\/\">prepare and optimise<\/a> SVG code to use as static graphics or in <a href=\"https:\/\/www.smashingmagazine.com\/2025\/05\/smashing-animations-part-1-classic-cartoons-inspire-css\/\">animations<\/a>. I love working with SVG, but there\u2019s always been something about them that bugs me.<\/p>\n<p>To illustrate how I build adaptive SVGs, I\u2019ve selected an episode of <em>The Quick Draw McGraw Show<\/em> called \u201c<a href=\"https:\/\/yowpyowp.blogspot.com\/2012\/06\/quick-draw-mcgraw-bow-wow-bandit.html\">Bow Wow Bandit<\/a>,\u201d first broadcast in 1959.<\/p>\n<figure class=\"\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/1-quick-draw-mcgraw-show.png\"><\/p>\n<p> <img loading=\"lazy\" width=\"800\" height=\"450\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Bow Wow Bandit illustration\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/1-quick-draw-mcgraw-show.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n The Quick Draw McGraw Show \u00a9 Warner Bros. Entertainment Inc. (<a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/1-quick-draw-mcgraw-show.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>In it, Quick Draw McGraw enlists his bloodhound Snuffles to rescue his sidekick Baba Looey. Like most Hanna-Barbera title cards of the period, the artwork was made by Lawrence (Art) Goble.<\/p>\n<div class=\"refs\">\n<ul>\n<li><a href=\"https:\/\/www.smashingmagazine.com\/2025\/05\/smashing-animations-part-1-classic-cartoons-inspire-css\/\">Smashing Animations Part 1: How Classic Cartoons Inspire Modern CSS<\/a><\/li>\n<li><a href=\"https:\/\/www.smashingmagazine.com\/2025\/05\/smashing-animations-part-2-css-masking-add-extra-dimension\/\">Smashing Animations Part 2: How CSS Masking Can Add An Extra Dimension<\/a><\/li>\n<li><a href=\"https:\/\/www.smashingmagazine.com\/2025\/05\/smashing-animations-part-3-smil-not-dead\/\">Smashing Animations Part 3: SMIL\u2019s Not Dead Baby, SMIL\u2019s Not Dead<\/a><\/li>\n<li><a href=\"https:\/\/www.smashingmagazine.com\/2025\/06\/smashing-animations-part-4-optimising-svgs\/\">Smashing Animations Part 4: Optimising SVGs<\/a><\/li>\n<\/ul>\n<\/div>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/2-andy-clarke-bow-wow-bandit-toon-title-recreation.png\"><\/p>\n<p> <img loading=\"lazy\" width=\"800\" height=\"450\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Quick Draw McGraw character pulling back on a dog leash attached to his bloodhound, Snuffles.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/2-andy-clarke-bow-wow-bandit-toon-title-recreation.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Andy Clarke\u2019s Bow Wow Bandit Toon Title recreation (16:9). (<a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/2-andy-clarke-bow-wow-bandit-toon-title-recreation.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>Let\u2019s say I\u2019ve designed an SVG scene like that one that\u2019s based on Bow Wow Bandit, which has a 16:9 aspect ratio with a <code>viewBox<\/code> size of 1920\u00d71080. This SVG scales up and down (the clue\u2019s in the name), so it looks sharp when it\u2019s gigantic and when it\u2019s minute.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/3-svgs-aspect-ratio.png\"><\/p>\n<p> <img loading=\"lazy\" width=\"800\" height=\"450\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"16:9 aspect ration vs. 3:4.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/3-svgs-aspect-ratio.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Left: 16:9 aspect ratio loses its impact. Right: 3:4 format suits the screen size better. (<a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/3-svgs-aspect-ratio.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>But on small screens, the 16:9 aspect ratio (<a href=\"https:\/\/stuffandnonsense.co.uk\/toon-titles\/quick-draw-3a.html\">live demo<\/a>) might not be the best format, and the image loses its impact. Sometimes, a portrait orientation, like 3:4, would suit the screen size better.<\/p>\n<figure class=\"\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/4-bow-wow-bandit-toon-title-recreation-portrait.png\"><\/p>\n<p> <img loading=\"lazy\" width=\"800\" height=\"729\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Andy Clarke\u2019s Bow Wow Bandit Toon Title recreation (3:4).\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/4-bow-wow-bandit-toon-title-recreation-portrait.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Andy Clarke\u2019s Bow Wow Bandit Toon Title recreation (3:4). (<a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/4-bow-wow-bandit-toon-title-recreation-portrait.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>But, herein lies the problem, as it\u2019s not easy to reposition internal elements for different screen sizes using just <code>viewBox<\/code>. That\u2019s because in SVG, internal element positions are locked to the coordinate system from the original <code>viewBox<\/code>, so you can\u2019t easily change their layout between, say, desktop and mobile. This is a problem because animations and interactivity often rely on element positions, which break when the <code>viewBox<\/code> changes.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/5-svg-smaller-larger-screens.png\"><\/p>\n<p> <img loading=\"lazy\" width=\"800\" height=\"450\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Left: 16:9 for larger screens. Right: 3:4 for smaller screens.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/5-svg-smaller-larger-screens.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Left: 16:9 for larger screens. Right: 3:4 for smaller screens. (<a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/5-svg-smaller-larger-screens.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>My challenge was to serve a 1080\u00d71440 version of Bow Wow Bandit to smaller screens and a different one to larger ones. I wanted the position and size of internal elements — like Quick Draw McGraw and his dawg Snuffles — to change to best fit these two layouts. To solve this, I experimented with several alternatives.<\/p>\n<p><strong>Note:<\/strong> Why are we not just using the <code><picture><\/code> with external SVGs? The <a href=\"https:\/\/www.smashingmagazine.com\/2014\/05\/responsive-images-done-right-guide-picture-srcset\/\"><code><picture><\/code> element<\/a> is brilliant for responsive images, but it only works with raster formats (like JPEG or WebP) and external SVG files treated as images. That means that you can\u2019t animate or style internal elements using CSS.<\/p>\n<div data-audience=\"non-subscriber\" data-remove=\"true\" class=\"feature-panel-container\">\n<aside class=\"feature-panel\">\n<div class=\"feature-panel-left-col\">\n<div class=\"feature-panel-description\">\n<p>Meet <strong><a data-instant href=\"https:\/\/www.smashingconf.com\/online-workshops\/\">Smashing Workshops<\/a><\/strong> on <strong>front-end, design & UX<\/strong>, with practical takeaways, live sessions, <strong>video recordings<\/strong> and a friendly Q&A. With Brad Frost, St\u00e9ph Walter and <a href=\"https:\/\/smashingconf.com\/online-workshops\/workshops\">so many others<\/a>.<\/p>\n<p><a data-instant href=\"smashing-workshops\" class=\"btn btn--green btn--large\">Jump to the workshops \u21ac<\/a><\/div>\n<\/div>\n<div class=\"feature-panel-right-col\"><a data-instant href=\"smashing-workshops\" class=\"feature-panel-image-link\"><\/p>\n<div class=\"feature-panel-image\">\n<img loading=\"lazy\" class=\"feature-panel-image-img lazyload\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Feature Panel\" width=\"257\" height=\"355\" data-src=\"\/images\/smashing-cat\/cat-scubadiving-panel.svg\"><\/p>\n<\/div>\n<p><\/a>\n<\/div>\n<\/aside>\n<\/div>\n<h2 id=\"showing-and-hiding-svg\">Showing And Hiding SVG<\/h2>\n<p>The most obvious choice was to include two different SVGs in my markup, one for small screens, the other for larger ones, then show or hide them using <a href=\"https:\/\/www.smashingmagazine.com\/2018\/02\/media-queries-responsive-design-2018\/\">CSS and Media Queries<\/a>:<\/p>\n<pre><code class=\"language-svg\"><svg id=\"svg-small\" viewBox=\"0 0 1080 1440\">\n <!-- ... -->\n<\/svg>\n\n<svg id=\"svg-large\" viewBox=\"0 0 1920 1080\">\n <!--... -->\n<\/svg>\n\n\n#svg-small { display: block; }\n#svg-large { display: none; }\n\n@media (min-width: 64rem) {\n #svg-small { display: none; }\n #svg-mobile { display: block; }\n}\n<\/code><\/pre>\n<p>But using this method, both SVG versions are loaded, which, when the graphics are complex, means downloading lots and lots and lots of unnecessary code.<\/p>\n<h2 id=\"replacing-svgs-using-javascript\">Replacing SVGs Using JavaScript<\/h2>\n<p>I thought about using JavaScript to swap in the larger SVG at a specified breakpoint:<\/p>\n<pre><code class=\"language-javascript\">if (window.matchMedia('(min-width: 64rem)').matches) {\n svgContainer.innerHTML = desktopSVG; \n} else {\n svgContainer.innerHTML = mobileSVG;\n}\n<\/code><\/pre>\n<p>Leaving aside the fact that JavaScript would now be critical to how the design is displayed, both SVGs would usually be loaded anyway, which adds DOM complexity and unnecessary weight. Plus, maintenance becomes a problem as there are now two versions of the artwork to maintain, doubling the time it would take to update something as small as the shape of Quick Draw\u2019s tail.<\/p>\n<h2 id=\"the-solution-one-svg-symbol-library-and-multiple-uses\">The Solution: One SVG Symbol Library And Multiple Uses<\/h2>\n<p>Remember, my goal is to:<\/p>\n<ul>\n<li>Serve one version of Bow Wow Bandit to smaller screens,<\/li>\n<li>Serve a different version to larger screens,<\/li>\n<li>Define my artwork just once (DRY), and<\/li>\n<li>Be able to resize and reposition elements.<\/li>\n<\/ul>\n<p>I don\u2019t read about it enough, but the <code><symbol><\/code> element lets you define reusable SVG elements that can be hidden and reused to improve maintainability and reduce code bloat. They\u2019re like components for SVG: <a href=\"https:\/\/css-tricks.com\/svg-symbol-good-choice-icons\/\">create once and use wherever you need them<\/a>:<\/p>\n<pre><code class=\"language-svg\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"display: none;\">\n <symbol id=\"quick-draw-body\" viewBox=\"0 0 620 700\">\n <g class=\"quick-draw-body\">[\u2026]<\/g>\n <\/symbol>\n <!-- ... -->\n<\/svg>\n\n<use href=\"#quick-draw-body\" \/>\n<\/code><\/pre>\n<p>A <code><symbol><\/code> is like storing a character in a library. I can reference it as many times as I need, to keep my code consistent and lightweight. Using <code><use><\/code> elements, I can insert the same symbol multiple times, at different positions or sizes, and even in different SVGs.<\/p>\n<p>Each <code><symbol><\/code> must have its own <code>viewBox<\/code>, which defines its internal coordinate system. That means paying special attention to how SVG elements are exported from apps like Sketch.<\/p>\n<div class=\"partners__lead-place\"><\/div>\n<h2 id=\"exporting-for-individual-viewboxes\">Exporting For Individual Viewboxes<\/h2>\n<p>I wrote before about <a href=\"https:\/\/www.smashingmagazine.com\/2025\/06\/smashing-animations-part-4-optimising-svgs\/\">how I export elements<\/a> in layers to make working with them easier. That process is a little different when creating symbols.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/6-exporting-elements-from-sketch.png\"><\/p>\n<p> <img loading=\"lazy\" width=\"800\" height=\"450\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/6-exporting-elements-from-sketch.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n My usual process of exporting elements from Sketch. (<a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/6-exporting-elements-from-sketch.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>Ordinarily, I would export all my elements using the same <code>viewBox<\/code>size. But when I\u2019m creating a <code>symbol<\/code>, I need it to have its own specific <code>viewBox<\/code>.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/7-exporting-elements-sketch-individual-svgs-files.png\"><\/p>\n<p> <img loading=\"lazy\" width=\"800\" height=\"450\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Exporting elements from Sketch as individual SVG files.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/7-exporting-elements-sketch-individual-svgs-files.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n Exporting elements from Sketch as individual SVG files. (<a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/7-exporting-elements-sketch-individual-svgs-files.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<p>So I export each element as an individually sized SVG, which gives me the dimensions I need to convert its content into a <code>symbol<\/code>. Let\u2019s take the SVG of Quick Draw McGraw\u2019s hat, which has a <code>viewBox<\/code> size of 294\u00d7182:<\/p>\n<pre><code class=\"language-svg\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 294 182\">\n <!-- ... -->\n<\/svg>\n<\/code><\/pre>\n<p>I swap the SVG tags for <code><symbol><\/code> and add its artwork to my SVG library:<\/p>\n<pre><code class=\"language-svg\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"display: none;\">\n <symbol id=\"quick-draw-hat\" viewBox=\"0 0 294 182\">\n <g class=\"quick-draw-hat\">[\u2026]<\/g>\n <\/symbol>\n<\/svg>\n<\/code><\/pre>\n<p>Then, I repeat the process for all the remaining elements in my artwork. Now, if I ever need to update any of my symbols, the changes will be automatically applied to every instance it\u2019s used.<\/p>\n<h2 id=\"using-a-symbol-in-multiple-svgs\">Using A <code><symbol><\/code> In Multiple SVGs<\/h2>\n<p>I wanted my elements to appear in both versions of Bow Wow Bandit, one arrangement for smaller screens and an alternative arrangement for larger ones. So, I create both SVGs:<\/p>\n<pre><code class=\"language-svg\"><svg class=\"svg-small\" viewBox=\"0 0 1080 1440\">\n <!-- ... -->\n<\/svg>\n\n<svg class=\"svg-large\" viewBox=\"0 0 1920 1080\">\n <!-- ... -->\n<\/svg>\n<\/code><\/pre>\n<p>\u2026and insert links to my symbols in both:<\/p>\n<pre><code class=\"language-svg\"><svg class=\"svg-small\" viewBox=\"0 0 1080 1440\">\n <use href=\"#quick-draw-hat\" \/>\n<\/svg>\n\n<svg class=\"svg-large\" viewBox=\"0 0 1920 1080\">\n <use href=\"#quick-draw-hat\" \/>\n<\/svg>\n<\/code><\/pre>\n<h2 id=\"positioning-symbols\">Positioning Symbols<\/h2>\n<p>Once I\u2019ve placed symbols into my layout using <code><use><\/code>, my next step is to position them, which is especially important if I want alternative layouts for different screen sizes. Symbols behave like <code><g><\/code> groups, so I can scale and move them using attributes like <code>width<\/code>, <code>height<\/code>, and <code>transform<\/code>:<\/p>\n<div class=\"break-out\">\n<pre><code class=\"language-svg\"><svg class=\"svg-small\" viewBox=\"0 0 1080 1440\">\n <use href=\"#quick-draw-hat\" width=\"294\" height=\"182\" transform=\"translate(-30,610)\"\/>\n<\/svg>\n\n<svg class=\"svg-large\" viewBox=\"0 0 1920 1080\">\n <use href=\"#quick-draw-hat\" width=\"294\" height=\"182\" transform=\"translate(350,270)\"\/>\n<\/svg>\n<\/code><\/pre>\n<\/div>\n<p>I can place each <code><use><\/code> element independently using <code>transform<\/code>. This is powerful because rather than repositioning elements inside my SVGs, I move the <code><use><\/code> references. My internal layout stays clean, and the file size remains small because I\u2019m not duplicating artwork. A browser only loads it once, which reduces bandwidth and speeds up page rendering. And because I\u2019m always referencing the same <code>symbol<\/code>, their appearance stays consistent, whatever the screen size.<\/p>\n<h2 id=\"animating-use-elements\">Animating <code><use><\/code> Elements<\/h2>\n<p>Here\u2019s where things got tricky. I wanted to animate parts of my characters — like Quick Draw\u2019s hat tilting and his legs kicking. But when I added CSS animations targeting internal elements inside a <code><symbol><\/code>, nothing happened.<\/p>\n<p><strong>Tip:<\/strong> You can animate the <code><use><\/code> element itself, but not elements inside the <code><symbol><\/code>. If you want individual parts to move, make them their own symbols and animate each <code><use><\/code>.<\/p>\n<p>Turns out, you can\u2019t style or animate a <code><symbol><\/code>, because <code><use><\/code> creates shadow DOM clones that aren\u2019t easily targetable. So, I had to get sneaky. Inside each <code><symbol><\/code> in my library SVG, I added a <code><g><\/code> element around the part I wanted to animate:<\/p>\n<pre><code class=\"language-svg\"><symbol id=\"quick-draw-hat\" viewBox=\"0 0 294 182\">\n <g class=\"quick-draw-hat\">\n <!-- ... -->\n <\/g>\n<\/symbol>\n<\/code><\/pre>\n<p>\u2026and animated it using an attribute substring selector, targeting the <code>href<\/code> attribute of the <code>use<\/code> element:<\/p>\n<pre><code class=\"language-css\">use[href=\"#quick-draw-hat\"] {\n animation-delay: 0.5s;\n animation-direction: alternate;\n animation-duration: 1s;\n animation-iteration-count: infinite;\n animation-name: hat-rock;\n animation-timing-function: ease-in-out;\n transform-origin: center bottom;\n}\n\n@keyframes hat-rock {\nfrom { transform: rotate(-2deg); }\nto { transform: rotate(2deg); } }\n<\/code><\/pre>\n<div class=\"partners__lead-place\"><\/div>\n<h2 id=\"media-queries-for-display-control\">Media Queries For Display Control<\/h2>\n<p>Once I\u2019ve created my two visible SVGs — one for small screens and one for larger ones — the final step is deciding which version to show at which screen size. I use CSS Media Queries to hide one SVG and show the other. I start by showing the small-screen SVG by default:<\/p>\n<pre><code class=\"language-css\">.svg-small { display: block; }\n.svg-large { display: none; }\n<\/code><\/pre>\n<p>Then I use a <code>min-width<\/code> media query to switch to the large-screen SVG at <code>64rem<\/code> and above:<\/p>\n<pre><code class=\"language-css\">@media (min-width: 64rem) {\n .svg-small { display: none; }\n .svg-large { display: block; }\n}\n<\/code><\/pre>\n<p>This ensures there\u2019s only ever one SVG visible at a time, keeping my layout simple and the DOM free from unnecessary clutter. And because both visible SVGs reference the same hidden <code><symbol><\/code> library, the browser only downloads the artwork once, regardless of how many <code><use><\/code> elements appear across the two layouts.<\/p>\n<figure class=\"\n \n break-out article__image\n \n \n \"><\/p>\n<p> <a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/8-final-adaptive-svg.png\"><\/p>\n<p> <img loading=\"lazy\" width=\"800\" height=\"450\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"The final adaptive SVG.\" class=\"lazyload\" data-src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/8-final-adaptive-svg.png\"><\/p>\n<p> <\/a><figcaption class=\"op-vertical-bottom\">\n View the final adaptive SVG on my <a href=\"https:\/\/stuffandnonsense.co.uk\/toon-titles\/quick-draw-3.html\">Toon Titles website<\/a>. (<a href=\"https:\/\/files.smashing.media\/articles\/smashing-animations-part-5-building-adaptive-svgs\/8-final-adaptive-svg.png\">Large preview<\/a>)<br \/>\n <\/figcaption><\/figure>\n<h2 id=\"wrapping-up\">Wrapping Up<\/h2>\n<p>By combining <code><symbol><\/code>, <code><use><\/code>, CSS Media Queries, and specific transforms, I can build <strong>adaptive SVGs<\/strong> that reposition their elements without duplicating content, loading extra assets, or relying on JavaScript. I need to define each graphic only once in a hidden symbol library. Then I can reuse those graphics, as needed, inside several visible SVGs. With CSS doing the layout switching, the <strong>result is fast and flexible<\/strong>.<\/p>\n<p>It\u2019s a reminder that some of the most powerful techniques on the web don\u2019t need big frameworks or complex tooling — just a bit of SVG know-how and a clever use of the basics.<\/p>\n<div class=\"signature\">\n <img src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" alt=\"Smashing Editorial\" width=\"35\" height=\"46\" loading=\"lazy\" class=\"lazyload\" data-src=\"https:\/\/www.smashingmagazine.com\/images\/logo\/logo--red.png\"><br \/>\n <span>(gg, yk)<\/span>\n<\/div>\n<\/article>\n","protected":false},"excerpt":{"rendered":"<p>Smashing Animations Part 5: Building Adaptive SVGs With `<symbol>`, `<use>`, And CSS Media Queries Smashing Animations Part 5: Building Adaptive SVGs With `<symbol>`, `<use>`, And CSS Media Queries Andy Clarke 2025-10-06T13:00:00+00:00 2025-10-09T20:32:45+00:00 I\u2019ve written quite a lot recently about how I prepare and optimise SVG code to use as static graphics or in animations. I…<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[11],"tags":[],"_links":{"self":[{"href":"https:\/\/computercoursesonline.com\/index.php\/wp-json\/wp\/v2\/posts\/1080"}],"collection":[{"href":"https:\/\/computercoursesonline.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/computercoursesonline.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/computercoursesonline.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/computercoursesonline.com\/index.php\/wp-json\/wp\/v2\/comments?post=1080"}],"version-history":[{"count":1,"href":"https:\/\/computercoursesonline.com\/index.php\/wp-json\/wp\/v2\/posts\/1080\/revisions"}],"predecessor-version":[{"id":1081,"href":"https:\/\/computercoursesonline.com\/index.php\/wp-json\/wp\/v2\/posts\/1080\/revisions\/1081"}],"wp:attachment":[{"href":"https:\/\/computercoursesonline.com\/index.php\/wp-json\/wp\/v2\/media?parent=1080"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/computercoursesonline.com\/index.php\/wp-json\/wp\/v2\/categories?post=1080"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/computercoursesonline.com\/index.php\/wp-json\/wp\/v2\/tags?post=1080"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}