Using Sass To Semantically @extend Bootstrap
Bootstrap provides a quick and easy way to create a scaffold for your latest site or app whether you’re a novice or a professional developer. For this reason, more and more developers are including the framework in their personal toolbox.
There is, however, a dark side to Bootstrap, in that it makes it incredibly easy to write cluttered, non-semantic and non-reusable markup that will render correctly across all browsers.
In this article, I’ll explain how you can use Bootstrap in a more robust and semantic way. Bootstrap’s latest version shipped with an official Sass port of the framework so we’ll use one of Sass’s most powerful features to achieve this: the @extend directive.
Some Basics on Semantics
First, let’s cover what we mean when we say that we want to make things more “semantic”. HTML documents are intended to be descriptive of their contents from an information hierarchy perspective. One should be able to read them and know what they are about, not how they will look.
With the rise in popularity of CSS and especially CSS frameworks, HTML is often written with a CSS sheet in mind rather than a reader/developer.
It’s not uncommon to see HTML markup like this in the source code of modern websites:
<div class="row">
<div class="col-md-4">
Name:
</div>
<div class="col-md-4">
John
</div>
<div class="col-md-4">
Smith
</div>
</div>
<div class="row">
<div class="col-md-12">
<p>
"I enjoy writing code in my spare time."
</p>
</div>
</div>
Bootstrap’s CSS files know exactly what to do with that. Two rows, one split into thirds and the other full width. As developers who are familiar with Bootstrap, that’s easy enough for us to figure out, but what if you’d never used the framework before? What is this snippet of HTML for? What does the information pertain to? The markup isn’t revealing anything practical.
Semantic markup is code that describes it’s content rather than its appearance. We could write the code above semantically as follows:
<div class="author-name">
<label class="author-nameLabel">
Name:
</label>
<span class="author-nameFirst">
John
</span>
<span class="author-nameLast">
Smith
</span>
</div>
<div class="author-bio">
<p>
"I enjoy writing code in my spare time."
</p>
</div>
It’s not all that different but it immediately tells us what each element is for and how each one might relate to other elements. What we’ve lost is the knowledge of how this will be presented visually. But that’s not the purpose of HTML after all.
How is Bootstrap Supposed To Style That?
You might be wondering how you’re going to use Bootstrap without any of its built-in class names in your markup? Well, we can leverage the power of Sass’s @extend
functionality to solve this problem.
From Sass’s documentation:
@extend
works by inserting the extending selector anywhere in the stylesheet that the extended selector appears.
This means we can use our semantic selectors and extend Bootstrap’s selectors to get all of its goodness. Here’s how:
/* Import bootstrap-sass so that we have access to all of its selectors */
@import "bootstrap";
/* Author Bio and Author Name are just Bootstrap .row elements */
.author-bio,
.author-name {
@extend .row;
}
/* Author nameLabel, nameFirst and nameLast need
to be a third of their container's width */
.author-nameLabel,
.author-nameFirst,
.author-nameLast {
@extend .col-md-4;
}
/* The paragraph inside the author's bio should be full width */
.author-bio p {
@extend .col-md-12;
}
Through the magic of @extend
, our selectors are slotted in to the compiled stylesheets alongside the Bootstrap selectors they extend. As you’ll see by examining the compiled code, our selectors have all the exact same properties as the classes they’re extending.
For example, among other things, you should see this in the compiled CSS:
/* one of the compiled rule sets */
.col-md-4, .author-nameLabel,
.author-nameFirst,
.author-nameLast {
width: 33.3333333333%;
}
You can view the Sass side by side with the compiled CSS here. Neat huh?
Reusability
Another great thing about this method is that it creates readable and reusable components. For example, you don’t have to rebuild the author component out of rows and columns each time you need to use it. Instead, you have sensible names for each part of the component, making it easy to construct. You can also rely on Bootstrap to make sure it’s presented uniformly across your site.
Portability
While Boostrap is one of the best frameworks available, the time may come when you want to move your site to a different framework or even write your own. With the above outlined method you can do so easily because your markup is cleanly decoupled from your CSS.
Fill Your Toolbelt
If you haven’t yet tried the Sass version of Bootstrap, you’re in for a treat. It’s easy to get started on their github page.
Sass isn’t the only thing at play here. If you truly want next-level semantics in your HTML and CSS, I recommend adopting a naming convention such as BEM or SMACSS to keep your selectors standardized and easy to remember.
Go Forth And Extend
Bootstrap gives us an incredibly powerful set of styles – but it’s all too easy to cobble them together into something presentable at the loss of quality markup. With Sass’s @extend directive, you’re free to write markup that speaks clearly both to its contents and to the developers reading it.