How to Build a Responsive Type Scale with Bootstrap

Share this article

Responsive Type Scale with Bootstrap

In this tutorial, we’ll 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!

Key Takeaways

  • Bootstrap’s typography can be customized by modifying the code within the source SCSS files. The html element uses -*-text-size-adjust: 100%; declarations to prevent mobile browsers from increasing font size independently.
  • Building a responsive type scale in Bootstrap involves setting up a type scale map, a function to check if the scale is valid, and two mixins to adjust font sizes. This prevents oversized headings across different screen and viewport sizes, maintaining a type scale hierarchy.
  • Bootstrap’s default typography settings include a base font size of 16px, a line height of 1.5, and a font family of ‘system-ui’. These settings can be overridden in a custom variables file, if using a Sass compiler.
  • A responsive type scale enhances readability and creates a visual hierarchy for better user experience. This can be achieved in Bootstrap using a Sass map of pre-defined typographic scales, a function to check if the scale is valid, and mixins to adjust font sizes.

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, I’ve commented out styles from the Bootstrap code that are NOT associated with typography.

The html Element

Let’s 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 there’s not much to report in terms of setting up a type scale. However, it’s 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, it’s 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 you’re 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 you’re 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 that’s quickly adjustable.

Creating the Responsive Type Scale

It’s 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 it’s 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 don’t 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.

It’s worth noting that, should your design not include a type scale that works on a common multiple, using the mixin won’t work and you’ll 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

It’s important that you aren’t 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:

@function check-type-scale-value($scale) {

  // Check $scale against the values in $type-scales.
  @if map-has-key($type-scales, $scale) {

    // If the value of $scale is defined in
    // $type-scales, return the value of $scale.
    @return map-get($type-scales, $scale);

  // If the value of $scale is not defined in the
  // $type-scales map, check if the value is a number
  // and that the number is a unitless value.
  } @else if type-of($scale) == number and unitless($scale) {

    // If the value of $scale is a unitless number,
    // return the number.
    @return $scale;

  // Lastly, should the value passed to $scale be neither
  // found in the $type-scales map nor a unitless number,
  // throw a Sass error to explain the issue.
  } @else {

    // Throw a Sass error if the $scale value is
    // neither found in the $type-scales map nor
    // a unitless number.
    @error "Sorry, `#{$scale}` is not a unitless number value or a pre-defined key in the $type-scales map.";
  }

}

Next we will build up the mixins for creating the initial font sizes.

Creating the Heading and Display Font Sizes

I first wrote the CSS to achieve a responsive type scale when the alpha version of Bootstrap 4 was available. But since the release of the stable version of the library, I’ve revamped things to use the default SCSS setup, which makes it convenient to include the code in Bootstrap projects.

The first mixin is used to create the heading font sizes from h6 to h1:

@mixin create-heading-type-scale($scale) {

    // Check the $scale value and store in a variable to be
    // used when calculating the font sizes.
    $the-heading-type-scale: check-type-scale-value($scale);

    // Starting from h6, multiply each previous value by the scale
    // to get the next font size
    $font-size-h6 : $font-size-base;
    $font-size-h5 : $font-size-h6 * $the-heading-type-scale;
    $font-size-h4 : $font-size-h5 * $the-heading-type-scale;
    $font-size-h3 : $font-size-h4 * $the-heading-type-scale;
    $font-size-h2 : $font-size-h3 * $the-heading-type-scale;
    $font-size-h1 : $font-size-h2 * $the-heading-type-scale;
    // $font-size-display-base is made global to allow for accessing the
    // varibale in the next mixin.
    $font-size-display-base : $font-size-h1 !global;

    // Add the created font sizes to the elements and classes
    h1, .h1 { font-size: $font-size-h1; }
    h2, .h2 { font-size: $font-size-h2; }
    h3, .h3 { font-size: $font-size-h3; }
    h4, .h4 { font-size: $font-size-h4; }
    h5, .h5 { font-size: $font-size-h5; }
    h6, .h6 { font-size: $font-size-h6; }
}

Above, the font sizes are first created and stored in variables starting from the $base-font-size and multiplying each previous value by the type scale value. The same principle is applied below but we start from the $font-size-display-base:

@mixin create-display-type-scale($scale) {

    // Store default type scale in a variable for calculations
    $the-display-type-scale: check-type-scale-value($scale);

    // Create variables to reference the previous font size
    $font-size-display-4 : $font-size-display-base + $font-size-base;
    $font-size-display-3 : $font-size-display-4 * $the-display-type-scale;
    $font-size-display-2 : $font-size-display-3 * $the-display-type-scale;
    $font-size-display-1 : $font-size-display-2 * $the-display-type-scale;

    // Add the created font sizes to the elements and classes
    .display-4 { font-size: $font-size-display-4; }
    .display-3 { font-size: $font-size-display-3; }
    .display-2 { font-size: $font-size-display-2; }
    .display-1 { font-size: $font-size-display-1; }
}

Drop the Root font-size

