Chapter 7: How to Build a Responsive Type Scale with Bootstrap
by Craig Watson
In this tutorial, well be taking an in-depth look at how Bootstrap handles typography and how we can modify the code in a couple of different ways to create a responsive type scale. This is often referred to as responsive typography, the aim of which is to keep your typography readable on all screen sizes and avoid giant headings on mobiles!
How Bootstrap Sets Up Typography by Default
To understand the way Bootstrap typography works, we need to begin looking into the source SCSS
files to explore the setup and default settings.
Note: for the sake of clarity throughout this tutorial, Ive commented out styles from the Bootstrap code that are NOT associated with typography.
The html
Element
Lets first look at styles for the root element, found in _reboot.scss
on line 27:
html { font-family: sans-serif; line-height: 1.15; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; // -ms-overflow-style: scrollbar; // -webkit-tap-highlight-color: rgba(0, 0, 0, 0);}
From the html
element theres not much to report in terms of setting up a type scale. However, its worth noting the -*-text-size-adjust: 100%;
declarations. These have been used to prevent some mobile browsers from increasing the font size of their own accord.
The body
Element
Here are the body
element styes, as found in _reboot.scc
on line 57:
body { // margin: 0; // 1 font-family: $font-family-base; font-size: $font-size-base; font-weight: $font-weight-base; line-height: $line-height-base; color: $body-color; text-align: left; // 3 // background-color: $body-bg; // 2}
Now we can start to see some typographic styes being applied. In terms of type scale, we only need to be concerned with font-size
. By default, this is set via the $font-size-base
variable found in _variables.scss
, and is equal to 1rem
.
The p
Element
These styles for the p
element are found in _reboot.scss
on line 109:
p { margin-top: 0; margin-bottom: $paragraph-margin-bottom;}
Not much to report here: the p
tag simply inherits its font-size
and line-height
from the body as you would expect.
The h1
through h6
Elements
These styles are found in _type.scss
from lines 16 to 21:
h1, .h1 { font-size: $h1-font-size; }h2, .h2 { font-size: $h2-font-size; }h3, .h3 { font-size: $h3-font-size; }h4, .h4 { font-size: $h4-font-size; }h5, .h5 { font-size: $h5-font-size; }h6, .h6 { font-size: $h6-font-size; }
You can see here the element and the utility class are given the font-size
through a variable. The corresponding variables are found in _variables.scss
on lines 246 to 251. Looking at these variables, we can see the default sizes set out to work across all browser and viewport widths:
$h1-font-size: $font-size-base * 2.5 !default;$h2-font-size: $font-size-base * 2 !default;$h3-font-size: $font-size-base * 1.75 !default;$h4-font-size: $font-size-base * 1.5 !default;$h5-font-size: $font-size-base * 1.25 !default;$h6-font-size: $font-size-base !default;
Looking at a type scale for the above, its clear that an increase of .25rem
is used until the h1
, which is given a .5rem
increase.
These sizes can be overridden in a custom variables file if youre using a Sass compiler, but it still leaves you with one font-size
for each heading across all browser and viewport widths.
The .display-1
through .display-4
Utility Classes
The following code is fond in _type.scss
from lines 29 to 48:
// Type display classes.display-1 { font-size: $display1-size; // font-weight: $display1-weight; // line-height: $display-line-height;}.display-2 { font-size: $display2-size; // font-weight: $display2-weight; // line-height: $display-line-height;}.display-3 { font-size: $display3-size; // font-weight: $display3-weight; // line-height: $display-line-height;}.display-4 { font-size: $display4-size; // font-weight: $display4-weight; // line-height: $display-line-height;}
As with the heading elements, the display utility class sizes are defined as variables in the _variables.scss
file on lines 259 to 262. Again, if youre working with a Sass compiler you can override these in a custom variables file.
That about covers the setup from Bootstrap, and we can now look at ways of making a responsive type scale thats quickly adjustable.
Creating the Responsive Type Scale
Its worth expanding on what I mean by a Responsive Type Scale. By default, Bootstrap font-size
for headings and its display-*
classes are explicitly set using variables found in _variables.scss
and rules found in _type.scss
.
Setting one font-size
outright for headings across all screen and viewport sizes can quite quickly lead to oversized headings that make for a poor user experience.
You could, of course, create some media queries when it suits to pull down font sizes that look over-sized, but its at this point that you lose any form of a type scale hierarchy. We need type hierarchy to follow the flow of the document.
In comes the Responsive Type Scale and a nice Sassy way to implement it into a Bootstrap project! If you dont use Sass or SCSS, you can simply update the pen I use for examples and extract the compiled CSS.
An Overview of the Responsive Type Scale for Bootstrap
We are going to set up three main things:
- a type scale map for quick changes and experiments
- a function to check if the scale is valid for use
- two mixins to allow us the flexibility of adjusting the font sizes at any given time.
Its worth noting that, should your design not include a type scale that works on a common multiple, using the mixin
wont work and youll need to look at the compiled CSS
in the pen to get the code you need to update the font sizes.
The Responsive Type Scales Map
Create a Sass map of pre-defined typographic scales, $type-scales
, according to the model found on type-scale.com. The scales in the map can be passed to the Sass mixin that creates the font sizes by using their key
from the key: value
pairs.
After the map of scales, two variables are defined: $heading-type-scale-base
and $display-type-scale-base
. These variables hold the initial scales that are used from a zero-width viewport or browser and upward. These variables accept a key from the $type-scales
map or can be passed a unitless value:
$type-scales : ( minor-second: 1.067, major-second: 1.125, minor-third: 1.200, major-third: 1.250, perfect-fourth: 1.333, augmented-fourth: 1.414, perfect-fifth: 1.500, golden-ratio: 1.618);$heading-type-scale-base : minor-third;$display-type-scale-base : minor-third;
How to Check the Responsive Type Scales Value
Its important that you arent restricted to only the values in the map, as that may not be suitable for your design.
For this reason, the function below will check if the value passed to the mixin is one of the values set in the $type-scales
map or it must be a unitless value to create the type scale: