Typography
for Developers
Ben Scott / @BPScott
Who?
Web Developer @ bbc.co.uk/programmes
Not a natural visual designer
Trying not to use that as an excuse
Not a visual designer. I can look at an existing design and make offer tweaks and suggestion
Give me a blank canvas and I still go "uuuuh".
Today I'm going to talk about a few basic properties of typography, and how you can string some of them together to create a building point that you can tinker with rather than being overwhelmed by staring at a blank canvas.
95% of the information on the web is written language. It is only logical to say that a web designer should get good training in the main discipline of shaping written information, in other words: Typography.
— Oliver Reichenstein
Most information on the web is text (well apart from all those ad images and JS); we should care about it making sense. We should care about it being readable and understandable. Nobody should have to expend excessive effort to consume information.
Two Disciplines
Creative Typography
Technical Typography
Typography is split into these two very broad classifications!
Creative Typography is the typographic design of a particular project.
What font(s) you should use, what sort of mood do you want to create
(formal vs. fun, calm vs. excitable).
You wouldn't use Comic Sans for a job cover letter in the same way you wouldn't use Times New Roman for your 8 year old's birthday party invite.
This is all opinionated design - what shall work best will depend on the type of project you're working on.
Technical typography is the universal rules that apply no matter the
project. Because they're standard anybody can utilise them. This is what
this talk shall be focusing on.
But first I want to do a quick reminder on CSS properties we'll be utilising
CSS
body {
font-size: 16px;
line-height: 1.5;
}
p {
margin-bottom: 24px;
}
Font-size specifies the size of your font, you could specify this in ems or rems, but today lets keep it straight forward and deal with pixels as they're a bit easier to think about.
Line-height specifies the height of a single line of text. You can specify this in any CSS measurement like pixels, ems or rems, but I prefer the unitless notation where it's just a number. This is because the number is a ratio based on the current font-size. So in this example the line-height equates to 16px * 1.5 which is 24px.
Margin-bottom provides your spacing between elements, if you've got continuous blocks of text then you'll want your spacing between paragraphs to be equal to your line height so you give the impression of a singe line break.
Note that font-size and line-height are inherited properties, meaning that these values shall also be applied to any child elements underneath the selector you set these properties on. Whereas margin-bottom does not inherit it will only be applied to the selector you specified.
Rhythm
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.
Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
est laborum. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit
in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit
in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Dummy Text
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
Vertical Rhythm is the spacing as text flows down the page. At its base level it is how the line-height of your text repeats and create a familiar flow that feels comforting to the reader. Through careful use of spacing you can also set this up so that headings and other content that breaks up your continuous prose can fit into this rhythm without breaking it. Note how this heading appears in the middle of a block of prose but any paragraphs after it fall back into the same rhythm.
There is an ideal width to your text too. Ideally your the readers head and eyes shouldn't need to move while read, that effort while slight is repeated several times while reading and should be avoided if possible so the reader doesn't tire. The common wisdom for traditional books is to have a line be between 45 and 75 characters long, though research has shown that longer lines are just a readable on screen, probably due to how the distance between your eyes and a desktop monitor differs compared to a book or handheld electronic device.
Line-Height
Usually between 1.2 and 1.8
Larger text needs a smaller line-height
Larger x-height needs a larger line-height
So I've hinted that your line-height is the base value that all your other settings shall hang off of, so what should you set your line-height to? Well it depends. Setting it to 1 isn't appropriate as then the height of a line is equal to the size of characters in it so your text lines shall butt into the lines above and below, thus you need a bit of spacing. Values between 1.2 and 1.8 are common but this shall depend on a few things.
The size of your font is a factor - a larger font-size means you want your line-height ratio
to be a bit tighter, while you'll smaller text shall need a larger line-height to breath.
Also it depends on the font you've chosen too. Different fonts have different x-heights - the size of their lower case letters in relation to their upper case ones. Fonts that have a larger x-height feel larger overall so you'll need a larger line-height to give the letters room to breath and not feel cramped.
So that's a little bit around what to consider when picking that value, but your typography isn't just about one font size, you've got all those heading sizes to consider.
Ratios
Ratios
Ratios
Rather than struggling to pick out sizes for your sizing hierarchy you can cheat a little, and short-circuit that process by leveraging ratios, where each step in your sizing is a multiple of the prior value
Modular Scale
Base font-size: 16px. Ratio: 1:1.5
Size Calculated By
7.111px 10.667px / 1.5
10.667px 16px / 1.5
16px -
24px 16px * 1.5
36px 24px * 1.5
54px 36px * 1.5
Modular Scale is a method for generating a harmonious scale of numbers that work well together, based off a common ratio and a starting point
For instance if we pick a ratio of 1:1.5 then we end up with a sizing hierarchy that looks like this, where each size is given by the prior value multiplied by your ratio.
There is another way of expressing this trend though:
Modular Scale
Base font-size: 16px. Ratio: 1:1.5
Size Calculated By
7.111px 16px * (1.5 ^ -2)
10.667px 16px * (1.5 ^ -1)
16px 16px * (1.5 ^ 0)
24px 16px * (1.5 ^ 1)
36px 16px * (1.5 ^ 2)
54px 16px * (1.5 ^ 3)
Using exponents gives us a slightly cleaner progression, your base size is 0 then the number of your step is the exponent that you raise your ratio to.
Modular Scale
7.111px - 16px * (1.5 ^ -2)
10.667px - 16px * (1.5 ^ -1)
16px - 16px * (1.5 ^ 0)
24px - 16px * (1.5 ^ 1)
36px - 16px * (1.5 ^ 2)
54px - 16px * (1.5 ^ 3)
81px - 16px * (1.5 ^ 4)
Bringing it all together
GridLover.net
This all works rather well, but it's a fair bit of maths. If only we had something to do all that computation for us. Oh wait, we do.
Sass
Sass is a stylesheet preprocessor, it takes code written in its on language and outputs CSS
The neat thing about it is it's a strict superset of CSS. Which means that you can write the CSS you already know, and sprinkle in it's features like variables and functions when you need them.
You're not starting from scratch.
Sassy Default Variables
$base-font-size: 16px !default;
$base-line-height: 1.5 !default;
$ratio: 1.5 !default; // Perfect Fifth
$round-pixels: true !default;
First let's setup some default variables that we'll be using.
A base font-size, line-height and a ratio we want
Sassy Vertical Rhythm
@function rhythm($multiplier: 1,
$base-font-size: $base-font-size,
$base-line-height: $base-line-height) {
@return $multiplier * $base-font-size * $base-line-height;
}
Next we'll define a function we can can use for working out a multiple of our vertical rhythm for when we want to space things out.
The duplication of the font-size and line-height are so it knows to reference the global
variables we just set as the default values for those parameters.
So if i need a space that is equal to two lines of text i can get that using rhythm(2)
Sassy Modular Scale
@function modular-scale($offset,
$base-font-size: $base-font-size,
$ratio: $ratio,
$round-pixels: $round-pixels) {
@if $round-pixels == true {
@return round($base-font-size * pow($ratio, $offset));
}
@return $base-font-size * pow($ratio, $offset);
}
And finally we can create a modular-scale function that can be used to get a font size in our scale.
modular-scale(0) shall be our base font-size, modular-scale(1) shall be our next size up and so on.
Let's put our variables and functions to use.
Sassy Basic Usage
html {
font-family: 'Open Sans', sans-serif;
font-size: $base-font-size;
line-height: $base-line-height;
text-rendering: optimizeLegibility;
}
p, ul, ol {
margin: 0 0 rhythm(1) 0;
}
ul, ol {
padding-left: $base-font-size * 2.5;
}
Sassy Headings
h1 {
font-size: modular-scale(3); // 16px * 1.5^3 = 54px
line-height: (rhythm(3) / modular-scale(3)); // 72px / 54px = 1.33
}
h2 {
font-size: modular-scale(2); // 16px * 1.5^2 = 36px
line-height: (rhythm(2) / modular-scale(2)); // 48px / 36px = 1.33
}
h3 {
font-size: modular-scale(1); // 16px * 1.5^1 = 24px
line-height: (rhythm(2) / modular-scale(1)); // 48px / 24px = 2
}
Reduced mental load as no maths is needed, just use rhythm multiples and
modular-scale points.
Sassy Headings
h1 {
font-size: 54px;
line-height: 1.33333;
}
h2 {
font-size: 36px;
line-height: 1.33333;
}
h3 {
font-size: 24px;
line-height: 2;
}
Reduced mental load as no maths is needed, just use rhythm multiples and
modular-scale points.
Rems
Relative measurements
A better fit for responsive thinking
Progressive enhancement
html {
font-size: 16px;
font-size: 1rem;
}
Sassy REMs
@mixin rem($property, $px-values, $baseline-px: $base-font-size) {
$baseline-rem: $baseline-px / 1rem;
$rem-values: ();
@each $value in $px-values {
$rem-values: append($rem-values,
if($value == 0, $value, $value / $baseline-rem));
}
#{$property}: $px-values;
#{$property}: $rem-values;
}
Sassy Headings (Redux)
h1 {
@include rem('font-size', modular-scale(3));
line-height: (rhythm(3) / modular-scale(3));
}
h2 {
@include rem('font-size', modular-scale(2));
line-height: (rhythm(2) / modular-scale(2));
}
h3 {
@include rem('font-size', modular-scale(1));
line-height: (rhythm(2) / modular-scale(1));
}
Sassy Headings (Redux)
h1 {
font-size: 54px;
font-size: 3.375rem;
line-height: 1.33333;
}
h2 {
font-size: 36px;
font-size: 2.25rem;
line-height: 1.33333;
}
h3 {
font-size: 24px;
font-size: 1.5rem;
line-height: 2;
}
TL;DR
Universal guidelines exist
They're pretty easy to use
Computers are good at math
A designer's eye always wins