Twitter Bootstrap 3 is great for creating responsive websites. It comes with many components and features that are easy to use and has a great documentation. That’s not always enough. Sometimes you need additional JavaScript functionality or custom CSS. You might even want to add additional jQuery plugins. Sooner or later you’ll hit an issue with some plugin or your code breaking stuff.
In this articles I’ll share the common issues I’ve seen in bootstrap based projects and ways to avoid them when customizing the framework.
box-sizing: border-box everywhere
Bootstrap 3 changes box-sizing
to border-box
on all elements (and pseudo elements). This means that padding and border are included in the width and height calculations but margin is not. When you add padding to an element instead of getting larger its content area will become smaller and the size will remain the same. This is not the default behavior. Remember this when writing your classes in a Bootstrap based project.
Box-sizing Example:
.example-1 {
box-sizing: content-box; /* Default CSS value. No need to write it. */
display: block;
width: 300px;
padding-left: 20px;
padding-right: 20px;
}
.example-2 {
box-sizing: border-box; /* Same as Bootstrap */
display: block;
width:300px;
padding-left: 20px;
padding-right: 20px;
}
.example-1
width will be 340px with 300px for the content.
.example-2
width will be 300px with 260px left for the content.
Grid system structure is important
Don’t omit .container
and .row
elements. The row class applies negative margin left and right of 15px which compensates for the gutter padding on the leftmost and rightmost columns inside. If you don’t have a .row
parent on you .col-
elements your columns content will be smaller than expected.
Don’t place anything different from columns in rows. Only columns can be child elements of .row
.
.container
class comes with fixed width depending on the screen size. If you want a full-width container use .container-fluid
on the outermost container.
<div class="container-fluid">
<div class="row">
...
</div>
</div>
jQuery plugins and Bootstrap grid layout
Don’t attach jQuery plugins on elements with Bootstrap grid system classes. Add the plugin root as child element instead.
<!-- WRONG -->
<div class="container">
<div class="row">
<div class="col-md-6 my-plugin">
</div>
...
</div>
</div>
<script type="application/javascript">
// Not an actual plugin. myPlugin can be any jQquery plugin.
$('.my-plugin).myPlugin();
</script>
If you attach the plugin on the grid column (col-md-6
) element and try to apply different width or padding on the plugin you might override Bootstrap styles and break the grid layout.
Use the following structure instead:
<!-- CORRECT - jQuery plugin will be attached on a child element -->
<div class="container">
<div class="row">
<div class="col-md-6">
<!-- Plugin root tag is inside .col-... -->
<div class="my-plugin"></div>
</div>
...
</div>
</div>
<script type="application/javascript">
// Not an actual plugin. myPlugin can be any jQquery plugin.
$('.my-plugin).myPlugin();
</script>
Bootstrap is not a CSS only framework.
Bootstrap applies JavaScript logic and listeners on some of its classes like toggle buttons, tooltips and collapse. If you try to attach a jQuery plugin or listeners to a such element results might be hard to predict. Instead use a sibling element or a child element when possible.
Avoid calling preventDefault
, stopImmediatePropagation
and stopPropagation
on events in listeners attached to Bootstrap elements unless you know what you are doing. Blocking event propagation might stop Bootstrap from attaching state classes on the DOM elements thus breaking the default behavior.
Overriding is scary. Run for your life.
Be careful with overriding Bootstrap classes styling. This might lead to complex CSS rules impossible to follow. It also locks you to the Bootstrap framework class used at the moment.
Lets say you add your new styles with the .col-md-4
element. What happens if the design changes and you now need your content to be 6 columns wide instead of 4? Better add a custom class and select it instead.
<div class="container">
<div class="row">
<div class="col-md-4 profile-info">...</div>
<div class="col-md-4 profile-info">...</div>
<div class="col-md-4 profile-info">...</div>
</div>
</div>
/* BAD: Don't use Bootstrap classes for styling */
#my-content .col-md-4 {
background-color: red;
height: 300px;
}
/* CORRECT: Custom class used. Nothing bad will happen if we use col-md-6 instead of col-md-4 */
#my-content .profile-info {
background-color: red;
height: 300px;
}
SASS and LESS to the rescue
Sooner or later you’ll need to change Bootstrap default styles in a more drastic way. For example you might want to change the gutter size or columns count. How about changing the default design breakpoints that come with the framework and use the desktop look for tablets? Or perhaps changing the default font size?
You can do this with CSS but your styles will become quite complicated and hard to manage. Remember, Bootstrap was written with a CSS preprocessor. As a result the compiled selectors are much more complex than if they were written by hand.
Bootstrap has 2 additional source code variants written with SASS and LESS. They introduce many variables you can easily change. The variables modify things from framework wide font size and padding to changing media queries breakpoints and columns count for various devices. With just one line of SASS code you’ll be able to achieve things you’ll otherwise need hundred of lines of CSS to do.
If you really need hardcore Bootstrap changes and there is no theme matching you preferences consider using the official SASS or LESS version.
To customize the framework with SASS you’ll need to change the variables values and then import Bootstrap. All variables are marked as !default so you can easily override the value before the framework is included.
$font-size-base: 12px !default;
$text-color: #222 !default;
$grid-gutter-width: 18px !default;
$btn-default-bg: #eee !default;
$navbar-height: 51px !default;
@import "bootstrap/_boootstrap";
// additional styles and imports
It’s crucial to change Bootstrap variables before the bootstrap import or you might end up with Bootstrap styles already compiled when you change your variables.
Themes are more than just “themes”
Bootstrap themes are really powerful but they are more than just “themes”. They come with additional classes and plugins. Large themes have additional content like charts, new components and a separate documentation.
There is a downside. Once you add a theme and start using the additional functionality it provides it becomes harder to drop it and use another one or switch to pure Bootstrap. The problem is that every “theme” comes with different added functionality and libraries. The larger the theme is the harder it will be for you to drop it once you chose it.
I’m not saying that you shouldn’t be using themes. Do use a theme if you find one that suits your needs and design preferences. If want to use a theme and you liked more than one then start writing your project only with Bootstrap. Apply the theme later when you have the whole project skeleton. This way there won’t be a risk for you to use something that is theme specific before you chose the best theme for you.
Well explained – thanks. I’m new to bootstrap though I have little knowledge of web development. I’m learning how to develop responsive websites and this has enlightened me on using bootstrap.