Frontend Bootstrap practices

Content here was adapted from rstacruz/bootstrap-practices.

Mashup Garage discourages using Bootstrap. For existing projects that use Bootstrap, however, this document lists down the guidelines we've learned through working on Bootstrap projects.

Including Bootstrap

Use Sass

Avoid the Less version of Bootstrap. Use the officially-supported Sass version. Be aware that the Bootstrap's official sources migrated from Less to Sass since version 4.

gem 'bootstrap-sass'            # Rails
bower install bootstrap-sass    # elsewhere

See: @mdo's tweet

Avoid the CDN

Don't use the Bootstrap CDN. Any site you build to last will eventually need to grow up to extend Bootstrap. The only legitimate use of this is for quick demos and jsfiddle.

See: Bootstrap CDN

Components

Graduate

Your objective is to eventually graduate from stock components into new ones. Instead of restyling stock components, consider creating new ones instead.

// ✗ Avoid (avoid restyling stock components)
.jumbotron {
  background: url('....');
}

// ✓ OK
.new-jumbotron {
  background: url('....');
}

Restyling stock components

Don't restyle stock components except .btn and .form-control. Everything else are too complicated to restyle (eg, navbars and tables). The stock components account for a lot of corner cases, and working around them is more effort than its worth.

// ✗ Avoid. You don't want to do this.
.nav-bar {
  background: $gray;
  ...
}

Bootstrap's modularity

Bootstrap's modules were made to be completely separate: grids, icons, components, JS components. This means you can mix and match them:

  • You don't need to use all the CSS components.
  • You can use different icons.
  • You can use a different grid system.

Here are some examples of alternate systems you can use:

The recommended setup is to use Bootstrap for grids, basic components, JS, and nothing else (eg, icons, stock components).

CSS

Restyling bare elements

Avoid style bare elements like h2, h3, and so on, with anything other than fonts & margins. If you need control on the styles to display documents (like Markdown descriptions), create a prefixed component. This will prevent creeping of your own rules into components that rely on these elements to have default styling.

// ✗ Avoid: borders will show up everywhere!
h2 {
  margin-top: 3em;
  border-bottom: solid 1px #ddd;
}

// ✓ Better
.formatted-text {
  h2 {
    margin-top: 3em;
    border-bottom: solid 1px #ddd;
  }
}

Be selective

Try not to use everything in Bootstrap. Take \bootstrap.scss_ and start with the bare minimum your project will need. Comment out everything else.

// Core variables and mixins
@import 'bootstrap/variables';
@import 'bootstrap/mixins';

// Reset and dependencies
@import 'bootstrap/normalize';
@import 'bootstrap/print';
// @import "bootstrap/glyphicons";

// Core CSS
@import 'bootstrap/scaffolding';
@import 'bootstrap/type';
@import 'bootstrap/code';
@import 'bootstrap/grid';
@import 'bootstrap/tables';
@import 'bootstrap/forms';
@import 'bootstrap/buttons';

// (...snip...)

// Utility classes
@import 'bootstrap/utilities';
@import 'bootstrap/responsive-utilities';

See: [\bootstrap.scss](https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/_bootstrap.scss)_

Media queries

Use Bootstrap variables for media queries. This will make your breakpoints consistent with where the Bootstrap columns will break.

@media (min-width: $screen-md-min) {
  /* ... */
}

Variable overrides

Always override the following variables. Refer to Bootstrap's variables.scss for things you can (should) reconfigure.

// fonts
$font-family-sans-serif: 'Helvetica Neue', Helvetica, Arial, sans-serif !default;
$font-size-base: 14px;
$line-height-base: 1.42857;
$headings-font-weight: 500;

// colors
$brand-primary: #337ab7; // your main color
$brand-success: #5cb85c; // green
$brand-info: #5bc0de; // blue
$brand-warning: #f0ad4e; // yellow
$brand-danger: #d9534f; // red

