How to Add an XL Grid Size Option to Bootstrap 3

col-xl

We’re using the Bootstrap framework on a current project, and we ran into an interesting problem this week while trying to design for extremely large screens. We found there to be too large of a gap from the col-md-* to col-lg-* to easily scale the design when using the Bootstrap grid system in a fluid layout.

There seemed to be two decent solutions:

  • change our use of the breakpoints, since we don’t need to design for mobile, and shift the breakpoints up to fit our needs, or
  • add another breakpoint

The second option seemed like a winner, and it would also leave the default breakpoints intact in case the client wanted to start to support mobile devices down the road.

The concept behind the solution is simple, but the most difficult part was finding all the places to add the new col-xl-* sizes to get this solution to work. The basic concept is to see what the bootstrap team did to create their 4 sizes and add on code to create a 5th size. The directions below show you what you need to edit and where to find the files.

Initial Setup

This solution requires you use and compile Bootstrap styles with LESS.

  1. Download the bootstrap source code.
  2. Unzip the package.
  3. Open the /less/ folder.

There are 5 files that will need to be manipulated in order to add a new size grid. I am going add use xl as the new grid size. Once we are done there will be xs, sm, md, lg, xl. Below the instructions will be the snippets of code that I changed in the corresponding LESS files.

  • variables.less
  • grid.less
  • responsive-utilities.less
  • mixins/grid.less
  • grid-framework.less

Changes to variables.less

  1. Open variables.less and search for @screen-lg (line 300).
  2. Copy and paste the code that defines the @screen-lg, @screen-lg-min & @screen-lg-desktop variables.
  3. Set the value of @screen-xl to the pixel width of the window where you want your new break point to be located.
  4. Create a new X-Large definition with those variable adjusted for the “xl” size, i.e. @screen-xl, @screen-xl-min & @screen-xl-desktop.
  5. Search for @screen-md-max (should be a few lines below).
  6. Copy the line and create the new @screen-xl-min size based on the pattern.
  7. Search for @container-large-desktop & @container-lg (again just below).
  8. Create a new max container width for the col-xl-* size. The px value you choose to enter will be the maximum width of the .container at the col-xl-* size.

// xLarge screen / wide desktop
@screen-xl:                  1300px;
@screen-xl-min:              @screen-xl;
//** Deprecated `@screen-lg-desktop` as of v3.0.1
@screen-xl-desktop:          @screen-xl-min;

// So media queries don't overlap when required, provide a maximum
@screen-lg-max:              (@screen-xl-min - 1);

//== Container sizes
//
//## Define the maximum width of `.container` for different screen sizes.
// xLarge screen / wide desktop
@container-xlarge-desktop:      (1240px + @grid-gutter-width);
//** For `@screen-xl-min` and up.
@container-xl:                 @container-xlarge-desktop;

Changes to grid.less

There are two changes that need to be made in this file: we need to set the container width and override it for fixed navbars.

  1. Open grid.less and search for @screen-lg-min (line 14).
  2. Copy that code and create one for @screen-xl-min.
  3. The second change, search for .make-grid(lg).
  4. Create the columns, offsets, pushes and pulls for the xl-column from the lg-column.

// Container widths
//
// Set the container width, and override it for fixed navbars in media queries.

.container {
  .container-fixed();
  @media (min-width: @screen-xl-min) {
    width: @container-xl;
  }
}

// xLarge grid
//
// Columns, offsets, pushes, and pulls for the xlarge desktop device range.

@media (min-width: @screen-xl-min) {
  .make-grid(xl);
}

Changes to mixins/grid.less

  1. Open mixins/grid.less and search for .make-lg-column.
  2. We need to create the code to generate the xLarge columns here, so copy the four lg-column calls and paste them below.
  3. Change the class names from .make-lg-column-* to .make-xl-column-.
  4. Change the @screen-lg-min out for @screen-xl-min.

