22 Comments

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();
  }
}