Getting Bootstrap Grid Classes Into Drupal 7 CMS Markup
Bootstrap is wonderfully useful and robust, mobile first framework for creating fully responsive, grid based web layouts.
The application of the Bootstrap framework relies on the principle of applying existing Bootstrap CSS classes to HTML mark-up, which in turn harness a suite of existing, integrated LESS classes, mixins and variables as well as some useful, included JavaScript plugins to create Bootstrap layout.
When building HTML from scratch, the principle and practice is pretty straight forward. Once your Bootstrap library files are in the right place and working, you simply need to add Bootstrap classes to your mark-up as you go.
When developing with Drupal, it can be a challenge to 'crowbar' in the Bootstrap classes you need.
When developing with Drupal, things are not quite so straight forward out-of-the-box and it can be quite a challenge trying to 'get at' all of the code where you would need to crowbar in the Bootstrap classes you need.
Luckily there a number of ways to tackle this challenge, four of which are listed below. I've kept the neatest, life changing trick till last, because it's important to understand your options. (There's a time and place for all these approaches.)
1. PHP Templating
https://api.drupal.org/api/drupal/modules!system!page.tpl.php/7
So tactic number 1 shouldn't come as massive surprise to most Drupal front enders and that is of course to harness the existing Drupal templating system to create templates containing Bootstrap specific mark-up.
The most obvious example of this (and the bare minimum required to even begin utilising the Bootstrap grid system) is good old page.tpl.php. Here you'll most likely want to be applying Bootstrap classes to Drupal regions like the main content area and sidebars, so that they respond to screen size and probably 'stack' on top of each other at a smaller sizes.
Of course the above 'regions' example is a simple scenario (and If you're using the Drupal Bootstrap starter theme (https://www.drupal.org/project/bootstrap) a lot of this basic, mark-up will already be in place.) but things will no doubt have to get a lot more fine grain than this and at some point It's a distinct possibility you'll also want to inject Bootstrap column classes into node templates, views templates etc.
2. Helper Modules
One of my favourite 'helper modules' is Views Responsive Grid.
As the name suggests this module helps create responsive (div based) grid layouts for your views. By itself the module doesn't do anything to auto-magically 'Bootstrapize' your views, rather it gives you an extra view format (Responsive Grid) which at odds with the default Drupal, table based grid format, produces a simple set of nested divs and the ability to assign your own responsive classes to the view wrapper, rows and columns, all through the admin interface, without need for template editing.
In our case we'd use it to add Bootstrap classes, but because it's framework agnostic, you could just as easily use it on sites using omega or foundation themes or your own bespoke responsive approach.
3. Display Suite
Display Suite can be found here.
To people who are already advocates of Display Suite, this one should be a no-brainer.
The Display Suite module (DS) is the ultimate tool in customising Drupal layout through the front end admin interface. Again no need for editing PHP templates directly.
If like me, you haven't used DS a massive amount in the past, Bootstrap presents a pretty good case for further investigation.
Simply put, DS presents to you through the Drupal admin interface, every default and custom field of a content type, stripped of mark-up and allows you to create multiple view modes where you can choose to show or hide specific fields, re-arrange their order, group them together, create custom page regions, wrappers and assign custom classes, IDs and various other formatting options to each of these elements. For all intents and purposes it lets you create complex node templates without necessarily writing a line of code.
So, say we have a 'case study' content type, for example, we could create a node view mode for presenting a single case study article, a teaser view mode to use in views listings where results should appear in a grid layout, and a second teaser view mode to use in views where results appear in a simple list format. We can show/hide whichever fields we like per view mode, group them together any way we choose and more importantly for us, we can use this method to insert all the Bootstrap mark-up and/or classes we require.
4. Bootstrap's Default Mixins
I said at the beginning of this blog, that I was saving the best till last and here it is.
This won't be news to everyone, but I'm willing to bet there are going to be a pretty large portion of bootstrap users, who, even though they have studied the Bootstrap documentation available on the getbootstrap site will have missed this nifty feature.
If you visit the CSS page of the Bootstrap site and specifically the 'grid' section, you will no doubt be familiar with the explanation and examples of the grid system itself and which classes to use where, but right at the bottom of this section (just before the section on 'Typography'), there's a sub-section on LESS mixins.
Now, far be it from me to advise Bootstrap on how to write their documentation, but this section seems to me to be ordered in a quite counter-intuitive manner. There's a large section of very over complicated example code, showing mixins being used in conjunction with various media queries and LESS variables without seemingly explaining what any of the individual lines of code actually mean. Complicated and confusing enough for may visitors to give up trawling through before reaching the end of the section. And this is the crime, because here, right at the end of the section under the heading 'Example usage', in one short example piece of code, the keys to the Bootstrap kingdom are presented:
.wrapper {
.make-row();
}
.content-main {
.make-lg-column(8);
}
.content-secondary {
.make-lg-column(3);
.make-lg-column-offset(1);
}
<div class="wrapper">
<div class="content-main">...</div>
<div class="content-secondary">...</div>
</div>
What does this mean?
Well it means, with a little thoughtful coding, you can create an entire Bootstrap layout without needing to physically insert classes into your HTML mark-up at all. You could in theory use just LESS mixins to style existing, non-Bootstrap markup elements to appear as if they had certain Bootstrap classes, without having to edit their HTML output directly.
The example code above would produce layout equivelent to the following HTML mark-up:
<div class="wrapper row">
<div class="content-main col-lg-8">...</div>
<div class="content-secondary col-lg-3 col-lg-offset-1">...</div>
</div>
Further examples
For instance you have a wrapper div, which contains 6 child divs and you want those 6 children to appear as if they were 6 Bootstrap columns with a class of .col-sm-4. They should have a width of 100% on mobile and stack above each other and then at the 'sm' breakpoint of 768px screen width and above, each of the 6 columns should float left in 2 rows of 3 and have a width of 33.33333333%, or in other words ocuppy 4 of the default 12 Bootstrap columns.
*The below layout examples are best viewed on larger screens, so that you can see the layout change as you resize the browser. (on mobile, layouts will all appear stacked at 100% as no 'xs' breakpoint has been declared.)
Col 1
Col 2
Col 3
Col 4
Col 5
Col 6
If you were editing the HTML directly, you would need to give the wrapper div a class of 'row' and each child div a class of '.col-sm-4'. Using the mixins available to Bootstrap you could do this indirectly, assigning the mixin .make-row(); to your wrapper and then the mixin of .make-sm-column(4); to each of the children. Bingo Bootstrap will now take care of the rest.
div.wrapper {
.make-row();
}
div.child {
.make-sm-column(4);
}
You can also stack Bootstrap classes just like in HTML like so:
div.child {
.make-sm-column(4);
.make-md-column(6);
}
Resulting in:
Col 1
Col 2
Col 3
Col 4
Col 5
Col 6
*Each child div will be 4 columns (33.33333333%) at the 'sm' breakpoint and above, until the 'md' breakpoint when each child div will be 6 columns (50%) wide. Because we haven't decared a specific number of columns at 'xs' (below the 'sm' breakpoint), the divs will revert to their 100% wide default and stack one on top of each other.
You can even add offsets like so:
div.child {
.make-sm-column(4);
.make-md-column(6);
}
div.thisclass {
.make-sm-column-offset(4);
.make-md-column-offset(6);
}
Col 1
Col 2
Col 3
Col 4
Col 5 Offset on larger screens
*In this example, at the 'md' breakpoint each div occupies 5 columns with an empty column to it's left. (5+1 = 6 cols - or 50% in total).
Conclusion
So there you go, there's my 4 favourite ways of getting Bootstrap into Drupal. You could exclusively use tactics 1,3 or 4 in isolation (2 is more of a 'bolt-on' to be harnessed by the others), depending on your preferred work flow and how much you want to 'get your hands dirty' by digging down into the code of Drupal, but in practice all methods should be viewed as complimentary tools available in a themer's toolbox, each with it own advantages and disadvantages in any one given situation.