You are too lazy to write markup independent CSS
Let’s face it: almost everybody is using things like normalize.css or creating his own basic element styles. The reasons for doing so might be the following:
- You don’t want unstyled elements
- You want to write simple and clean html
- You want to be fast and write less
Well, I understand that. But do you agree that using CSS has the following advantages?
- Creating reusable style rules
- Separating markup and styles
If yes, I am asking you:
Why is it evil to style elements?
Styling elements means you are attaching your styles to the DOM. I bet you have seen something like this in the past
<h1 class="as-h2">I am an evil styled element headline</h1>
Why do you need this? In this case you styled the <h1>. Why not use <h2> instead? Because your content structure forces you, cause you care about semantics, to use <h1>. So in your .as-h2 class you need to rewrite every single rule of the <h1> tag that you don’t want on your h2 element styles. You think that’s not much work? What about the other headlines? In the worst case you need a combination of each headline class matched to each headline element style, which might look like this
.h1-as-h2
.h1-as-h3
.h1-as-h4
.h1-as-h5
.h1-as-h6.h2-as-h1
.h2-as-h3
.h2-as-h4
.h2-as-h5
.h2-as-h6.........h6-as-h5
Don’t understand yet? I have more examples!
Have you done this before?
a:hover { //I am an evil styled element
text-decoration: underline;
}
If yes, then you certainly have also done this here in a navigation:
nav {
li a:hover {
text-decoration: none;
}
}
And that again in a button style used on an <a>:
.button:hover {
text-decoration: none;
}
So again..
Thats not everything!
It’s shit for debugging
Thats an example of the Chrome Developer Console:
Although Chrome does a nice job in displaying the “real” attached styles and striking through the overwritten styles, it would be much easier to read if we could avoid it. The screenshot above is a real world example I found on a public website. Besides all the overwrites there is another problem you can see: someone has overwritten the text-decoration: none; although it was already set to none. Why? Maybe he was just confused? Or he wanted to make sure changes to the <a> wouldn’t break his button styles?
It’s shit for teams
Have you ever worked in a company with an inhouse SEO genius? If not, I can tell you most of the time the workflow is as follows: you create the project, you carefully craft the markup, you design it with much much love and then your SEO specialist has to optimize it afterwards… and he tells you
Fuuuuuuuuuck! Do you now how much work that is? It’s not possible, the deadline is tomorrow!!
Guess what? I know how to avoid this.
Don’t ever style your elements (globally)!
Ok, I think you got the point.
Classes to the rescue
Use classes instead. Use classes for everything you style. At first it seems like it requires you to write much more code but as seen above: that’s not the case. You will write more classes, but if you do it right, you will never need to overwrite a rule.
<p class="paragraph">I am always a beautifully styled paragraph.</p>
And I know what you think right now!
Exactly! <p> says “I am a paragraph” but <p> does not say “I look like a paragraph”, that’s CSS’s task! Now you might think that your <p> will always look like a paragraph and not like anything else, ever. What about that here?
<p class="intro">I am always a beautifully styled intro</p>
<p class="hint">I am always a beautifully styled hint</p>
<p class="description">I am always a beautifully styled description</p>
I hope you are convinced :) What about links? Simple! Use classes.
<a class="link">I am always a beautifully styled link</a>
<a class="text-link">..</a>
<a class="navigation-link">..</a>
Dealing with headlines
Instead of styling h1-h6 you need to name them. In my opinion it’s really hard to give your headlines semantic names, as the designers mostly use them “like they want”. To you as a logical thinking developer it’s sometimes not easy to understand why one headline looks different then another one, even though the hierarchy is the same. In most projects I use an approach like this one:
.headline { ... } //used for all headlines
.headline.large { ... } // used for the largest headline, mostly h1
.headline.big { ... } // mostly h2
.headline.medium { ... } // mostly h3
.headline.minor { ... } // mostly h4
.headline.small { ... } // mostly h5
.headline.mini { ... } // mostly h6
Problem with this is, that you might say “large” is bigger than “big”, but somebody else might think “big” is the biggest headline. Same problem with “small” and “mini”.
Dealing with CMS generated markup
The problem with a CMS is that you don’t always have the control about the output of a WYSIWYG editor. If you can control it: apply classes. If you can’t control it: use a wrapper class.
.wysiwyg {
h1 { ... }
h2 { ... }
p { ... }
a { ... }
...}// or like that
.paragraph, .wysiwyg p { ... }
If you are using a preprocessor like Sass you could easily make use of extends.
.wysiwyg {
p { @extend .paragraph; }
}
But please use this .wysiwyg class with care! Always apply it on the lowest level, so it really only affects the content coming from the CMS.
Navigation lists
The same problem might apply to dynamically generated navigations. But again, same rules apply. If you can control it: apply classes. It might look like this:
<nav class="navigation">
<ul class="navigation_list __level-1">
<li class="navigation_item __level-1">
<a class="navigation_text __level-1">Navigation item name</a>
<ul class="navigation_list __level-2">
<li class="navigation_item __level-2">
<a class="navigation_item __level-2"></a>
</li>
</ul>
</li>
</ul>
</nav>
If you can’t control the output make sure to use a safe wrapper class and style the <ul> and <li> within it. There is no better way so far. You could also add classes using javascript but that might also not be so nice. Try to avoid rules that style elements on more than one level, cause you will then find yourself overwriting yourself a lot. If your navigation contains more than 2 levels you will be frustrated very, very soon.
Omg this makes my HTML so ugly
Really? I find it much easier to read. You need to name everything you do, so it’s easier to communicate to others. It’s not just an <ul> it’s a navigation-list, it’s not just a <p> it’s a product description. It’s not the first <p>, it’s the intro.
Is normalize.css forbidden?
Sure, you can use it. For example if you fear browser default styles. Although you could also overwrite those browser defaults in your classes. In my eye there is no real need for it, it just bloats your css and you will do even more overwrites.
Use display on every class
To really encapsulate styles from markup you will need to define the display property on every class. Why? Because of browser defaults. Imagine this:
<div class="hint">Remember to always set a display property</div>
And now your SEO specialist comes and tells you it must be this
<small class="hint">Remember to always set a display property</small>
— said you, the developer who uses markup independent CSS. You, who knows that <small> is an inline element by default, but you don’t care, cause you have foreseen this scenario like a CSS wizard, and you added a display property before the SEO specialist even got the chance to destroy your dreams.
Summary of rules
- Don’t style elements, use classes, always
- Use wrappers if you can’t set classes
- Set browser defaults in classes, especially the display property
- Don’t overwrite yourself
Summary of benefits
- Less magic: you only inherit styles if you want to do so
- Less writing: you don’t overwrite yourself
- Less need to use @important: specificity should never be a problem
- Less confusion reading markup
Cheers! If you want more of that, don’t forget to follow ;) If you still have problems or edge cases, feel free to ask in the comment section.