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.

Thank you!

@dudleystorey

thenewcode.com