RWD & SVG
@dudleystorey
thenewcode.com
Making Responsive SVG Icons & Logos
In modern browsers and under normal conditions, SVG icons and logos are fully responsive if five rules are followed during design & development:
One:
Design & build SVG icons & logos at the approximate pixel dimensions they will appear on-screen (~ 50 × 50px for icons, as needed for logos)
Two:
Ensure that your design tool is set up & used correctly. (Strokes in the middle of paths, exporting styles as CSS, boolean paths rather than superimposed layers, etc).
http://thenewcode.com/821/Adobe-Illustrator-Workflow-For-SVG
Similarly, draw icons at least 1px in from the edge of the viewBox to allow for browser's tendency to fractionally “bloat” SVG with anti-aliasing, which can be cut off if you draw too close to the edges.
Three:
Optimize the SVG, removing redundant code.
- SVGOMG
- Adobe Illustrator 2015.2
- Sketch Beta 3
Four:
Since SVG is a replaced element, linked CSS that doesn't load will leave an SVG element rendered at 300 × 150 by default, so icons should have fallback width and height attributes:
<a href="http://codepen.io"> <svg class="icon" aria-label="CodePen" width="50" height="50"> <title>Codepen</title> <use xlink:href="#codepen" /> </svg> </a> <svg style="display: none;"> <symbol id="codepen" viewBox="0 0 50 50"> <path d="…"/> </symbol> </svg>
http://codepen.io/dudleystorey/pen/MKxrEr
http://fvsch.com/code/svg-icons/how-to/
Five:
Deal with Internet Explorer (this will take awhile…)
Hot take for logos:
If width and height attributes are removed, every modern browser assumes SVG elements (as either img or inline) are width: 100%, and automatically sets height proportionally.
That is, except for IE
In IE9 - 11, the browser sets the height of the SVG <img> to its replaced default (150px), and its width to 100%, distorting the image.
To fix:
Write a CSS rule to impose the standard approach on IE:
img[src$=".svg"] { width: 100% }
img { width: 100% }
(or, safer…)
However… inline SVG is different
It requires a container element and a "padding hack"
Why inline SVG?
- Save an HTTP request
- Direct access to SVG elements
<div class="svg-container"> <svg viewBox="0 0 500 500" preserveAspectRatio="xMinYMin meet"> <path d="…" /> </svg> </div>
This SVG is square (width equal to height) so the padding amount will be 100%:
.svg-container { display: block; position: relative; width: 100%; padding-bottom: 100%; vertical-align: middle; }
Then the SVG within it uses the absolute-in-relative trick:
.svg-container svg {
display: block;
position: absolute;
top: 0;
left: 0;
}
More tips for icons and logos:
In SVG stroke thickness automatically scales with image size. While this is often appropriate, sometimes (such as strokes on UI elements or text) it shouldn't:
path { stroke-width: 4; vector-effect: non-scaling-stroke; }
Consider adaptive logos:
Responsive design is not just about making things smaller; it is about presenting appropriate content at all viewport sizes.
“Traditionally” this was one with SVG sprites: moving an SVG image of multiple drawings in a fixed space to show one at a time.
While this technique remains entirely possible, it necessitates a lot of duplication (and associated large file size). Instead, I'd encourage designers to consider adaptive designs: using media queries to directly affect SVG elements, changing them as needed.
(responsivelogos.co.uk, as one example)
http://codepen.io/dudleystorey/pen/xZzowx
Interestingly, media queries can be placed inside the SVG itself, allowing to you create independent element queries for SVG documents that are inserted as <img> tags, <object>, or background images.
<svg xmlns="…2000/svg" viewBox="14 82 272 139">
<defs>
<style>
@media all and (max-width: 200px) {
#drink, #coke { opacity: 0; }
}
…the difference being that media queries placed inside an SVG respond to the current width of the SVG, not the viewport: they can't "look outside" the <img> context. This can be an advantage, but requires a slightly different mindset to execute well.
Making Responsive Hero Text
vw units can be used to size hero text, but the current lack of "clamping" for font-size in CSS means extra media queries. Alternatively, use SVG (especially inline, due to accessibility)
thenewcode.com/363/Creating-Responsive-Hero-Text-with-SVG
<header>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 285 80">
<text x="0" y="66">Kauai</text>
</svg>
</header>
header { width: 80%; margin: 0 auto; }
svg text {
font-family: sans-serif;
text-transform: uppercase;
font-weight: 900;
fill: blue;
}
Other recent experiments:
http://thenewcode.com/633/Boom-Wham-Pow-Comic-Book-FX-Lettering-with-SVG-Filters
http://thenewcode.com/810/Web-Developer-Reading-List-SVG-Text
The Future:
SVG 2 (https://www.w3.org/TR/SVG2/)
- expected to be taken on by browsers much as HTML5 / ES6 / new CSS Modules were: version-less, incremental evolution
- in some respects, simpler syntax, closer integration: no more namespacing links, for example.
- mesh gradients will create broader use of SVG in responsive, “photo-real” illustrations.