// Generate the xlarge columns
.make-xl-column(@columns; @gutter: @grid-gutter-width) {
  position: relative;
  min-height: 1px;
  padding-left:  (@gutter / 2);
  padding-right: (@gutter / 2);

  @media (min-width: @screen-xl-min) {
    float: left;
    width: percentage((@columns / @grid-columns));
  }
}
.make-xl-column-offset(@columns) {
  @media (min-width: @screen-xl-min) {
    margin-left: percentage((@columns / @grid-columns));
  }
}
.make-xl-column-push(@columns) {
  @media (min-width: @screen-xl-min) {
    left: percentage((@columns / @grid-columns));
  }
}
.make-xl-column-pull(@columns) {
  @media (min-width: @screen-xl-min) {
    right: percentage((@columns / @grid-columns));
  }
}

Changes to mixins/grid-framework.less

Here we need to add col-xl to the .col(@index) calls. It is called two separate places, so be sure to add them accordingly.

  1. Open mixins/grid-framework.less and search for .col-lg-@{index}.
  2. Add .col-xl-@{index} after .col-lg-@{index} for both instances of .col-lg-@{index} in this file.

// Framework grid generation
//
// Used only by Bootstrap to generate the correct number of grid classes given
// any value of `@grid-columns`.

.make-grid-columns() {
  // Common styles for all sizes of grid columns, widths 1-12
  .col(@index) { // initial
    @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}, .col-xl-@{index}";
    .col((@index + 1), @item);
  }
  .col(@index, @list) when (@index =< @grid-columns) { // general; "=<" isn't a typo
    @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}, .col-xl-@{index}";
    .col((@index + 1), ~"@{list}, @{item}");
  }
}

Changes to responsive-utilities.less

This is the code that adjusts the visibility of the grid sizes.

  1. Open responsive-utilities.less and search // Visibility utilities.
  2. Add .visible-xl to the definition.
  3. Next definition needs: .visible-xl-block, .visible-xl-inline, .visible-xl-inline-block added.
  4. We need to duplicate definitions for .visible-lg, .visible-lg-block, .visible-lg-inline, .visible-lg-inline-block and create them for “xl”.
  5. Search for .visible-lg.
  6. The 4x @media definitions need to be adjusted for the “lg” colums. To do that we need to add a (max-width: @screen-lg-max) to the media query.
  7. The last change is to create a .hidden-xl definition from .hidden-lg

// Visibility utilities
.visible-xl {
  .responsive-invisibility();
}

.visible-xl-block,
.visible-xl-inline,
.visible-xl-inline-block {
  display: none !important;
}

.visible-lg {
  @media (min-width: @screen-lg-min) and (max-width: @screen-lg-max){
    .responsive-visibility();
  }
}
.visible-lg-block {
  @media (min-width: @screen-lg-min) and (max-width: @screen-lg-max){
    display: block !important;
  }
}
.visible-lg-inline {
  @media (min-width: @screen-lg-min) and (max-width: @screen-lg-max){
    display: inline !important;
  }
}
.visible-lg-inline-block {
  @media (min-width: @screen-lg-min) and (max-width: @screen-lg-max){
    display: inline-block !important;
  }
}

.visible-xl {
  @media (min-width: @screen-xl-min) {
    .responsive-visibility();
  }
}
.visible-xl-block {
  @media (min-width: @screen-xl-min) {
    display: block !important;
  }
}
.visible-xl-inline {
  @media (min-width: @screen-xl-min) {
    display: inline !important;
  }
}
.visible-xl-inline-block {
  @media (min-width: @screen-xl-min) {
    display: inline-block !important;
  }
}

.hidden-xl {
  @media (min-width: @screen-xl-min) {
    .responsive-invisibility();
  }
}
 
