Tuesday, February 7, 2012

Theming Twitter Bootstrap (Without Less)

As I've mentioned in previous posts, I use Twitter Bootstrap as the base for my CSS for EatDifferent, both on the web and mobile versions. I like it because it's pretty by default — the way I think the web should be, but it started off ugly and must stay backwards compatible, so it's too late for that dream

I also like it because it's easy to customize. The Bootstrap CSS is built using LESS, a stylesheet language like SASS, so if you use LESS, then you can actually modify the variables in the LESS files themselves and re-compile the CSS. However, I use SaSS instead of LESS, so for me to customize the Bootstrap CSS, I have to override their generated rules. I started off by tinkering with the CSS in Chrome DOM inspector, but then I realized I could more effectively and cleanly override their rules by basing my overrides on the rules in the original LESS files. I thought I'd share my overrides here in case others are going down the same path as me.

Colors

Much of my Bootstrap customization is just changing the colors and background colors of elements. Bootstrap defaults to a fairly generic color scheme- white background, dark grey text, blue links, and a black nav bar. For EatDifferent, I wanted a slightly brighter color scheme and a different blue. Since I use SASS, I set up various color variables at the top of my .scss file that I use throughout my CSS overrides.

$white: #ffffff;
$black: #000000;
$darkblue: #339bb9;
$darkestblue: #257085;
$blue-gradient: linear-gradient(top, $lightblue, $darkblue);

Links & Buttons (buttons.less)

The standard .btn button fits fine into my scheme — it's just a muted grey — but the btn-primary class is a blue, so I needed to change that over to my scheme's blue.

The SASS:

a {
  color: $darkblue;
  &:active, &:link, &:hover {
    color: $darkestblue;
  }
  &.btn-primary {
    color: $white;
  }
}

.btn-primary {
  @include background-image($blue-gradient);
  background-color: $darkblue;
  border-color: $darkblue;
  &:hover, &:active, &.active, &.disabled, &[disabled] {
    background-color: $darkblue;
  }
}

The result:


Navigation (navs.less)

Bootstrap offers two navigation elements, pills and tabs. The tabs don't require customization as they're just links with a grey border, but the pills have a hover and active background that must be overridden.

The SASS:

 
.nav-pills {
  .active > a, .active > a:hover {
    background: $darkblue;
  }
}

The result:


Tooltips (tooltip.less)

Bootstrap tooltips default to black background and white text, so I changed the background to my blue instead.

The SASS:

.tooltip {
  font-size: 13px;
  @include opacity(1.0);

  .tooltip-inner {
    background: $darkblue;
    color: white;
  }
}

The result:


Header (navbar.less)

Bootstrap provides a navigation bar (.navbar) for creating the typical top bar with site navigation, and this navigation bar is probably what most people recognize when they see a Bootstrap site. It defaults to a black background with white/grey links, and that was just way too morbid for my tastes. I changed the backgrounds to my blue, and added a logo and login area. There's a bit more to override here because the navbar also includes a dropdown menu.

The HTML:

  <div id="header" class="navbar navbar-fixed-top">
    <div class="navbar-inner">
      <div class="container">
        <a id="header-logo" class="pull-left">      
        </a>
          <ul id="header-login" class="nav pull-right">
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                <img src="pamelafox.png">
                <span id="header-login-name">Pamela Fox</span>
                <b class="caret"></b>
              </a>

              <ul class="dropdown-menu">
                <li><a href="{{ url_for('settings') }}">Settings</a></li>
                <li><a href="#" id="logout-button">Logout</a></li>
              </ul>
            </li>
          </ul>
      </div>
    </div>
  </div>

The SASS:

.navbar {
  .navbar-inner {
    background-color: $darkblue;
    @include background-image($blue-gradient);
  }
  div > ul a, .nav a {
   font-size: 14px;
   font-weight: bold;
   color: $white;
   &:hover {
      background-color: $darkblue;
   }
  }
  div > ul .active a, .nav .active a {
    background-color: white;
    color: $darkblue;
  }
  .dropdown-menu {
    &:before {
      border-bottom-color: #ccc;
    }
    &:after {
      border-bottom-color: $darkblue;
    }
  }
  div > ul .menu-dropdown, .nav .menu-dropdown, .topbar div > ul .dropdown-menu, .nav .dropdown-menu {
    background-color: $darkblue;
    li {
      a {
        background: $darkblue !important;
        color: white;
        &:hover {
          background-color: $darkblue;
        }
      }
    }
  }
}

#header {
  #header-logo {
    background-image: url('images/logo_long_trans.png');
    width: 138px;
    height: 40px;
  }
  #header-login {
    img {
      width: 16px;
      height: 16px;
      vertical-align: text-bottom;
      border: 1px solid #CCCCCC;
    }
  }
}

The result:

1 comment:

Claudio said...

Nice post! Just what I'm looking for!