CSS: From I hate it, to I actually like this thing

Do you feel hopeless when you have to work with css? Anxious knowing the site will break the minute you add a minor change to the styling? No more my friend! These 9 steps will make your life easier!

CSS: From I hate it, to I actually like this thing

I remember on my early days as a web developer I'd get a task that sounded so simple "Hey Ignacio, we need to add a small red button bellow this form. It has to be aligned to the right. Oh, and btw vertically centered too". I was doomed. A few hours spent breaking the site, fixing it and breaking it again with every CSS change I made. We have all been there...

Hopefully, after reading this post you'll learn some tips to help you on your path to mastering CSS.

Let's start:

0. Drop old browsers support

I wouldn't call this exactly a tip, hence the 0, but it's something I always consider whenever I take on a new project.
Try to avoid supporting old browsers versions. Look at usage stats, and balance more user reach vs. extra development costs. Giving support to stuff older than IE 10 is painful.

Of course, this is not always possible. I know of a company that forces all their non-tech employees to use IE 7, so every internal tool has to work on it. If that's your case, I'm really sorry for you. You will have to live in the old land of hacks and browsers inconsitency that we're all trying to forget about - I can't help you.

Also, if you already have a public website and have the stats, look at how browsers versions behave in the context of your business. For example, in one of the projects I used to work on, the percentage of users using IE was low in terms of visits. But when you looked at data like conversion by browser, IE users had a much higher conversion rate, which led to a non minor percentage of the revenue.
Give support to stuff that matters to you.

1. Understand CSS rules precedence

I can't stress this enough. If you don't understand why certain property is being applied over another you'll be in a constant battle against frameworks, libraries or even your own site set of stylesheets.

Let's say you have these HTML and CSS snippets:

<div id="container" class="my-container">
  I want my <span class="text red">color</span>
#container span {
  color: blue;

.my-container .text.red {
  color: red;

Which color do you think the text will be?
If you're answer was, "I don't care, I'll just use !important on the one I want", then I wish you a life full of IE 6.
For the rest of the people that do care, the answer is blue. No matter how many class selectors you add to the second rule, you'll never get it to be red.

The key is that different types of selectors (#id, .class, element or inline) have different precedences. Each selector will get a "score" and the one with the highest value wins.

A good resource to learn about this topic is this great short blog post by Steven Bradley Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade.

2. Use a preprocessor

Nowadays it's difficult to find a webapp that uses plain CSS instead of a preprocessor, but if you're starting a new project, add a preprocessor at an early stage. Mixins, variables, parent selectors and importing will help you keep your stylesheets modular and DRY from the get go.
I always chose SASS, which is currently the most popular tool, seconded by LESS.

3. Embrace flexbox for layout

With flexbox you can build a consistent, responsive layout with only a very small set of rules. After you use it for the first time, you will never want to write a float or use Bootstrap's grid system again.
I love this simple game, flexboxfroggy.com, to learn the basics.

You'll have to be careful with each browser compatibility and their custom prefixes. Which leads me to the next point...

4. Don't write vendor prefixes manually

Adding each browser's prefixed properties means duplication, which is tedious and error prone.
Autoprefixer is a tool that will help you to deal with the small differences between browsers. Based on http://caniuse.com/ , you define which browser versions you want to support and autoprefixer will look at your stylesheets and add the properties required for each vendor. Forget about those pesky -webkit or -moz prefixes.
Whether it's the rails asset pipeline, webpack, gulp or grunt, it should be fairly simple to integrate it.

If you can't mess with your pipeline, then at least try to use something like Bourbon, a SASS mixins library that adds all the prefixes for you.

5. Don't just use any class name, use a methodology

As your project grows, the number and complexity of your styles can become a problem. If you're not careful, adding a simple property to a class can have unexpected impact on other parts of your site that you didn't intend to change.
Using a specific methodology will prevent these kind of erros. At the same time, it will set an standard in your codebase, keeping consistency between all the different developers' styles.

There are a few different techniques: BEM, OOCSS, SMACSS, etc... The one I'm most familiar and quite happy with is BEM.

With BEM (Block, Element, Modifier) you define classes of the type block__element--modifier. For example, if you have a header with your company logo and a sign-in button in it, you'd have classes like header__company-logo, header__sign-in-btn or header__sign-in-btn--hidden. Now, when you look at a selector in a stylesheet, you know which element it's impacting and where to find it.

Also, BEM suggests a flat classes structure (instead of nesting like in .header .sign-in-btn). This way you decouple your HTML layout from your styles. You can take a <button class="header__sign-in-btn">, move it around in your HTML and its style will always be the same (except for inherited properties of course). Neat!

6. Learn about different types of units

What's the difference between px, em and rem?
Do you know what viewport units (vw and vh) are?

Adding stuff other than % and px to your toolbox will allow you to expand on what you can do. Especially when dealing with a responsive website.
Learn about them here.

7. Understand all the different position values

Ever wondered why sometimes you set position: absolute and your element skyrockets to the top of your window and why sometimes it just stays there?

The key is how each element position value plays with each other. absolute, relative, fixed or static have their own valid use cases and you should understand when each of them is needed.

8. Pseudo-selectors

CSS selectors don't end at classes, ids and elements. With each new CSS spec version, new pseudo-selectors appeared that allowed to do in plain CSS stuff that would've previously required Javascript or backend code.
:last-of-type, :last-child, ::before are a few examples of pseudo-selectors that get used all the time. This site has an extensive list of pseudo-selectors with their definition, examples, and support of each browser version.

9. Make heavy use of Chrome's developer tools

There're not many hidden secrets here, but make sure you understand everything that the "Styles" and "Computed" tabs have to offer. They're very useful to understand where certain properties are being set and test new changes more quickly.
Also, set your pipeline to produce source maps, so you can see the file name and line number where properties have been defined from the browser.


After going through all these 9 points, you will have a fair understanding of how to be in control of your styles, specially in terms of layout, which in my opinion it's the most complex part.

Of course the CSS world it's much more than layout and there are many more advanced topics to cover, like animations, transitions, transforms, the new grid layout, etc... On top of that, you need to understand what each styling property does and what are their possible different values, but that comes in a as needed basis.
Becoming a CSS pro takes a lot of time and practice, but with a strong foundation it doesn't have to be a painful journey.

And to end this article, no CSS post can be complete without this GIF. It never gets old!


A Portuguese version of this post can be found here. Thanks @leandrw for the translation.