• Let’s Meet At Web Summit 2018! The P2H team is coming to the Web Summit 2018 that will take place in Lisbon on Nov… twitter.com/i/web/status/1…

COMPANY BLOG & NEWSROOM

26Mar

How to Customize Bootstrap Grid with Sass

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.

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:

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

  li {
    @include make-xs-column(6);
    @include make-sm-column(4);
  }

  .panel {
    padding: 20px;
  }
}

1

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!

Alex

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 PSD2HTML who loves web standards and enjoys experimenting with various technologies.

MORE ABOUT bootstrap, css, sass

7 comments

  1. Vladimir Dumitraskovic Mar 27, 2015

    Great post!

  2. Sivadass Dec 17, 2015

    Incredible collection of Information, thank you 🙂

  3. Pisit Mar 11, 2016

    Thank you 🙂

  4. Nadgeman May 23, 2016

    I’ve installed Bootstrap v4 url: https://github.com/twbs/bootstrap/tree/v4-dev

    but @include make-xs-column(6); returns a sass error (undefined mixin….)

    I searched for it on https://github.com/twbs/bootstrap but the only reference was to a LESS mixin. I also searched all my bootstrap scss files for a reference to it but there wasn’t one.
    Am I missing something?

  5. Nadgeman May 24, 2016

    I finally got @include make-xs-column etc working but I found that it causes css bloat.

    I thought this was a bug in my code to begin with but I checked out your css output on sass meister (link in web page above) and it was the same.

    What happens is that every time you @include make-(xs,sm,md,lg)-column the padding-left, padding-right, position and min-height rules are output to the style.css file.

    This means if you have eg:

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

    you will get:

    position: relative;
    min-height: 1px;
    padding-left: 15px;
    padding-right: 15px;

    output 4 times in the style.css file!

    So if you used this method to create all of your semantically named containers you’d end up with an enormous style.css file with tons of repetition.

  6. PSD2HTML Team May 27, 2016

    Hi there,
    Thank you for your feedback!
    In our post we describe two ways of creating the bootstrap grid:
    1) assigning classes in HTML
    2) via CSS

    Obviously, second method has a drawback – repetition of styles. It happens because each activating mixin has a property set.
    If you’d like to configure the bootstrap grid using styles, we can recommend you to try CSS Optimizer. (https://github.com/css/csso)
    However, the most popular and easiest way is assigning pre-set classes in HTML (this method doesn’t cause the repetition of the styles).
    Hope this helps.

  7. IN Aug 22, 2016

    @include make-xs-column(12);
    @include make-md-column(8);
    @include make-xs-column-push(0);
    @include make-xs-column-push(2);

    in mobile also it is taking ‘left: 16.6667%;’

leave a comment

All posts Back to top