CSS Markup Web Development

How to Customize Bootstrap Grid with Sass

The Bootstrap grid system is a very popular technology used on thousands of websites. While it is flexible in its own right, you can make it even more so by customizing it with Saas. Read this hands-on guide to learn how you can do that.

thumbnail

Bootstrap_sass

The Bootstrap grid system is incredibly popular and it’s been discussed in many tutorials and articles. Today, I will show you how to take advantage of its basic features and modify it using site customizer and Sass variables.

The Bootstrap grid allows 12 columns with 30 px wide gutters by default, but these numbers can be adjusted. Just check the Grid System block on the Customize page. The @grid-columns field allows to set a different number of columns, and the @grid-gutter-width field lets you change the gutter width.

Customizers are convenient when bootstrap.css is the only file you need and when you don’t work with preprocessors. It’s better to download the Sass-version of the framework to modify default Bootstrap styles using Sass. No doubt, it’s much better to have a file with all the Bootstrap variables you’d like to change rather than go to the website, open the customizer, type the required values, and save the bootstrap.css file again.

Best WordPress Development Services

Main Bootstrap Grid Features

The Bootstrap grid contains four sizes (Large, Medium, Small, and Extra Small Grids) for four different viewports. Each size has its own prefix:

size prefix
Extra small devices Phones (<768px) .col-xs-
Small devices Tablets (=768px) .col-sm-
Medium devices Desktops (=992px) .col-md-
Large devices Desktops (=1200px) .col-lg-

Each size has its own viewport and container width. Here’s a table with basic values:

Features
Bootstrap 3 Grid System
Extra small devices
Phones (<768px)
Small devices
Tablets (=768px)
Medium devices
Desktops (=992px)
Large devices
Desktops (=1200px)
Max container width None (auto) 750px 970px 1170px
Class prefix .col-xs- .col-sm- .col-md- .col-lg-
Max column width Auto ~62px ~81px ~97px
Gutter width 30px (15px on each side of a column)

To change them, you can either use the website customizer or change corresponding Sass variables in the _variables.scss file.

variable value by default (px)
$screen-xs: 480px
$screen-sm: 768px
$screen-md: 992px
$screen-lg: 1200px

I prefer the Sass-version. Editing the _variables.scss file is very easy and convenient. It contains some nice comments to help you easily find the required parameters.

// Extra small screen / phone
$screen-xs:                  480px !default;
$screen-xs-min:              $screen-xs !default;
$screen-phone:               $screen-xs-min !default;
  
// Small screen / tablet
$screen-sm:                  768px !default;
$screen-sm-min:              $screen-sm !default;
$screen-tablet:              $screen-sm-min !default;
  
// Medium screen / desktop
$screen-md:                  992px !default;
$screen-md-min:              $screen-md !default;
$screen-desktop:             $screen-md-min !default;
  
// Large screen / wide desktop
$screen-lg:                  1200px !default;
$screen-lg-min:              $screen-lg !default;
$screen-lg-desktop:          $screen-lg-min !default;

You can customize the parent container width using these variables:

variable value by default
$container-tablet: (720px + $grid-gutter-width)
$container-desktop: (940px + $grid-gutter-width)
$container-large-desktop: (1140px + $grid-gutter-width)

The main container width includes the container width value and the grid gutter width value. In a mobile viewport, the main container width takes the whole width of the viewport, excluding the @grid-gutter-width value.

See the Difference

Let’s create a simple grid containing two columns (one column takes one third of a parent container width designed for a desktop viewport, and the other takes two thirds). You’ll need grid classes with -md prefix here.

Since one column takes 1/12 of the total width (or 8.33%) and is called .col-md-1,and since you need values of 1/3 = 4/12 and 2/3 = 8/12 correspondingly, use the .col-md-4 class for the sidebar and the .col-md-8 class for the main content. The code will look like this:

<div class="container">
  <div class="row">
    <div class="col-md-4">Sidebar content</div>
    <div class="col-md-8">Article content</div>
  </div>
</div>

Now you have a container with two elements: a sidebar with the width of 33.33% and a main content area with the width of 66.66% (1/3 and 2/3).

If you want the columns to take half (50%) of the total width on tablets, you have to add classes with the -sm prefix to your code (.col-sm-6). The result will look like this:

<div class="container">
  <div class="row">
    <div class="col-md-4 col-sm-6">Sidebar content</div>
    <div class="col-md-8 col-sm-6">Article content</div>
  </div>
</div>

And if you want the columns to take the whole width (100%) on mobile devices, use the class with -xs prefix (.col-xs-12):

<div class="container">
  <div class="row">
    <div class="col-md-4 col-sm-6 col-xs-12">Sidebar content</div>
    <div class="col-md-8 col-sm-6 col-xs-12">Article content</div>
  </div>
</div>

As you can see, the code is quite simple but it contains too many classes and the names are non-semantic. Here’s how you can get the same effect but with a better HTML code:

<div class="container">
  <div class="main">
    <div class="sidebar">Sidebar content</div>
    <div class="content">Article content</div>
  </div>
</div>

Now let’s add some Sass code:

.main {
  @include make-row;

  .sidebar {
    @include make-xs-column(12);
    @include make-sm-column(6);
    @include make-md-column(4);
  }

  .content {
    @include make-xs-column(12);
    @include make-sm-column(6);
    @include make-md-column(8);
  }
}

That’s much simpler and better, isn’t it?

Column Positioning

