
CSS coding techniques - nachtigall
https://hacks.mozilla.org/2016/05/css-coding-techniques/
======
georgestephanis
> This is implied in the previous recommendations, but since it’s crucial I
> want to stress it: Don’t use !important in your code.

Ehhhh, sometimes `!important` is a good option. I agree that just for the
'quick fix' it's a bad idea, but it can solve other issues beautifully.

For example: If you're writing a plugin or some sort of module that will
inject a block of styled content in websites whose normal styling you have no
control over, and you need to not accidentally let the sites override your own
styling, it's a great fit.

In that situation, it's used to ensure that your block will display correctly
across thousands or millions of websites and not fall victim to some awkward
accidental local CSS rule like `#body #content #post strong {}` that some
developer thought was a clever idea at one point, but didn't realize the
implications of the insane level of specificity that is assigned. (I've seen
this happen and the support load that it causes).

Far better to have reasonable selectors targeting only your markup, with
`!important` so that sites, if they want to, can override your styling, but
they just need to be explicit about it.

Long story short, rigidly holding to rules like these in /all/ situations can
lead to far worse results for your users than taking them with a grain of salt
and making educated decisions while understanding the implications.

~~~
koolba
>> This is implied in the previous recommendations, but since it’s crucial I
want to stress it: Don’t use !important in your code.

> Ehhhh, sometimes `!important` is a good option. I agree that just for the
> 'quick fix' it's a bad idea, but it can solve other issues beautifully.

`!important` is the GOTO of CSS.

In general you're not supposed to use it, but if you do, it makes some things
much simpler.

~~~
tambourine_man
I thought of the same analogy while reading the article

~~~
treerunner
agree

------
JasonSage
This is a pretty good article about general things to do or to avoid when
writing CSS.

If you'd like to go a step further, I really recommend this[1] CSS style guide
by the folks at Trello. I try to use it on all my projects. It makes working
with CSS so much easier in my experience.

