The League of Extraordinary Developers

Telephone
0113 815 0986
Email
team@theled.co.uk

Blog

Whilst working on client projects we often find useful bits of information out. Where possible we blog about that information to pass on our knowledge. Below are some of our most recent entries.

Screengrab of the new LED site

Twitter Bootstrap - It's not all roses

I just dropped into the middle of a conversation on Twitter, mainly because of this statement "Twitter Bootstrap has proved its worth though. It is to HTML & CSS what jQuery is to JavaScript. It's about standardisation."

My reply was this: "I hope not. Twitter Bootstrap is awful. It's got loads of bad practice in it."

This got me thinking, what is it that I really dislike about Twitter Bootstrap? In the end I decided to write this blog post about my gripes with the framework.

There are two big issues I have with Boostrap.

  1. It forces you to use non-semantic markup
  2. It doesn't reinforce the idea of progressive enhancement.

To be fair, I've only used it once and it was a while ago, so things may have improved, but I doubt it. I decided that I'd like to use it for an existing product I have.

In the first draft of the product I'd spent time crafting the markup, and I was very happy with it. Semantically it was spot on, in my opinion anway. You know the way we are meant to do things, crafted.

I then came to looking at Twitter Bootstrap for 2 reasons.

  1. It would look a lot better than my existing product design / layout
  2. It had responsive built in. (Lazyness on my part)

So I quickly sat down and started to re-engineer my markup. Of course I expected to have to change things, but with each thing I changed I was battling with myself over the markup I was having to produce.I suddenly started to feel like the markup I was producing was sub-standard. The care and attention, the semantics was going out of the window, and fast. Ok, so who cares about semantics, I mean really which of my clients is going to read the HTML and say, "Woah! That's not semantic! I'm not going to pay this bill". The thing is, as a developer, I care. I always think, would I be happy if someone produced this markup for me? If the answer is no, then it's not good enough.

I'll show a few examples of what I mean shortly. Before I get to that I want to really hammer home some of my big gripes. Don't worry I'm not going to go into everything here.

Layout information in markup

My thoughts on CSS frameworks and those that force layout information into classes have been discussed in the past. Needless to say, I'm far from keen.

The idea of putting 'row', 'span4', 'pull-left' etc into my markup irks me at great deal, let alone the unnecessary tags that are often required to do things like group content into rows. '<div class="row">'

Twitter bootstrap does this heavily, so that's a big negative for me already.

Icons

Bootstrap has some useful icons built in as part of the framework, but upon deeper inspection there is something very wrong with it's icon markup. For those of you that don't know it uses the <i> tag. Let's just remind ourselves what the <i> tag is for http://www.w3schools.com/html5/tag_i.asp.

The <i> tag defines a part of text in an alternate voice or mood. The <i> tag is typically displayed in italic type. The <i> tag can be used to indicate a technical term, a phrase from another language, a thought, or a ship name, etc.

So why use it from icon placement? My guess is that the devs wanted to pick a tag that wasn't used widely and after all 'i' could be thought of as short for 'icon'. Basically it's wrong, wrong, wrong.

The irony is that the use of <i> is discussed on the Base CSS page. while <i> is mostly for voice, technical terms, etc. Clearly the devs can't follow their own advice.

A few real life examples

So as I said, I've tinkered with Twitter Bootstrap for a product. I'm just going to pick a couple of examples here of before and after. You can make up your own mind which is better markup.

Navigation and Header section

<header>
  <div class="inner-wrapper">
    <a href="/"><%= company_logo %></a>
         
    <nav>
      <ul>
        <li><a href="/">Home</a></li>
        <li><%= link_to "My Account", edit_account_path %></li>
        <li><%= link_to "Companies", companies_path %></li>
        <li><%= link_to "Teams", teams_path %></li>
        <li><%= link_to "Users", users_path %></li>
        <li><%= link_to "My Games", games_path %></li>
        <li><%= link_to "Log Out", destroy_user_session_path %></li>
      </ul>
    </nav>
  </div>
</header>

