In a previous article I detailed how to create an SVG branding module that automatically adapted to different screen sizes. While that solution works, it has one disadvantage: even as the logo simplifies and grows smaller, the aspect ratio of the SVG viewBox remains the same, meaning that the logo takes up less space inside the available area. This is particular problematic when the branding changes from a rectangular format to square one, like the example above.

Maintaining Overwatch

While I don’t play the game, I very much admired the logo design of Blizzard’s new Overwatch; it also happens to typify the rectangle-to-square problem discussed above.

The logo is built from three primary components: a stylized circle (divided into two sections), the logo text, and some triangles. Each of these is given a class, with the circle components placed inside an SVG group element:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 200" id="overwatch-logo">
    <g class="overwatch-circle">
        <path class="overwatch-uppercircle" d="…"/>
        <path class="overwatch-lowercircle" d="…"/>
    </g>
    <path class="overwatch-text" d="…"/>
    <path class="overwatch-triangles" d="…"/>
</svg>

The viewBox, as initially defined, contains the entire logo. Components are styled with CSS:

.overwatch-text, .overwatch-lowercircle { fill: #4A4C4E; }
.overwatch-triangles, .overwatch-uppercircle { fill: #FA9C1E; }

Dealing with Darkness

One challenge that logos must deal with is being placed against backgrounds of different colors: white text in a logo will look fine against a dark background, but disappear when placed on a lighter color. Short of using CSS blend modes, a logo on a web site can’t “detect” what kind of background it is placed on, so it requires a single addition to the markup: a class of .dark applied to the SVG or it’s container that will change the colors used in the logo components:

.dark .overwatch-text, .dark .overwatch-lowercircle { 
    fill: white;
}

(Note that this variation isn’t shown above, but is used in the CodePen demo.)

Making an Adaptive viewBox

The adaptive CSS starts very much like the previous example: changing the visibility of components via opacity in @media queries:

@media all and (max-width: 800px) {
  .overwatch-circle {
    opacity: 0;
  }
}
@media all and (max-width: 500px) {
  .overwatch-circle {
    opacity: 1;
  }
  .overwatch-text, .overwatch-triangles {
    opacity: 0;
  }
}

The problem, as detailed above, is that the circle component, when shown by itself, will remain in a rectangular space, taking up a lot of room. I’ve highted the unaltered viewBox to illustrate this:

Unaltered viewBox higlighted, showing wasted space

In order to address that, we need to change the viewBox - the visible “canvas area” of the SVG. Unfortunately, we can’t yet do that with , forcing us to use instead:

var svg = document.getElementById("overwatch-logo"),
origviewbox = svg.getAttribute("viewBox"),
overwatch = window.matchMedia("(min-width: 801px)"),
overtext = window.matchMedia("(max-width: 800px)"),
overcircle = window.matchMedia("(max-width: 500px)");

function boxChange(coords) {
    svg.setAttribute("viewBox", coords);
}

window.onresize = function(){
    if (overtext.matches) {
        boxChange("0 140 350 200");
    }
    if (overcircle.matches) {
        boxChange("100 0 150 140");
    }
    if (overwatch.matches) {
        boxChange(origviewbox);
    }
}

While this JavaScript can be placed inside the SVG, this interactivity does not “bleed” through if the SVG file is used as an image. For now, this means that the SVG logo would need to be applied as in inline element.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/qZzxqO