[1]
[https://gist.github.com/bobbygrace/9e961e8982f42eb91b80](https://gist.github.com/bobbygrace/9e961e8982f42eb91b80)

~~~
nallerooth
The Trello CSS Guide is awesome. I especially like the part about media
queries and.. well, everything else too. Thanks!

------
BigJono
> And using JavaScript to do the things CSS is meant for is just a terrible
> idea.

That's very strong wording, and I couldn't disagree more. I've added in-line
styles into my React workflow for several projects and couldn't be happier
with it.

To me, React is primarily a tool that lets the developer define their view in
terms of their model, separating business logic from display. Styling is a
part of that view. Class names are just an extra abstraction between the view
and the model, and offer little benefit.

~~~
robin_reala
I guess you don’t have to maintain those projects. You’re coupling the style
to the view so tightly that any updates in the future will be serious effort.

~~~
eterm
As a counter-point, the "style" is usually heavily coupled to the "view". It's
rare to see a re-style which wouldn't also require a reworking of the view
anyway.

I like the idea of purist separation of "style" and "view" but it's
unrealistic to think it needs to be a point of dogma.

There are clearly cases where you would want most your styling to be separate,
particular for client-specific branding, but there is likely "functional" css
such as css that gets date pickers etc working and those can't really be
cleanly separated from the view.

A lot of CSS isn't really "style", it's actually far more functional than
that. Try turning off CSS and see what happens to fancy date-pickers or rich
text editors or other controls, they don't degrade cleanly they just break.

~~~
robin_reala
I’m not talking about a complete rebrand, but let’s say your a/b testing
discovers that users react better when there’s 20% more whitespace between
elements. If you’ve got all your margins contained in your CSS (or better yet
a global SASS variable to control default gutter sizes) then it‘s trivial to
update and push. If you have to search through every view in your project to
see where you might have snuck in some inline styles… well, you’re just not
going to bother. Which means you’re throwing user need / conversion away.

~~~
rickhanlonii
In the react style he was talking about, you would import reusable styles so
you can still change just one variable to update the gutter size.

------
Kmaschta
We've just released Universal.css, which is a great state-of-the-art CSS
library.
[https://github.com/marmelab/universal.css](https://github.com/marmelab/universal.css)

What do you thinks, guys?

~~~
nachtigall
I'm missing a `display-none` css class, looks good otherwise!

Edit: Meant `js--on-hover-this-element-do-display-block-other-class`.
Obviously, other class would be an element with `.other-class`

~~~
Kmaschta
Great idea! I've opened an issue, feel free to open anothers for each idea.

[https://github.com/marmelab/universal.css/issues/2](https://github.com/marmelab/universal.css/issues/2)

------
spdustin
All the people piling on with "!important is evil, nuke it from orbit!" have
clearly never been tasked with branding an enterprise product like SharePoint.

~~~
gremy0
SharePoint and !important together is like a nuclear standoff of perfect evil
in balance.

~~~
spdustin
Truer words were never spoken. Have you discovered the elusive
double-!important? Or the fabled inline style with !important?

SharePoint's markup is rad. /s

------
crucio
I know not everyone is using react and webpack, but using CSS modules has made
CSS incredibly easy and removes the pitfalls that most large projects fall
into.

With CSS modules you don't have to think about whether you're being too
specific or whether your styles will have side effects, because all of your
CSS is locally scoped to just the component you're working with.

[https://github.com/css-modules/css-modules](https://github.com/css-
modules/css-modules)

~~~
pygy_
[http://j2c.py.gy](http://j2c.py.gy) provides similar avantages from JS. You
get the full CSS feature set (at-rules, pseudo-selectors) unlike with inline
styles, and local class names. No need for WebPack since it's plain JS.

Disclaimer: I wrote it :-)

------
huuu
What also helps a lot is to keep in mind that classes are for classifications
(categories) and id's for identifications (unique).

I see a lot of people using classes to create unique styles for specific
elements. This will make a mess of your stylesheet.

Also try not to think too much in subcategories (nested classes) because it
will remove flexibility from you stylesheet. For example:

    
    
      .button {}
      .button.text-center {}
    

is used to create buttons with centered text. But now you need to create
another class for other elements that need centered text. So instead this
would be more flexible:

    
    
      .button {}
      .text-center {}
    

In both cases you can use _< element class="button text-center">_.

~~~
tangue
Sadly using only classes is now considered a "Best Practice" and some
employers forbid id or are considering it as an antipattern [1] resulting in a
clusterfuck of classes in the html. But best practices in CSS changes so often
that I wouldn't be surprised if people starts to use id again in two or three
years.

[1] [https://github.com/airbnb/css](https://github.com/airbnb/css)

~~~
dexterdog
That's why just like not growing sideburns I'm not listening to this trend
either. Use classes where there may be multiple. Use ID when it's a
Highlander.

------
drinchev
These days, based on the requirements I would suggest using CSS Modules [1].

On the other hand if this would be an overkill ( small landing page ), then
basically whatever you would choose it would be okay, because rewriting the
stylesheets will take less than a day.

If the requirements doesn't allow that and you are building a huge complex UI,
then I would advise >against styling tags<. There have been at least 100 times
in my career, where I discover someone styled an `a` element, that I would
like to become a button. My approach is to use class names everywhere.

1 : [https://github.com/css-modules/css-modules](https://github.com/css-
modules/css-modules)

------
ianpurton
I'm a dev so I think I'll carry on using Bootstrap thanks.

It may be a 'bloated framework' but it works and I've spent enough time on CSS
already.

~~~
thirdsun
> and I've spent enough time on CSS already

I hope that time wasn't spent customizing Bootstrap to your liking and
requirements - you could have worked on your very own and much more
lightweight set of common CSS rules instead.

I'm sorry but how anyone, who is at least moderately experienced in web
design, could use massive CSS frameworks like Bootstrap or Foundation for
anything but quick previews and basic demo apps is beyond me.

~~~
ianpurton
It's not massive.

------
babbeloski
KISS:

\- Only use cascading for global theme styles, like type faces

\- Don't nest rules with sass or w/e, it's too hard to know what's affecting
what in a template

\- Naming conventions: Prefix every component class with the titlecased
version of the name, have one css file per component that's of the same name.
This makes it easy to know where to look for styles when you're working in a
template. e.g. styles/header.css would contain:

    
    
      - .Header-container .Header-link .Header-title--hover .Header-image

~~~
Roboprog
I guess I can agree with that, in spirit. My CSS include file has very broad
look and feel stuff. There is also a CSS block inside some pages that
customizes size / layout stuff that only applies to that page (e.g. - fieldset
and label widths based on content of various blocks).

------
blowski
For me personally, the hardest problem in CSS is the inability to automate
testing effectively. If I change this declaration to fix this bug, who knows
what's going to happen across the rest of the project? It's less likely to
break something else if I add a new class to fix this bug.

Of course, I know in the long run, that will lead to even more bugs but I
don't have an effective workflow around that.

~~~
steveax
I've used two techniques:

1) use a prefix (t-) for test selectors and do not attach any styles to them
(put them on the elements you need to target directly so the tests do not have
to know about the DOM structure)

2) use data- attributes for test selectors (again directly on the target
elements so DOM changes won't break the tests)

The second I got from this article, which is a bit Ember specific, but makes a
lot of good recommendations:

[https://dockyard.com/blog/2015/09/25/ember-best-practices-
ac...](https://dockyard.com/blog/2015/09/25/ember-best-practices-acceptance-
tests)

~~~
blowski
Actually this is a really good idea... But I was referring to to testing the
CSS itself - in the same way I text my JavaScript. I'd love to have a suite of
tests that say "this element should be 10px from the left of the page" or
something like that. I've seen tools that attempt to make this possible but
they are hard to work with.

Thanks for the suggestion on how to work with test classes anyway. Very
useful.

~~~
steveax
Probably the best way to test things like that is with a visual regression
testing tool [1][2]. In practice these are difficult to get right and tend to
produce a lot of false positives and negatives. See for instance Huxley [3]

[1]: [https://github.com/BBC-News/wraith](https://github.com/BBC-News/wraith)

[2]: [https://percy.io/](https://percy.io/)

[3]:
[https://github.com/facebookarchive/huxley](https://github.com/facebookarchive/huxley)

------
madethemcry
Great article. It should emphasize the part about !important even more.

!important should be banned. !important divides the good guys from the bad
guys. Whenever I see code with !important I instantly know that guy was lazy,
unexperienced, wrong guided - you name it. And it also makes my life hard if I
have to continue to work on that same css.

I also miss one of the most useful methods to be more granular with the
cascading. To apply a new rule, instead of using a fresh new class or to
hammer into some new style definitions with an id/!important just use the
class twice in your css. More of the same class means more important.

    
    
      .button.button.button outranks .button.button which outranks .button. 
    

See here for an example:
[http://codepen.io/gkey/pen/ONevEe](http://codepen.io/gkey/pen/ONevEe)

It's not beautiful and if you're doing css right you won't need it most of the
time. But try this before using the big bad boys like an #ID or the !important
statement.

~~~
exodust
No way. You are not considering the places where the developer doesn't have
access to all the CSS that is happening on the page. !important is a way to
override styles you don't have access to. For example, I've integrated plenty
of third party social media widgets in micro-sites, and they often have the
capacity to customise the design by _adding_ new CSS, not replacing the
untouchable CSS.

Various other scenarios similar to above is not uncommon for frontend
developers to find themselves dealing with in the workplace.

~~~
hutzlibu
Just curious: what happens if they start to use important, too?

~~~
exodust
Well of course it's not cool when that happens, and while generally most
people agree !important is to be avoided, I was responding to the idea it
should be banned completely, or the article where it says it's only good for
debugging. It's a last resort that needs to be there, and has probably saved a
lot more time than it's wasted.

------
regecks
Compounding em is total hell to keep track of in my head, even with a
stylesheet open in front of me. I'm not much on top of front-end, but why
aren't rem units just better in every way?

~~~
jaseflow
If you use em for say the bottom margin on a heading, it is going to be
relative to the font size of that heading (if specified).

Where as a rem would always be relative to the root of the document, which is
not always the desired effect when it comes to responsive typography.

~~~
manmal
I'm sure grandparent knows that. The problem with cascadingly using em is that
you cannot easily deduce the derived em-value on the nth level (e.g. header >
nav > div > a, each with their own em-based font-size; good luck reasoning
about a's em-value).

------
z3t4
You should only use classes in CSS! Leave #id's for Javascript: Wont have to
update your JavaScript when you update your CSS and vice versa.

------
jaseflow
I like most of these except the one about not using !important.

I use .flat { margin-bottom: 0 !important } to remove the default bottom
margin from certain typographical elements (ie. h1,p,ul). In this case where I
absolutely know that I mean what I say when I apply that class, it works
great.

~~~
Klathmon
In the future, try using:

    
    
        .flat.flat.flat.flat { margin-bottom: 0; }
    

It gives you the specificity to override most things, and still leaves you the
"nuclear option" of `!important` if you ever need it.

~~~
dcherman
I'd rather see !important instead of this. This rule would call for quite a
lengthy comment explaining just what in the hell the repeated .flat rules are
for, and what other rules it's attempting to pave over such that you know when
you need to add a 5th .flat as a "fix'.

------
quakenul
Overall rather mundane stuff (I kind of expected something more profound when
it addressed the "seasoned developers" in the opening paragraph). I recommend
csswizardy.com articles for more insightful thoughts/solutions to actual high
level css problems.

------
tmaly
Great post, I did not know about the view port options. The specificity I
first learned about from another poster on here that created a store locator
module for websites. He pointed me to this 3rd party javascript book written
by former engineers at Disqus.

I love using SASS to generate my CSS, and I recently started using bourbon and
neat with my Go project.

I ran into issues as I did not want to use gulp or grunt so I put together my
own way using a Makefile

[http://www.tysonmaly.com/programming/go/how-to-use-
sass/](http://www.tysonmaly.com/programming/go/how-to-use-sass/)

------
benologist
I'm partial to BEM From Yandex for my CSS -

[http://docs.emmet.io/filters/bem/](http://docs.emmet.io/filters/bem/)

~~~
romaniv
BEM is _extremely_ verbose:

    
    
      <div class="block block__element block__element--modifier"></div>
    

Is there some good reason people write _that_ instead of just the following?

    
    
      <div block="element modifier"></div>
    

Unless I'm missing something, with the second approach you get the same
specificity, higher flexibility and shorter and more readable markup.
Moreover, you end up using selectors the way they're intended to use.

~~~
RobertKerans
It's supposed to be extremely verbose, and extremely explicit, and create
single-responsibility classes as much as is possible. It makes it explicit
_what_ is being modified. It's not very nice to write, but on balance, it
works well.

------
Raphmedia
Don't use !important and don't use any id.

If you are reduced to needing to use either of them, it means that your CSS
had gotten out of hands and you are trying to apply band-aids.

If you ever _need_ to use !important or an id to fight selector specificity,
take a step back and rework all your CSS.

Source: 5 years of not using either of those as a front-end developer.

------
manmal
My main learning in this article was: Be as unspecific as possible. I think
making things as specific as possible is what coders learn early on (component
thinking etc). But since we want the whole page/component to profit from the
styles we write - this makes a lot of sense.

~~~
stupidcar
NO, NO, NO! This advice is completely and utterly __wrong __.

Component thinking is _good_ , it's CSS "best practices" that are backwards
and insane, probably because many of the people who came up with them were
designers who weren't educated in the basic principles of writing maintainable
code.

You do _not_ want to be in a situation where, when you change a particular
class, in order to fix a bug in one UI element, it potentially has side-
effects in a myriad of others, none of which you know about.

You _do_ want to be able to come into a codebase and make a fix to a
particular element, or component, in your UI, and have absolutely confidence
that you have not broken anything else.

How do you do that? By breaking down your UI into independent, encapsulated
and composable components. And the component's styles should be specific and
encapsulated in the same way as its JS code would be. The fact that CSS allows
you to create a big stew of global variables does _not_ mean that it's a good
idea to do so. Anyone who tells you otherwise is misleading you.

Follow this "be as unspecific as possible" advice and I _guarantee_ that in a
year or so, your CSS will contains thousands of low specificity rules, all
applying randomly to different bits of your DOM, with thousands more specific
classes to override the unwanted styles that are being picked up from
elsewhere.

~~~
Roboprog
Perhaps a bit more subtlety: Keep global concerns global, and local concerns
local. Coloring and font schemes (margins/padding too, I suppose) are usually
global, with variations for broad types of components. Sizes / positions of
components often end up being very specific, at least in cases where "auto"
doesn't work well for what you want.

~~~
manmal
Yes, that's the scope I was talking about, intuitively. I don't understand
grandparent's agitation, but yes, sure, local rules should be constrained to
their scope.

------
igotsideas
Having been on projects where !important was used, I'm not able to rationalize
why it's okay to use. It's a quick fix and leads to bad css. We have it in a
linter at work so nobody tries to pull a fast one :)

------
z3t4
Be careful some of these tips wont work in old browsers! Yeh, there's still
old browsers out there (mobile devices, enterprise workstations)

~~~
Bahamut
For that, there are tools like autoprefixer

------
pistoriusp
The majority of these problems have been solved for me by adopting SMACSS and
BEM.

------
xufi
Pretty cool set of tips. I didn't even know about the !important tip.

------
jackgavigan
Am I the only person who thinks that writing CSS should not count as "coding"?

I feel like the term "coding" should be reserved for writing code that will be
compiled. Anything that's not compiled (but is still Turing complete) is
"scripting". CSS, HTML, etc. is just "tagging".

~~~
ethanbond
"Hey can you tag up a gallery page this week?" \- You

"What?" \- Everyone

Not sure that this matters except to preserve some "purists'" (read:
pretentious engineers') holy lands. CSS is code. Writing code is called
coding.

I don't think it should be called _programming_ , though.

~~~
jackgavigan
_> I don't think it should be called programming, though._

So you're suggesting that the term _programming_ be used to describe writing
code that will be compiled?

~~~
ethanbond
No, I think that's awfully arbitrary. I'd say CSS doesn't really have any
computational capabilities (although that's been changing recently) so it
doesn't seem right to call it programming.

I really don't care though. Call it whatever you want as long as I can
understand what you're trying to say. "Tagging" doesn't satisfy that sole
requirement.