I like to drop the root font-size to 14px for mobiles and work my way up to 16px and then 18px. Below is the SCSS to do so using the breakpoint sizes of md and lg:

html {
    font-size: 14px;
    @media (min-width: 768px) {
        font-size: 16px;
    }
    @media (min-width: 992px) {
        font-size: 18px;
    }
}

Wrapping It Up

Once all this work is done, it’s all about including your mixins and choosing your desired scales!

// Create the heading font sizes
@include create-heading-type-scale($heading-type-scale-base);

// Create the display font sizes
@include create-display-type-scale($display-type-scale-base);

// At the Bootstrap md breakpoint, adjust the heading font sizes.
@media (min-width: 768px) {
    @include create-heading-type-scale(minor-third);
}

As you can see, you can include the mixin at any breakpoint and completely change your type scale. Each font size can still be overridden if necessary and all looks good.

The Bootstrap Responsive Type Scale in Action

You can see the Bootstrap responsive type scale in action in this pen:

See the Pen Bootstrap 4 Responsive Type Scale by SitePoint (@SitePoint) on CodePen.

I hope this tutorial has given you an insight into how you can customize Bootstrap to work for you by providing a better understanding of how to achieve a responsive type scale using this popular library.

If you’ve got the basics of Bootstrap under your belt but are wondering how to take your Bootstrap skills to the next level, check out our Building Your First Website with Bootstrap 4 course for a quick and fun introduction to the power of Bootstrap.

Frequently Asked Questions on Building a Responsive Type Scale with Bootstrap

How can I customize the typography in Bootstrap?

Bootstrap provides a robust and flexible system for customizing typography. You can easily modify the default settings by overriding the CSS variables in your custom stylesheet. For instance, you can change the base font size, line height, and font family by altering the values of the respective variables. Remember to include your custom stylesheet after the Bootstrap CSS file in your HTML document to ensure that your changes take effect.

What is a type scale and why is it important in responsive design?

A type scale is a progression of font sizes that are harmoniously related to each other. It’s crucial in responsive design because it ensures that your typography looks consistent and balanced across different screen sizes. A well-implemented type scale enhances readability and creates a visual hierarchy that guides the user’s attention through your content.

How can I implement a modular scale in Bootstrap?

A modular scale is a type scale based on a specific ratio. You can implement it in Bootstrap by using the ‘calc()’ function in your CSS. This function allows you to calculate the font size for each heading level based on the base font size and the chosen ratio. For example, if your base font size is 16px and your ratio is 1.5, your h1 font size would be ‘calc(16px * 1.5)’.

What are the default typography settings in Bootstrap?

Bootstrap comes with default typography settings that include a base font size of 16px, a line height of 1.5, and a font family of ‘system-ui’. These settings are applied to the ‘body’ element and inherited by all other elements. However, specific elements like headings, paragraphs, and lists have their own styles that override these defaults.

How can I change the font size for different screen sizes in Bootstrap?

Bootstrap’s responsive font sizes (RFS) feature automatically adjusts the font size based on the screen size. You can customize this feature by changing the values of the RFS variables in your custom stylesheet. For instance, you can set a different font size for small, medium, and large screens by altering the ‘font-size-sm’, ‘font-size-md’, and ‘font-size-lg’ variables respectively.

How does Bootstrap handle vertical rhythm?

Bootstrap maintains vertical rhythm by using a global line height that’s applied to all text elements. This line height is set as a unitless number, which means it’s multiplied with the current font size to calculate the actual line height in pixels. You can adjust the global line height by changing the value of the ‘line-height-base’ variable in your custom stylesheet.

What are Bootstrap’s built-in classes for typography?

Bootstrap provides a variety of built-in classes for styling typography. These include classes for headings, paragraphs, lists, blockquotes, and more. You can use these classes to apply specific styles to your text elements without having to write any custom CSS.

How can I use Google Fonts with Bootstrap?

You can use Google Fonts with Bootstrap by including the link to the font in your HTML document and then setting the font family in your custom stylesheet. Make sure to include your custom stylesheet after the Bootstrap CSS file to ensure that your font family overrides the default one.

How can I style links in Bootstrap?

Bootstrap provides several classes for styling links. You can change the color, decoration, and hover effect of links by using the ‘.text-primary’, ‘.text-decoration-none’, and ‘.hover’ classes respectively. You can also create button-like links by using the ‘.btn’ and ‘.btn-primary’ classes.

How can I create a typographic hierarchy in Bootstrap?

You can create a typographic hierarchy in Bootstrap by using different font sizes for different levels of headings. The h1 element should have the largest font size, followed by h2, h3, and so on. You can also use color, weight, and spacing to differentiate between different levels of text.

Craig WatsonCraig Watson
View Author

Web Developer with a passion for learning front-end development, a slight addiction to Bootstrap and an avid user of WordPress. When I can drag myself away from the code I like spending time with my wife and young son as well as sneaking in the odd round of golf.

bootstrapbootstrap-hubLearn-BootstrapResponsive DesignResponsive Type Scale
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week