<header class="navbar navbar-fixed-top">
  <div class="navbar-inner">
    <div class="container">

      <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
      <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </a>
      <a href="/" class="brand"><%= company_logo %></a>
         
      <nav class="pull-right nav-collapse">
        <ul class="nav">
          <li><a href="/">Home</a></li>
          <li><%= link_to "My Account", edit_account_path %></li>
          <li><%= link_to "Companies", companies_path %></li>
          <li><%= link_to "Teams", teams_path %></li>
          <li><%= link_to "Users", users_path %></li>
          <li><%= link_to "My Games", games_path %></li>
          <li><%= link_to '<span class="label important">Log Out</span>'.html_safe, 
              destroy_user_session_path %></li>
        </ul>
      </nav>
    </div>
  </div>
</header>

Granted in the 'after' example there is the added collapsable navbar so there is some extra markup there, but to be honest that shouldn't even be in there anyway. The collapsable navbar is driven by JS and as such that additional markup that it needs should be written by the JS, and not polluting the markup.

Message alerts / notices

<% if flash[:notice] and flash[:notice] != "nil" %>
  <div class="notice"><%= flash[:notice] %></div>
<% end %>
<% if flash[:alert] %>
  <div class="alert"><%= flash[:alert] %></div>
<% end %>
	
<% if flash[:notice] and flash[:notice] != "nil" %>
  <div class="alert alert-success">
    <a class="close" data-dismiss="alert">×</a>    
    <%= flash[:notice] %>
  </div>
<% end %>
<% if flash[:alert] %>
  <div class="alert alert-error">
    <a class="close" data-dismiss="alert">×</a>    
    <%= flash[:alert] %>
  </div>
<% end %>

So to have a close message button in Twitter Bootstrap you have to add in a meaningliness <a> tag. I mean from an accessiblity point of view, what does 'x' mean? Surely it would make more sense to have some meaningful text like 'Close' in the <a> tag? Seeing as the close action is reliant on JS it would make even more sense to use Progressive Enhancement and get the JS to produce the close tag.

Conclusion

This is in no way a comprehensive list of issues with Twitter Bootstrap. I've definitely picked the easy targets here, but that is mainly because my experience is limited. I've seen other developers talk about issues with badly written JavaScript, and poor usage of Less. We use SASS here, so I didn't even bother to investigate that.

What worries me is that I've barely scratched the surface with Bootstrap, what other horrors can be found deeper? A lot of people seem to regard this framework as best practice, where as in reality it doesn't contain much best practice at all. The only reason the framework is so popular and gets so much coverage is that it's from Twitter. With the recent announcements from Twitter regarding client-side MVC rendering not being as fast as server side rendering, which most devs have known for a long time, it's pretty clear Twitter is quite a way off when it comes to best practices on the front-end side of things.

Don't get me wrong I can see why people love Twitter Bootstrap. It certainly makes it quick and simple to produce a decent looking page layout, but at what cost? It's certainly not a sacrifice I wish to be made here.

blog comments powered by Disqus

Read more entries

Keep up to date

Blog RSS feed

Want to find out more?

If we have piqued your interest then we'd love to hear from you.

Get in contact with us

Services

  • Ruby on Rails
  • .Net
  • PHP
  • HTML5
  • CSS3
  • JavaScript
  • Web Apps
  • Mobile Web Apps
  • iOS Apps

Blog

  1. Blog title
    C4DI and the magical coffee beans
    Post Date
    Thursday, September 05 2013
  1. Blog title
    Designers - how far should their coding knowledge go?
    Post Date
    Thursday, May 30 2013
  1. Blog title
    Twitter Bootstrap - It's not all roses
    Post Date
    Friday, June 22 2012
  1. Blog title
    Keep your requests thin
    Post Date
    Friday, January 06 2012
  1. Blog title
    Storing a Product Catalog for eCommerce with a Document Database
    Post Date
    Monday, November 21 2011
  1. Blog title
    Success for Incentive Maker - Hull Digital Post
    Post Date
    Friday, July 08 2011
RSS

Twitter

Follow