$gray-light: #777777; // muted text
$gray-lighter: #dddddd; // lines

See: [variables.scss](https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/bootstrap/variables.scss), colors variables, typography variables_

Use Autoprefixer

Use Autoprefixer instead of Bootstrap's CSS3 mixins. Autoprefixer has been endorsed officially as of Bootstrap 3.3.

// ✗ Avoid
.my-component {
  @include box-shadow(0 1px 4px black);
}

// ✓ OK
.my-component {
  box-shadow: 0 1px 4px black;
}

See: Autoprefixer, Less mixins

Naming

Naming conventions

When creating new components, there's no reason to stick to Bootstrap's naming convention. Consider rscss or BEM instead.

// ✗ No need to follow bootstrap conventions like .panel-body (elements) or .btn-primary (modifiers)
.eventlist { ... }
.eventlist-expanded { ... }
.eventlist-heading { ... }
.eventlist-item { ... }

// ✓ Better: rscss conventions are cleaner
.event-list {
  &.-expanded { ... }
  .heading { ... }
  .item { ...}
}

See: rscss, BEM

Reserved keywords

Avoid using the following classnames when making new components. They are defined as top-level classes in Bootstrap and may produce conflicts. This is a partial list of the most common ones, check the full list below. #

alert*, breadcrumb*, close*, label*, mark, open, small, badge*

See: list of Bootstrap keywords

Markup

Avoid helpers

Avoid using helper classes like .pull-left or .text-right. Consider the use of these as code smell anti-patterns: anytime they appear in your code, it's a wise time to evaluate if they should be refactored into new components instead.

<!-- ✗ Bad: too much helper classes -->
<div class="profile-card clearfix">
  <div class="info pull-left">
    <h2 class="name text-center">John Smith</h2>
    <p class="occupation text-center text-uppercase small">The doctor</p>
  </div>
  <div class="avatar pull-right">
    <img src="avatar.jpg" alt="Picture" />
  </div>
</div>
/* ✓ Better: use components */
/* (this example uses rscss conventions.) */
.profile-card {
  & {
    @include clearfix;
  }
  > .info {
    float: left;
  }
  > .info > .name {
    text-align: center;
  }
  > .info > .occupation {
    text-align: center;
    font-size: 0.8em;
  }
  > .avatar {
    float: right;
  }
}

Grids

Column mixins

Use column mixins when necessary. This will free your markup from unsemantic grid classes.

.dashboard-layout {
  & {
    @include make-row();
  }
  > .content {
    @include make-lg-column(8);
  }
  > .sidebar {
    @include make-lg-column(3);
    @include make-lg-column-offset(1);
  }
}

See: Less grids reference

Grid classes

Grid classes are okay to use in your markup. However, if they appear too often, consider making them a CSS component instead.

Grid CSS classes include: .container, .container-fluid, .row, .col-sm-6.

.field-row {
  & {
    @include make-row();
  }
  > .label {
    @include make-lg-column(4);
  }
  > .control {
    @include make-lg-column(8);
  }
}

See: Less grids reference

Icons

Avoid Glyphicons

They're too bland of a default, so chances are you designer wouldn't wanna use them anyway. If they do, fire them.

// @import "bootstrap/glyphicons";

Attribute Glyphicons

If you do end up using Glyphicons, be aware that you are required to give attribution.

Icons by <a href="http://glyphicons.com">Glyphicons</a>.

See: reference

Forms

Make your own form components

The Bootstrap docs prescribe you to use .col-md-6 (and so on) to line up your forms. It's better to create your own components.

<div class="form-field">
  <label class="lbl">Name:</label>
  <div class="controls">
    <input type="text" class="form-control" />
  </div>
</div>
.form-field {
  & {
    @include clearfix;
  }
  > .lbl {
    width: 30%;
    float: left;
  }
  > .controls {
    width: 70%;
    float: left;
  }
}
/* We're using `lbl` instead of `label` because `label` is a reserved Bootstrap keyword :( */