Conversation
  • chm says:

    Cool concept but didn’t you just sacrifice the possibility for a quick update of bootstrap to newer version when it comes out?

    • chm says:

      Ok I got the concept now.
      If someone is looking for sass solution based on this cool tutorial, there you go:
      http://pastebin.com/mDP3Nfde

      Just import it after _bootstrap.scss and ur ready to go with col-xl. In my case it is for 1400 px width :)

      • Bryan Elkus Bryan Elkus says:

        Thanks chm. That sounds like it will work too. The point about updating, I’m not 100% sure about. Last time they updated i believed they changed around class names which would have caused a headache too. At least for this project, the need for the xl col was enough to deal with it when we have to.

  • Kim Dolleris says:

    I have same concern as chm. I would rather add a less file than change core files. I guess adding the changes in a seperate file would work to.. Trying it out – Thank you for sharing.

  • Jan Peša says:

    Thank a lot for this summary. I just bumped into a request for adding a new XL breakpoint and this was a great help. BTW, I made a separate layout less file, which overrides default behavior (easier Boostrap upgrading). You can basically just copy out all the code above and import it after main Boostrap import. This approach just needs one tiny tweak, so visible-lg-* classes work as intended:

    .visible-lg, .visible-lg-block, .visible-lg-inline, .visible-lg-inline-block {
    @media (min-width: @screen-xl-min) {
    .responsive-invisibility();
    }
    }

    • Jan Peša says:

      Dunno why I write Boostrap instead of Bootstrap. :D And the code block at the end inserted empty lines… oh well, lol.

  • Mat says:

    Hi, looks great! And what about .hidden-lg > .hidden-xl ?

    • Bryan Elkus Bryan Elkus says:

      Thanks Mat, You should be able to use .hidden-xl. How were you thinking you would use .hidden-lg > .hidden-xl?

  • Andrew says:

    Thanks a lot! Your tutorial very helped me to add XXS breakpoint!

  • Jay says:

    Thanks for info – I used this to add xl and xxl sizes.

    The only thing I discovered though is some missing css needed to keep everything in line with Bootstraps other col styles:


    .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 {
    position: relative;
    min-height: 1px;
    padding-left: 15px;
    padding-right: 15px;
    }

    Without this, the col doesn’t sit properly with the usual padding etc.

    Other than that, very useful info.

  • Amin Diary says:

    Thank you, it helped much!

  • Jarosław says:

    Great! I’ve also put it in one less file and added some stuff from comments. Thank you!

  • Owen says:

    Great, thanks! This was the best guide I found, and easy enough to follow for SASS too. I added an xxs.

  • Bogdan Mart says:

    you can use prebuilt BootstrapXL
    https://github.com/marcvannieuwenhuijzen/BootstrapXL

  • Dave Still says:

    This can also be built as a stand-alone LESS sheet that can be added after Bootstrap so that the original bootstrap code can be left intact. This has the advantage of making upgrading your version of Bootstrap much easier since you haven’t made any changes directly in Bootstrap. (The “C” is for CASCADING!) The biggest difference is adding the following 3 includes to the top of the your LESS file:


    @import (less) "../bootstrap/less/variables.less";
    @import (less) "../bootstrap/less/mixins.less";
    @import (less) "../bootstrap/less/grid.less";

    Adjust your paths accordingly.

  • JULIEANN LIPP says:

    Fantastic post – Incidentally , if your company is interested a OCA Official Form 930 NYHIPAA , my family used a template document here https://goo.gl/IWQTBL.

  • Elvenmagic says:

    Awesome post. It helped so much. Thank you dear sir

  • Emanuele Ciriachi says:

    Cheers, this was very useful

  • Jens Gernnadt says:

    did you miss something (last point)?

    .hidden-lg {
    @media (min-width: @screen-lg-min) and (max-width: @screen-lg-max) {
    .responsive-invisibility();
    }
    }

    • Sajal says:

      Yes, I think So.Also face some problem for this. But when i look into the code got this mistake. :)

  • Sajal says:

    Thanks Bryan.This is very useful and helps me a lot.

  • Comments are closed.