CSS Structure
Most programming languages have a clean structure that defines where a variable is set and can be used. Sometimes they need to be defined at the top of the document, sometimes global outside functions and sometimes specially inside functions or object.
CSS doesn't have some sort of "forced structure" or "best structure". You can write poorly, bad CSS with a lot of repeating and re-writing or you can do it right. But is there really a "right" way? I guess not, people online are discussing this topic everyday.
My personal "right way"
Let's start with a bad practice.
.my-class {width:500px; height:auto;}
.my-class > h1 {color:green; font-size:1.5em;}
.my-class > .my-other-class > p {font-size:1.3em}
Let's say this would be some markup to create a basic article style. Everything would work as expected as long as the HTML Markup doesn't change. But let's say there comes a new developer who will change all h1
to h2
and the p to small
-Tags? Do you see what would happen? Nothing would work anymore.
Therefore I highly recommend to write readable CSS and - the most important - to use describing class names, even if the are longer than short ones. Here's a good example using the [Syntax Harry (csswizardry) described here].
.article {width:500px; height:auto;}
.article__header--headline {color:green; font-size:1.5em;}
.article__footer {font-size:1.3em}
This one would produce the exact same output as the first code block, but if the HTML elements change, the styling will stay the same.
When your Team of Developers can come up with this syntax - or equal one - everyone will be able to actually see what a class does.
Last words about good CSS:
- Avoid IDs (they're better used for JS only)
- Use readable class names
- Comment your code
- Do not repeat yourself
"Do not repeat yourself" - if it comes to the point that you have 6 Modules with the exact same properties, you'd better combine them into one Block inside your CSS.
e.g.
.site-header,.single-article,.site-footer,.sidebar {
background:#fff;
box-shaodw: 0 0 10px rgba(0,0,0,0.4);
border:1px solid #ccc;
}
This will be much more maintainable and with SASS you can even use the @extend feature so you do not need to write those blocks by yourself.
I'm really looking forward to feedback and your way to structure CSS.
Written by Kevin Gimbel
Related protips
12 Responses
We have adopted BEM where I work, and it's pretty nice: http://coding.smashingmagazine.com/2012/04/16/a-new-front-end-methodology-bem/
@donutdan4114 Yeah. BEM is terrific.
You should never have to write a class called .article__header--headline
if you truly grok cascading.
"Keep things generic and re-usable." is one of the golden CSS rules that I always remind myself of whilst developing styles.
@ultimatedelman then please tell me what else would be a good use. I'm willing to learn from mistakes. :)
@davidandrewsmit I agree, especially re-usability is very important though.
@kevingimbel the correct way would be to have a semantic structure, like so:
<article>
<header>
<h1>My Headline!</h1>
</header>
</article>
So you can reference your h1
like so in your SCSS file (if you wanted to get this specific):
article {
h1 {
//header styles here
}
}
Of course you can add classes and such, but you shouldn't give your elements classes of the same name as what they are, for instance, you shouldn't do this: <article class="article">
. A better convention would be something like <article class="news">
or whatever the article is supposed to be representing.
@ultimatedelman in one point I agree with you: Giving an <article>
the class article
is kinda useless, but there is a reason why I avoid SCSS Structures like
article {
h1 {
}
}
If the markup changes, let's say because a new developer comes and decides that all articles should have an h2
as headline because an h1
headline is only used on the header
, they'd need to change the SCSS, too. If I use describing names like single__article--headline
they're readable AND can be applied to any kind of element. If you only have one thing to change it wouldn't be a big deal but imagine you have a site with hundreds of different elements, all only made with nesting or in other ways related to the mark up. You'll end up running through all your codes to change all the things - if you have describing names and avoid nesting, you'll be able to make changes much faster.
I do lose the nesting feature of SCSS but nesting can cause more problems than it solves. I do only nest :hover
,&:before
, &:after
and :focus
- in other words: most of the time only pseudo elements.
I can get much more out of SCSS by using mixins and vars.
Like I said, you can get as specific as necessary, or add classes to your elements. For example:
<article class="news">
<header class="headline">
<h1 class="title">I like tuhtles</h1>
</header>
</article>
Your CSS can now be very generic and reusable:
.news { //styles }
.headline { //styles }
.title { //styles }
If you want to change your h1
s to h2
s, no problem. You can also re-use your .title
class elsewhere, but if you wanted to be specific about a .title
in a .headline
you just do:
.headline {
.title { //overriding or additional styles }
}
If you do something like this, you've properly leveraged (I hate that word) cascading, whereas in your example, your pieces are far less modular and will get very specific very fast.
So what would you say? Working on a "My CSS is like my HTML" base requires to change both whenever something new comes in. Which way of naming is the best?
I agree with you Kevin! 100%!
@kevingimbel there's no magic bullet when it comes to building a site. When you change something in one part, you'll often have to change something elsewhere. It's just the nature of the beast. The trick is coming up with loosely-coupled conventions that minimize the amount of change required ;) Your above conventions are very tightly-coupled.
That seems pretty standard now a days, just the syntax is horrendous. Why the need for underscores?
.module
.module--modifier
.module-element
.module-element--modifier