Coding in any language is hard before you spend time mastering it. Imagine what your JavaScript would look like if you never took the time to learn about OOP or functional programming principles? Just because you expect CSS to be easy, doesn’t mean the language is broken when you find it is not.

A lot of people have gone on about how horrible JavaScript is . JavaScript is not horrible. It is an incredible language. It has a few odd quirks, just as CSS does. But if you take the time to actually understand these quirks, you will reap huge reward.

You cannot be proficient in JavaScript until you understand coercion, prototypal inheritance, and asyncronous flow control. Likewise, in CSS, you have to understand the cascade, inheritance, and the box model. Once you have those down, take a deeper look at the various layout methods. Do you know what stacking contexts and block formatting contexts are? Do you know why setting a height on an element leads to problems and how to accomplish what you need without doing so?

CSS is hard. But this is not because the language is faulty. Rather, the difficulty lies in what the language seeks to accomplish. I’ve heard many developers say they wish they could “throw out CSS and start over with something better.” I think this betrays a fundamental misunderstanding of the purpose of the language:

Furthermore, CSS isn’t just code, it’s also part of the design. A vital concern of CSS is consistency . You should want “global” styles: colors and spacing should be consistent throughout your application. Similar components need to look similar. Your buttons should all be consistently sized and your box shadows or border radiuses should not be ad-hoc.

I find it ironic that developers who bemoan the “global” nature of CSS are usually the ones who run into specificity problems because they unnecessarily scope their styles to particular parts of a particular page. When you have selectors like #directory .sorted .sidebar :nth-child(2) button , your problem isn’t that CSS is global. Your CSS isn’t global enough!

The next thing you know, you find yourself using !important to correct specificity problems. This is a red flag that you need to stop and learn the cascade. You can use !important to sweep specificity problems under the rug once. But you will soon need it a second time, at which point you will face the same specificity problem all over again.

Design your styles so they can be reused, anywhere in the app. Learn SMACSS and BEM. And don’t stop because you understand the “naming system”—these methodologies are about far more than double-underscores and double-hyphens. They are about code organization, reuse, and refactoring. They are the solution to dead code elimination. They offer ways to utilize the cascade instead of fearing it. They allow you to know precisely where in your code you can find a certain set of styles.

CSS isn’t broken. But it does require study and skill . It does require careful thought. As with anything in programming, you can make a mess of the code. Sure, blaming the language is the easy way out. But when your JavaScript is confusing and buggy, you know it’s not the language’s fault.