Now, what if the sidebar has to be placed after the main content in the HTML code, but also be displayed before the main content in the browser on the left? Just add two classes: .col-md-pull-8 to shift the sidebar eight positions left, and .col-md-push-4 to move the main content four positions right. This should also work for desktops.

<div class="container">
  <div class="row">
    <div class="col-md-8 col-sm-6 col-xs-12 col-md-push-4">Article content</div>
    <div class="col-md-4 col-sm-6 col-xs-12 col-md-pull-8">Sidebar content</div>
  </div>
</div>

Here’s how you can do this using Sass and two mixins (make-**-column-pull and make-**-column-push).

HTML:

<div class="container">
  <div class="main">
    <div class="content">Article content</div>
    <div class="sidebar">Sidebar content</div>
  </div>
</div>

SCSS:

.main {
  @include make-row;

  .sidebar {
    @include make-md-column-pull(8);

    @include make-xs-column(12);
    @include make-sm-column(6);
    @include make-md-column(4);
  }

  .content {
    @include make-md-column-push(4);

    @include make-xs-column(12);
    @include make-sm-column(6);
    @include make-md-column(8);

  }
}

Offsets for Columns

The previous method positioned columns using left and right and didn’t affect nearby columns. You can shift columns using margin left. You will need .col-**-offset-* classes. Let’s take a look at a simple example where two columns should have a width of 33% and the second column should also have an offset for the same width.

<div class="row">
  <div class="col-md-4">Column</div>
  <div class="col-md-4 col-md-offset-4">Column</div>
</div>

Here’s the same sample written with Sass:

HTML:

<div class="main">
  <div class="col">Column</div>
  <div class="col">Column</div>
</div>

Sass:

.main {
  @include make-row;
  .col {
    @include make-md-column(4);
    &:nth-child(2) {
      @include make-md-column-offset(4);
    }
  }
}

Simple Sass Trick

Imagine you need a responsive list of products where product items have a width of 50% on mobile devices and 33% on tablets and desktops. Nobody wants to write long pieces of code, so let’s take the clean HMTL and add some Bootstrap to the CSS.

HTML:

<ul class="items">
    <li><div class="panel">item 1</div></li>
    <li><div class="panel">item 2</div></li>
    <li><div class="panel">item 3</div></li>
    <li><div class="panel">item 4</div></li>
    <li><div class="panel">item 5</div></li>
    <li><div class="panel">item 6</div></li>
</ul>

Sass:


This method has some issues, though. You’ll get the following error if different products have different heights:

2

The fourth product runs into the large second product because of its height. This can be solved by setting a display: inline-block; property to these items and cancelling float: left;.

Sass:

.items {
  list-style: none;
  padding: 0;
  @include make-row;

  li {
    @include make-xs-column(6);
    @include make-sm-column(4);
    display: inline-block;
    vertical-align: top;
    float: none !important;
  }

  .panel {
    padding: 20px;
  }
}

3

Because of the inline-block, blocks now have additional spacing between them and they do not fit into the width of their parent element. To fix this problem, consolidate the opening and closing tags of the list </li><li>:

HTML:

<ul class="items">
  <li><div class="panel">item 1</div>
  </li><li><div class="panel">item 2 long (Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium?)</div>
  </li><li><div class="panel">item 3</div>
  </li><li><div class="panel">item 4</div>
  </li><li><div class="panel">item 5</div>
  </li><li><div class="panel">item 6</div></li>
</ul>

The result will look like this on tablets:

4

and mobile devices:

5

Now you have a simple, responsive list of items with a minimum of HTML and Sass code. Easy, huh?

Play with this gist on SassMeister.

tariffs Table

Take this example: you need to create a grid with tariffs, where an Alfa tariff goes as the first item in the code but it is centered in the design.

topHTML:

<div class="container tariffs">
  <div class="row">
    <div class="tariff alfa">
      tariff Alfa
    </div>
    <div class="tariff omega">
      tariff Omega
    </div>
    <div class="tariff epsilon">
      tariff Epsilon
    </div>
  </div>
</div>

Sass:

.tariffs {
  .row {
    @include make-row;
  }
  .tariff {
    @include make-xs-column(12);
    @include make-sm-column(4);
    &.alfa {
      @include make-sm-column-push(4);
    }
    &.omega {
      @include make-sm-column-pull(4);
    }
  }
}

If you need the columns to stick together, you can use the mixins mentioned above with some additional parameters.

bottom

Add 0 into the @include make-row(0); mixin that removes external side indents. For the columns, insert an additional second parameter 0: @include make-xs-column(12, 0);, @include make-sm-column(4, 0); that will remove internal indents in columns. By changing these additional values in mixins, you can change spacing between columns without changing the default value set in @grid-gutter-width. Sass:

.tariffs {
  .row {
    @include make-row(0);
  }
  .tariff {
    @include make-xs-column(12, 0);
    @include make-sm-column(4, 0);
    &.alfa {
      @include make-sm-column-push(4);
    }
    &.omega {
      @include make-sm-column-pull(4);
    }
  }
}

Here’s what you have:

Play with this gist on SassMeister.

I showed how you can customize the grid and gave a few examples of how to adjust the grid to your project using Sass mixins. This method significantly simplifies the code, saves time, and makes it easier to support and update the project in the future. Instead of editing several HTML templates and removing and adding various classes, you just add several values to the files with styles.

If you have any questions or comments, you are more than welcome to share!

About the Author: Alex is a talented web developer, passionate tutor and geek. He has been coding websites for over 9 years. This has led him to be the R&D analyst at GetDevDone who loves web standards and enjoys experimenting with various technologies.