Hi folks! 👋 A while ago, I started adopting this little style convention in my CSS code, and I wanted to share it with you in this article.
➡️ It is about defining an order over the various declarations that may appear into a selector. Let me be more specific.
Instead of just throwing all of my declarations one after another, without any particular order, I try to divide them semantically, grouping them under a common area.
Approximately, this is the skeleton that I try to follow:
.my-selector {
/* display stuff */
display: ...;
grid-template-columns: ...;
/* positioning stuff */
position: ...;
left: ...;
z-index: ...;
/* box-model stuff */
width: ...;
padding: ...;
border: ...;
margin: ...;
/* typography stuff */
text-align: ...;
font-family: ...;
color: ...;
/* manipulation stuff */
transform: ...;
filter: ...;
opacity: ...;
/* misc stuff */
box-shadow: ...;
border-radius: ...;
}
Of course this is just an approximate blueprint, and I do not follow it strictly each and every time. If an exception should be made, so be it!
But the thing is, in the general picture, keeping this kind of style helps my code in at least 3 ways:
✅ It's more consistent
✅ It's less error-prone
✅ Overall it's more readable, and thus more maintainable
Just to give you a quick comparison example, this is what a simple button could look like without using any ordering for its various declarations:
button {
text-transform: uppercase;
border-radius: 8px;
display: inline-flex;
padding: 0.5em 1em;
font-size: 1rem;
align-items: center;
transition: 250ms ease-out opacity;
gap: 1em;
text-align: center;
font-weight: 700;
background-color: #252b2e;
color: white;
border: none;
justify-content: center;
cursor: pointer;
}
😐 Pretty overwhelming, isn't it?
The very same button, with some tidy-up, could look a little bit nicer:
button {
display: inline-flex;
justify-content: center;
align-items: center;
gap: 1em;
padding: 0.5em 1em;
border: none;
background-color: #252b2e;
font-size: 1rem;
font-weight: 700;
color: white;
text-align: center;
text-transform: uppercase;
transition: 250ms ease-out opacity;
cursor: pointer;
border-radius: 8px;
}
😁 Much better!
Now, at a glance, I can see more clearly where everything is placed in the code, and if I just need to modify the background-color
for this button, I know where to look.
At this point, one could also enforce an ordering for the declarations inside each group: it could be alphabetical, it could be something else.
I really just focus on the big picture here: to me, it doesn't really matter much if a font-size
comes before or after a font-weight
.
What matters, is that typography-related declarations are well distinguishable and separated from, for example, display-related ones.
And that's all! Feel free to leave a comment and let me know what you think about this! 😉
Till next time! 👋
Top comments (8)
Meanwhile, the dev in the corner thinking ..."At least they don't know that I sort my declarations alphabetically!" :)
Not my case, but heard it more then once on StackOverflow & such.
😂 Well, I mean, doing it manually surely would be a pain!
The only way I could see something like that working, if someone reeeeally wanted to, would be to set up a linter that orders alphabetically declarations for you.
Otherwise, in my opinion, it shortly becomes a waste of time.
Anyway, even if I had a linter doing that for me, I would still prefer some other approach: I really like those visual gaps that I showed in my examples, those empty lines that separate one semantic group from another. They really help me visualize things faster.
With an alphabetical ordering I guess there is no such thing as a "semantic group", I would just have a list of properties, like in the first example I showed. The only difference is that now these properties are sorted, but for my way of thinking and writing CSS, this would not be very helpful... 😕
Anyway, I guess the moral of the story is: there is really no "correct" methodology here, no silver bullet. It's really a personal choice, everyone should just find what they're more comfortable and productive with. That's what my message really is ☺️
For me, my order of sorting my css is:
position:
width:
height:
margin:
padding:
display: flex or grid
justify-content:
align-items:
gap:
-- Typography Stuff --
-- Animation and Transition --
z-index:
Because my way of thinking is in this order... How big should my div be?
Should this div be relative or absolute?
How should the inside be arranged?
What are the fonts to be used inside?
Transition and animation?
Should this div appear at the back or at the front?
I see, that's definitely another valuable approach! My point with this article is: better organizing things in some way, than having no organization at all.
What I proposed was just my way of organizing things, but if this this organization you just showed is what you feel more comfortable with, then so be it! 😉
Is it useful to use so many declarations at all? The word "Cascading" in CSS means, definitions have an order, being valid for one level and all leves below. So, there is already some kind of "semantic" order that should result in kind of a uniform appearance of all elements.
And, there are some styling rules that have nothing to do with "style". They are about the page logic. Assume, you want to show a traffic light, you would nees some CSS to make the lights red, yellow green. But this is not for styling, but has a logical meaning.
I think it is important to organize your CSS following to this categories mainly.
The code that I showed is just an example. Of course in a real-world scenario the code would not have been written like that, and I would have taken advantage of many things.
Inheritance is one of them. Of course I take advantage of that for my text-related properties, and when I feel it's the case, I could also explicitly inherit properties that don't inherit by default, in order to be as DRY as possible.
And also, maybe, I would use preprocessors such as sass, taking advantage of things such as mixins and functions, giving my code more modularity.
Also, often it is useful to create so-called utility classes: tiny classes that absolve for a very specific task, and that are then composed into a single element.
My point is: this organization-style is not some kind of silver bullet. It's just something I use to give myself a sense of organization, and it really helps me in that. Of course, it has to be combined with all those other best practices.
Why not utilize a alredy defined order like: concentric order (npmjs.com/package/stylelint-config...). Combined with stylelint it is lintable and auto fixable. The order follows the css box model.
Didn't even know "Concentric CSS" was a thing... yeah, I guess that's another valuable approach as well! At the end of the day, I think it's really just a matter of what you feel more productive working with. I think I'll stick with the approach I described just because I'm used to it and it works for me, but if "Concentric CSS" is the way you feel more productive, then so be it! 😉