Let's face it. All websites need CSS and yours is probably awful. There's too much of it. There's a bunch of duplication. It's like a delicately spun spider web, tightly coupled and fragile. It has more patches than a bicycle wheel. It doesn't need to be this way. I’ll introduce you to the concept of component-based styling and show you how to curate a style guide for your site.
Why is this so hard?
I hate CSS. I just want to write code.
- A lonely developer, after finally getting that margin-right right
Sound familiar? Here are some common CSS code smells you may have run into.
- Whoa that’s a lot of CSS. You know the file I’m talking about. It’s got more than 1,000 lines of CSS and it’s hard to navigate.
- Writing CSS when you shouldn’t have to. This website you’re working on isn’t new. There are already buttons and tables and lists on plenty of other pages. And yet, when working on a new feature, you still have to write a bunch of CSS to make the elements on your page look like they do on the rest of the site.
- No re-use. Do you have a user-table class and a transaction-table class, each with their own styling? Do you wish you had a single table class they could both use?
- Everything is special. It would be easy to make both tables use the same class, but this is not a straight case of copy-paste. Each table has been tweaked in its own unique way. There’s no consistency on the site. Every element is precious.
- Side effects. Thank goodness. You’ve finally got your page looking right and it feels good. Until you notice some odd things happening on the rest of the site. You can’t change one thing without a ripple effect breaking things elsewhere.
It doesn’t have to be this way
There are two principles that can help you stay sane when styling your site. The first is that you should treat your CSS like code. CSS is the most neglected programming language. We think it’s too hard to keep it maintainable so we don’t even try. When you start applying the same coding practices you’re used to in other languages, you’ll see that writing CSS isn’t so bad.
The second is that you should think about your styles like a consumer. We don’t think about re-use when we style our websites, so our styling is never re-usable. When coding something new, we find it hard to know what the right way is to do it, or even what the end product should look like. When you’re actually consuming an API as you code it, it ends up being much easier to understand and use. In the same way, structuring and presenting your CSS in a way that is geared for re-use will make it much easier to benefit from the hard work you’ve already done once.
I’m going to take you through a practice I like to call Component-based Styling and show you how this can help you treat your CSS like code, think about your styles like a consumer and make your site’s styling easier to understand.
Introducing the style guide
One of the core practices of component-based styling is creating a style guide for your website. What is a style guide? Let’s look at a familiar example.
If you’ve ever used a styling framework like Bootstrap or Foundation, you’ll recognize this concept. Let’s say you’d like to leverage the work the nice folks at Twitter or Zurb have done and use one of their pretty components. For example, you visit the Bootstrap website and scroll around until you find what you’re looking for – an error alert.
The first thing you do is to include their CSS in your website. Then you go to the HTML file where you’d like the alert to appear and use the markup structure you find in the code snippet below their example.
<div>This is my scary alert!</div>
In this example, it’s simple – all you have to do is put the text for your message inside a <div> tag. Next, you add some classes that they show in their example.
<div class="alert alert-danger">This is my scary alert!</div>
That’s it! You open the page in your browser and your new alert is styled just like the example on the Bootstrap site.
What is so special about what you’ve just done? You’ve styled a component on your website without writing a single line of CSS. You wrote some markup, copied a few classes and it looked like an alert. Now imagine if you could do the same thing for the styles on your own website.
Creating your own style guide
(It’s not pretty, but it demonstrates the concept.) |
Wouldn’t it be nice if styling new pages on your site was as easy? It can be. Create your own style guide.
The simplest way to get started is to create a new style-guide.html file at the root of your project. Include all your site’s CSS. If you’re already concatenating and minifying your CSS, this should be easy.
The next step is to start adding examples of your own components. A component could be as simple as an alert or a button:
It could also be something very specific to your website or business domain, like this box for displaying products:
Notice how each component includes an example of what it looks like as well as the HTML code you need to create it.
Let’s look at the code for the style guide itself. Each component has its own section, which features an example. You’re already pulling in the site’s CSS, so that will do the work of styling the example.
<div class="component">
<h3>Button</h3>
<div class="demo">
<button>I am a button</button>
</div>
</div>
We can use a little JavaScript to automatically find all the .demo elements and add the code used to render the component in a little box below it. Using this technique, you can avoid duplicating the HTML. The bonus is that the code we see for a component is always in sync with the code being used to render that component. I find this to be a really useful form of living documentation.
The real magic of a style guide is that it uses the same CSS as your site. It offers an accurate summary of the styles available to your site. This is helpful when designing and development as it showcases the options available and provides a single place you can experience the look and feel of the site.
Having living documentation is so helpful. If you change the CSS, the style guide and the actual site are both updated. Because they share the same CSS, the documentation of your components and the components themselves will be the same. If the component you update looks good on the style guide, but bad on the actual site, it means your HTML is not consistent. If it looks good on the site, but bad on the style guide, it means your component isn’t reusable enough and you have to change your CSS.
If this is a brand new site, you can add components to your style guide as you create them. Don’t be put off if you have an old site, though. If you’re creating a style guide for an existing site, you can add components whenever you happen to be working on them. When you do, you can do some refactoring to shape your CSS to better suit a component-based model. Over time, you’ll improve your CSS and make the components on your site more consistent.
Tip: Having your own style guide doesn’t mean you can’t still leverage a framework like Foundation or Bootstrap. Just include their stylesheets as usual, and build your components using a combination of their styles and your own. |
Keeping your CSS DRY
We’ve covered the concept of component-based styling and a couple of pointers on how to get started with a style guide for your website, but you might be wondering how you’re actually going to code this. Let’s take a look at some CSS coding practices that will help you create your style guide and keep your CSS DRY.
The first rule of CSS is don’t write any CSS
CSS is an outdated language that doesn’t offer much help for keeping your code clean. Instead of writing CSS by hand, use a language like Sass or Less that will offer you additional language features and compile into the CSS the browser will understand. These languages provide features like variables and functions to make coding your styles more like coding for real, allowing you to focus on maintainability.
Style each component once
It’s very important that the CSS for each of your components is easy to find and modify. To achieve this, we make sure that all the code for a particular component is in a single place. For every component, you should have a separate file (e.g. _button.scss, _table.scss). In this file, you should have a class or element for your component, within which you can nest all the associated styles. I like putting all these files in a components directory. In the example below, you’ll see the Sass code for our product box component, as well as the small changes it makes to buttons.
.product-box {
background-color: white;
border: 0.2rem solid $grunge_grey;
padding: 1rem;
min-height: 24rem;
margin: 2rem 0;
button {
margin-top: 2rem;
width: 100%;
}
}
Consistent markup
Remember our Bootstrap example. We copied some HTML and the component magically looked like we expected it to, without writing any CSS. The only way that this works is if the HTML is consistent. If your product boxes are <div> tags in one place, but <span> tags somewhere else, you’re never going to achieve the consistency you’re looking for. You’ll be stuck writing extra CSS to compensate for the differences in HTML. I cannot stress this point enough: writing more consistent HTML means less CSS. Less CSS means fewer headaches.
Scope specific styles
As much as component-based styling will help us keep specific CSS code to a minimum, it is inevitable that you’ll still have to write specific CSS. There are always cases where, on a particular page, a component needs extra padding or needs to be aligned differently. The trick is to make sure your CSS code that caters to such a scenario only applies to that scenario and nowhere else. We achieve this by using the power of SCSS to nest our specific styles in a class that is only associated with the page where it’s needed. Let’s say, we want our buttons to be twice as big on the checkout page of our site. You know, so people buy stuff. We need to write some CSS to achieve this, but first we add a class to our HTML for that page.
<div class="checkout-page">
<!-- … -->
<button>Pay now</button>
<!-- … -->
</div>
We can then use the checkout-page class to scope our SCSS so it only applies to this bit of HTML.
.checkout-page {
button {
height: 6rem;
font-size: 2rem;
}
}
This helps us make sure that whatever we fiddle with in this scope won’t affect the rest of the site and the way we expect our buttons to behave elsewhere.
The code above actually raises an interesting question - should we be creating a new component? You could argue that, instead of making this code specific to the checkout page, we could have created a big-button component, which we could use elsewhere in future. You certainly could and whether you should or not just depends on whether you’re going to be adding more big buttons in future.
Be critical of every line
An interesting phenomenon with CSS is that, while it is a language that is pretty easy to get decent at, there are very few developers who have mastered it. For most of us, writing CSS is a trial-and-error process and that’s not going to change. During the course of trying to get something to look right, you’re bound to add all kinds of code to try achieve the effect you’re looking for. The trick is to revisit your code after you’ve written it. Delete every single line of CSS you’ve written and see whether that line actually helped. Do you really need that overflow: hidden, did changing the display to inline actually make a difference? If not, delete it. The less code you leave behind, the less code there is to confuse you the next time around.
Talk about keeping things simple
When it comes to styling a website, simpler is better. HTML is a particularly simple creature. It expects a nested list of elements - top to bottom, left to right. Try not to fight the Internet too much. Try not to get too fancy with how you put things together. The more complicated you make your markup and your pages, the more difficult styling will become. This is especially true on mobile devices.
Our customers often ask for visual differences that seem simple at the surface level. For example: ‘can this image be below the heading on mobile, instead of above it?’ The mistake that many developers and designers make in this scenario is to say ‘sure’ and then spend the rest of the week trying to craft the CSS that will make it happen. I’ve often found that a conversation is very useful at this point. Explain the complexity involved in the change and how much longer you think it’s going to take. Remember that more complex code doesn’t just take longer to write, it also makes future features take longer. I’ve often seen customers respond by saying: ‘oh, I didn’t realize it was so complicated. Just do it the simplest way and then start work on Feature X.’
The trick is to keep your non-technical stakeholders informed. Understanding how the web works and what the path of least resistance is will help them immensely in their daily decision making.
Mobile first
Taking an existing desktop site and trying to make it look good on a mobile device is an arduous task. Try to avoid this situation. Mobile devices are everywhere and users expect sites to be usable on their phones. One of my pet peeves is opening a restaurant’s menu on my phone and being faced with some horrible interactive magazine animation or a message about a missing plugin, when a simple text list of items next to prices would have done the trick.
When starting work on a new site (or a new page on an existing site), put together your markup and your CSS in such a way that it renders properly on mobile. Do this first. Then, with that working and looking good, you can add some media queries to embellish the page for larger screens. Give things more breathing room, let things spread out horizontally, add images that would have been too big for mobile. This way, your user’s core experience will be the same across devices and your CSS will be much simpler. In my experience, it takes much less code to make a mobile-friendly page look good on a desktop than the other way around.
Less CSS, less hassle
The basic premise the techniques we’ve covered are based on is that less code is easier to work with than more code. By treating your CSS and HTML in the same way as you treat the rest of your code (and by using tools that support this), you will reduce the amount of duplication and build a code base that is easier to reason about and work with. When you adopt component-based styling, you force yourself to make it easier to reuse your styles. Give these techniques a try. Think about how your CSS is organized and put together a style guide. Let me know how it goes. Hopefully it saves you time and you’ll stop having shivers running down your spine whenever you open a CSS file.