Cloud Four Blog

Technical notes, War stories and anecdotes

Breaking Out With Viewport Units and Calc

While iterating on a new article layout for the impending Cloud Four redesign, I encountered an old CSS layout problem.

For long-form content, it’s usually a good idea to limit line lengths for readability. The most straightforward way to do that is to wrap the post content in a containing element:

.u-containProse {
  max-width: 40em;
  margin-left: auto;
  margin-right: auto;
}
<div class="u-containProse">
  <p>...</p>
  <p>...</p>
</div>

But what if we want some content to extend beyond the boundaries of our container? Certain images might have greater impact if they fill the viewport:

Mockup of container with full-width element

In the past, I’ve solved this problem by wrapping everything but full-width imagery:

<div class="u-containProse">
  <p>...</p>
</div>
<img src="..." alt="...">
<div class="u-containProse">
  <p>...</p>
</div>

But adding those containers to every post gets tedious very quickly. It can also be difficult to enforce within a content management system.

I’ve also tried capping the width of specific descendent elements (paragraphs, lists, etc.):

.u-containProse p,
.u-containProse ul,
.u-containProse ol,
.u-containProse blockquote/*, etc. */ {
  max-width: 40em;
  margin-left: auto;
  margin-right: auto;
}

Aside from that selector giving me nightmares, this technique might also cause width, margin or even float overrides to behave unexpectedly within article content. Plus, it won’t solve the problem at all if your content management system likes to wrap lone images in paragraphs.

The problem with both solutions is that they complicate the most common elements (paragraphs and other flow content) instead of the outliers (full-width imagery). I wondered if we could change that.

Flipping the Script

To release our child element from its container, we need to know how much space there is between the container edge and the viewport edge… half the viewport width, minus half the container width. We can determine this value using the calc() function, viewport units and good ol’ percentages (for the container width):

.u-release {
  margin-left: calc(-50vw + 50%);
  margin-right: calc(-50vw + 50%);
}

Voilà! Any element with this class applied will meet the viewport edge, regardless of container size. Here it is in action:

See the Pen Full-width element in fixed-width container example by Tyler Sticka (@tylersticka) on CodePen.

Browsers like Opera Mini that don’t support calc() or viewport units will simply ignore them.

One Big, Dumb Caveat

When I found this solution, I was thrilled. It seemed so clever, straightforward, predictable and concise compared to my previous attempts. It was in the throes of patting myself on the back that I first saw it…

An unexpected scrollbar:

On any page with this utility class in use, a visible vertical scrollbar would always be accompanied by an obnoxious horizontal scrollbar. Shorter pages didn’t suffer from this problem, and browsers without visible scrollbars (iOS Safari, Android Chrome) seemed immune as well. Why??

I found my answer buried deep in the spec (emphasis mine):

The viewport-percentage lengths are relative to the size of the initial containing block. When the height or width of the initial containing block is changed, they are scaled accordingly. However, when the value of overflow on the root element is auto, any scroll bars are assumed not to exist. Note that the initial containing block’s size is affected by the presence of scrollbars on the viewport.

Translation: Viewport units don’t take scrollbar dimensions into account unless you explicitly set overflow values to scroll. But even that doesn’t work in Chrome or Safari (open bugs here and here).

I reacted to this information with characteristic poise:

Not reacting with poise at all

Luckily, a “fix” was relatively straightforward:

html,
body {
  overflow-x: hidden;
}

It’s just a shame that it’s even necessary.

Mood Boards (Neither Bored Nor Moody)

Our team had a set of defining characteristics and was almost ready to start redesigning cloudfour.com. But before we dived into element collages (more on that in a future post), we wanted to draw from a shared well of design inspiration. So we decided to make a mood board.

A mood board is a collage of reference imagery from the outside world with some relevance to the project in question. It can include examples of typography, colors, illustrations, photography or other stylistic elements. Traditionally, you’d assemble one from magazine clippings or whatever else you didn’t mind cutting up and gluing to foam core.

Photo of traditional mood board exercise in progress circa 2009

We decided against the cut-and-paste method for a couple of reasons:

  • Most of the team’s favorite sources of inspiration are easier to assemble digitally than in physical form. One could argue that the value of a mood board exercise is in exploring sources outside one’s typical frame of reference, but for this project it felt like a poor fit.
  • By this point, our team was engaged in parallel projects that made scheduling a day-long, in-person exercise difficult to coordinate.

Digital mood boards are nothing new, and there are plenty of tools to choose from (InVision’s being particularly impressive). We decided to use Pinterest, simply because most of our team was already using it.

Over the next few days, we assembled 79 pins into the cloudfour.com mood board:

Screenshot of our Pinterest mood board

Although our team members contributed independently, the overall tone of the board is fairly cohesive (possibly owing to our earlier characteristics exercise). This gave us the inspirational mind-meld we needed for the next design phase.

Shared Visions and Sticky Notes

When we started redesigning cloudfour.com, I knew I wanted the entire team to feel a sense of ownership in the end result. To establish an inclusive design direction without designing a camel, we had to distill the collective input of every team member into one guiding vision… a singular “us.”

Fortunately for us, few problems in the universe cannot be solved by getting in a room and writing things on sticky notes.

After broadly discussing our hopes and dreams for the redesign, we jotted down words on stickies that described how we wanted Cloud Four to feel.

Each of us presented and clustered these notes on the whiteboard, grouping those that seemed thematically related.

Collage of sticky note exercise photos

Then, we agreed on informal titles for each cluster. These became (in no particular order):

  • Leadership
  • Academic
  • Open
  • Ahead
  • Craft
  • Integrity
  • Cheerful
  • Web ❤
  • Responsive
  • You
  • Boutique
  • Portland

We managed to swiftly condense 93 sticky notes from nine team members into twelve tidy descriptors. I call that a successful exercise!

These directly informed our mood boards… but that’s a story for another post!

Simpler SVG Icons

As a follow-up to my post discouraging the use of icon fonts, I recently wrote about the SVG icon process we’ve been using at Cloud Four. While most of the feedback I received was positive, some felt the steps I described seemed complicated, even intimidating.

I can’t entirely disagree. Our designers find the process easy to use (save SVG to folder, optionally update YAML file, use in HTML), but it does require quite a bit of elbow grease up-front.

And while I’d argue that our process is only modestly more complex than comparable icon font setups (examples here, here, here and here), I completely understand how it might feel overwhelming to anyone new to the SVG format (which is most of us, if we’re honest).

So I thought it might be helpful (and fun!) to devote a post to some of the simpler ways you can start using SVG icons today. Whether these options serve as your “toe in the water” or your production-ready technique of choice, I think you’ll find all of them more approachable.

Use Images

SVG is an image format, which means you can use it just like an image:

<img src="my-icon.svg" alt="Niftiest Icon Ever">

Crazy, right? Or if your icons are purely decorative:

.my-icon {
  background-image: url("my-icon.svg");
  /* width, height, etc. */
}

Neither of these techniques inherit the parent element’s text color, a feature we’ve all taken for granted since 2011. But unless your site’s color palette is enormous, they’ll probably work just fine.

Copy and Paste SVG Source

We use this technique a lot when we’re prototyping. Most of the time, you can copy and paste the source of an SVG right into your HTML document:

See the Pen SVG icon pasted into HTML by Tyler Sticka (@tylersticka) on CodePen.

The markup’s a little messy and there’s no caching to speak of, but it works just fine. SVG elements can even inherit the parent text color!

(Tip: If you find yourself saving files over and over just to copy their contents, try clicking the “Show Code” button in Illustrator’s Export dialog instead. There’s also a “Copy Layer as SVG” plugin for Sketch.)

Use a GUI

Detail of IcoMoon interface

If you really want to compile your icons into a single resource but don’t want to mess with Gulp or Grunt, several web apps exist that will guide you through the process. Our favorites are:

  • IcoMoon: Can generate an SVG sprite or an icon font (or both) using any combination of stock icons or your own.
  • Grumpicon: Generates a CSS file with embedded SVG, as well as PNG fallbacks.

Both apps are free and easy to use, generating helpful code samples along with the assets themselves.

Use Pre-Made Icons

In addition to the stock icons available via the aforementioned IcoMoon, there are a growing number of SVG icon packs available. Some of the best we’ve seen so far:

  • Material icons: Google’s material design icons are open source, and available individually or as as a sprite.
  • Evil Icons: Free and open source icon pack with an intuitive markup syntax.
  • Glyph: Large icon pack available via Creative Commons.
  • Iconic: Not free, but SVG version is incredibly full-featured.
  • Resources like The Noun Project, SVG Icons and iconmonstr offer lots of great stock icons in SVG format.

If you have a favorite icon pack that doesn’t offer SVG as an option, ask for it! For example, here’s an open issue in the FontAwesome repo requesting the format.

And Many More!

SVG as a format is only as complicated as you need it to be. None of the aforementioned techniques are inherently less valid than the fancy-schmancy process we use at Cloud Four. You can start simple and stay there, or you can choose to expand on your process later on.

So give it a try! It’s probably less scary than you think.