How to structure your typography in Sass

I’ve always been focused on strong typography when it comes to design. As I’ve evolved into a front end developer, I still focus a lot on the typography of a project. As I’ve written about before, if the design is up to me, I even start with setting the paragraph.

However, what can you do to set yourself up for success when it comes to coding a design and it’s typography? I’ve done this – a lot – and I’ve come to some conclusions.

Some of my guiding principles are:

  • Do the absolute least amount possible. I’ve seen a lot of projects where other developers write and re-write chunks of code they don’t need, and in fact are adding to maintenance headaches down the road.
  • Err on the side of commonality. The more common a type treatment is, the more global it’s application. I’m not saying special one-off treatments are bad, just that as a developer you need to focus on the common ones more.
  • Make your life as easy as possible. Use a preprocessor (the rest of this post will be about Sass) and make smart use of it’s features.

So what does this look like in an actual project?

  1. Determine the paragraph style. I typically start development at the same place I start a design: the treatment of the paragraph. If I’ve been supplied with a visual design, I look for what treatment could be considered the most common, “body copy” style.
  2. Set up your font stacks. Most designs I deal with make use of 1 to 3 typefaces. (Any more than this and there needs to be an intervention) Those typically are a serif, a sans-serif, and possibly some kind of accent typeface. Knowing this, I’ll set up my font stacks as SASS variables very early on in the project:

    $sans-serif:  "Source Sans Pro", Helvetica, Verdana, sans-serif;
    $serif: Merriweather, Georgia, 'Times New Roman', serif;
    $mono: 'Source Code Pro', Courier, mono;

    The above example is from this very website’s variables partial. (In my case my third typeface is used for code examples).

  3. Set your font weights as variables. This is really useful if the design switches from using a 700 weight to a 900 weight for bold, for instance.

    $light: 300;
    $normal: 400;
    $semibold: 500;
    $bold: 700;
  4. Style the body element. This is where I typically see other developers missing an opportunity to make their lives easier, so this is really the point of the post. If you apply the paragraph typographic style to your body element, you will save yourself a lot of rework. If you’ve identified the most common typographic treatment (see Step 1), you can style your <body> element with that treatment. This has three advantages –

    1. You save yourself a lot of redeclaration of font-famlies, colors and so on.
    2. And in so doing you’ll acheive greater consistency, as there are fewer declarations to get wrong or maintain later.
    3. There will be a baseline deliberate styling of text, in the event you don’t think to style some element down the line.

    Here is what this website’s body element looks like:

    body {
      font-family: $sans-serif;
      font-weight: $light;
      color: $txt-primary;  //color variable set elsewhere
      background: $body-bg;
      -webkit-text-size-adjust: 100%;  //fix for iOS
    }

This is usually constrained just to the font-family, font-weight, color, and sometimes line-height declarations. You’re not going to want to apply box-model properties to the <body> element.

With this styling in place, you can start changing the style of elements by making use of the font-weight and font-style property, which goes back to the “least amount possible” principle. By relying on those styling switches, governing the overall typeface becomes much easier.

Now, when you want to call in your secondary or accent typeface, you deliberately declare it where needed, and that’s it.

h1 {
  font-family: $serif;
}

And since you already have your font stacks declared as variables, you can govern that type choice much more easily.

I hope these guidelines and basic steps help you in your next project. If you have any other ways to make your life easier, please share them in the comments!

  • Great post, Chip! Something else that I find helpful is to set my font weights as variables, so that if down the road we decide to change our “bold” treatments from 700 to 900, for instance, it only has to be changed in one place… Learned that lesson the hard way once or twice.

    • Chip Cullen

      I actually do that on most projects, too. I just hadn’t on this site, which was where I was getting my code samples.

    • Chip Cullen

      FYI I updated the post to include your idea – thanks, Abby!

  • andysolomon

    Nice, but shouldn’t we use a separate font-file for ‘bold’, ‘italics’, and other font-weights.

    • Chip Cullen

      Andy – you are right in saying that different font weights and styles need different files. That is typically handled in your @font-face declarations, which I didn’t get into in this article. I might do a follow up, as there seems to be some confusion around this point.

  • Good tips, but no mention of managing font size. I find the naming conventions of my font size variables a pain, whether to go with: $title-size, $subheader-size, $paragraph-size etc, or just $large, $medium, $small etc. Also, setting sizes on the various h1, h2, h3 etc tags feels somewhat restrictive semantically. What is clear is defining them in ems is a must. I set a px value on the body which changes responsively and alters all the font sizes accordingly across all screens. Anyone got different methods/other insights?

    • Chip Cullen

      There is no real clear answer here, in my experience. I’ve seen projects start out with the best of intentions with nicely defined variables for font sizes, but invariably during implementation font-size tends to devolve into lots of one-off size declarations. It usually is due to a designer wanting this or that element “bumped up by a pixel” in order to achieve the visual effect they are after. I usually let this slide because when it comes to font size, it’s better to rely on your eye than set values to make things look “right”.