
Principles we use to write CSS for modern browsers - vuknje
https://gist.github.com/alekseykulikov/68a5d6ddae569f6d0456b0e9d603e892
======
skrebbel
A bit meta, but I need this off my chest: I love how this document starts off
saying "this is for react apps". IMO every discussion about CSS coding
standards needs to start with context.

A lot of old CSS lore came from people who build websites. I mean those fairly
uninteractive things, focus on content. Blogs, restaurants, newspapers.

Building an application that happens to use the DOM as their UI toolkit is
totally different. The whole "reuse the same classes but with different
content" thing that CSS classes were designed for becomes less important, and
"reuse pieces of _behavior_ " makes a lot more sense.

There's probably more domains or subdomains that warrant their own CSS best
practices. But I'm totally tired of a blog designer and a react app coder
fighting on HN about how the other one is doing it wrong, when really they're
just solving different problems.

~~~
sanderjd
Well said. This goes (probably double) for the similar conversations about
javascript, where lots of people question whether it should be used at all,
which is a reasonable question for _sites_ but not for _applications_.

~~~
threesixandnine
Those people probably have static content sites with lots of js on their mind
when they say that, no? Ads, tracking code, etc....

~~~
sanderjd
I think they probably do, which is why I really liked the parent comment about
how people should be clear about what they're talking about so that we stop
talking around each other all the time.

------
MatekCopatek
IMHO, naming conventions such as SUIT, BEM, OOCSS and the like are NOT a good
practice, but merely a workaround for dealing with the limitations of a global
namespace.

My preferred solution are CSS Modules[1], Vue's scoped styling[2] or something
similar.

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

[2] [https://github.com/vuejs/vue-
loader/blob/master/docs/en/feat...](https://github.com/vuejs/vue-
loader/blob/master/docs/en/features/scoped-css.md)

~~~
davidkpiano
CSS Modules is still a "naming convention," just one that is auto-generated
for you. Naming conventions in CSS are as much of a good practice as
naming/linting conventions in JS.

~~~
vinceguidry
Auto-generation is a good solution because names are the brain's interface to
the code. If the names are auto-generated, and the brain doesn't have to look
at the auto-generated names, and the abstraction doesn't leak, then you can
consider the problem solved.

~~~
Jasper_
My devtools still doesn't show me the unmangled name. The abstraction leaks.

As a practicality, I prefer the naming conventions to the CSS processing
pipeline, because it gives me a much better ability to debug and iterate.

~~~
Klathmon
With sourcemaps you can get close, but it still shows the "mangled" class name
in the HTML.

But with a dev/prod environment, you can have your cake and eat it too (for
the most part). In dev we have our classnames be in the format of
`[classname]---[file-path]---[filename]---[partial-hash]` So one of my
classnames from a current project is `.container` in the file, but shows up as
`.container---src-components-scanner----styles---1446d`. And in production
shows up as `._1533JgnvGu096C2bCAkrxT`.

------
ulkesh
Some thoughts:

\- Good CSS design needs zero !important statements. Fix your specificity or
your component architecture if you have a need to use !important.

\- DRY is a good thing, not a bad thing. Maybe straight CSS isn't quite there
yet but...

\- Why not use the tools at your disposal to aid in development (and DRY) such
as SASS/LESS?

\- Flexbox will be great once IE dies the well-earned death it deserves.

I'm very happy the author had great success with their setup. What works,
works. But I hesitate to assume that just because it works without using DRY
principles or other tooling, it means you shouldn't.

~~~
daurnimator
> \- Why not use the tools at your disposal to aid in development (and DRY)
> such as SASS/LESS?

Because there is so much tooling churn + barrier to entry. The point is that
sometimes it's better to repeat yourself than to use the tool of the month.

~~~
shabda
Both the tools mentioned above LESS/SASS have been for 5+ years. There is
churn in frontend tooling, but it is not a valid reason for not using LESS.

------
al2o3cr
".ComponentName-descendentName" nested inside ".ComponentName"?

Remember kids, the cascade is TEH B4DZORS - so always include everything you
would have gotten from it in every class name. _headdesk_

Solidly delivered on the "no DRY" premise. Maybe they should coin a new
acronym like "WET": "Write Everything Thrice"

~~~
awesomebob
CRY: Continuously Repeating Yourself

WET: Write Everything Twice

Credit: [https://roots.io/sage/docs/theme-
wrapper/#fn2](https://roots.io/sage/docs/theme-wrapper/#fn2)

:)

~~~
gr3yh47
WET is standardly 'Write Every Time'

------
andybak
A random brain dump prompted by this statement: "No DRY. It does not scale
with CSS, just focus on better components"

All programming involves resolving a conflict between two different principles
and a lot of the fiercest disagreements are between people that weight the
importance of these two things differently:

1\. Reducing repetition

2\. Reducing dependencies and side effects

The language and it's tooling/ecosystem can affect the importance of these.

The project's complexity, rate of change and lifespan is also a factor that
might push you one way or the other.

But anything that helps one of these harms the other.

Thoughts?

~~~
MatekCopatek
I wouldn't say that they are always mutually exclusive. I think there is a
variable ratio between advantages gained by 1. and disadvantages caused by 2.

In other words, at first, reducing repetition will net nearly no negative
results - you just recognise different areas that do very similar things and
write a common functionality. The most basic example would be programming
languages providing standard libraries, even though everything could be done
with regular operations. At this point, abstractions are even simpler to use
than implementing things yourself.

Problems start to arise once you hit a certain point beyond which your
abstractions become harder to use and maintain than simply writing things
multiple times. This is where you should stop abstracting/modularising things
away (assuming that the reason is purely overengineering, not _bad_
engineering).

------
davedx
> Flexbox is awesome. No need for grid framework;

Yes, great, if you can ignore all the IE users. Is that what "modern" means?

I'd love to use flexbox where I work, but it's just not feasible to give up
all the customers we would lose.

~~~
freshyill
Why not both? Global flexbox support is >96% and in the US it's >97%.

Unless you're aiming for a 1:1 pixel-perfect experience in crappy old versions
of IE, it's negligibly simple to detect IE (or lack of flexbox support), and
just use something else. You can usually get pretty close to a lot of flexbox
layouts with display: table and related properties, and also falling back to
floats for others.

In a worst case scenario, you can provide old IE with a more mobile-like
experience and just let things stack up.

~~~
spdustin
Enterprise in the US. IE9 still rules, in many cases. I actually work all over
this space, do not tell me otherwise. And now I have to maintain two
codebases?

~~~
Roboprog
Been there, done that. But you might mention to bosses/clients that MS no
longer supports/patches anything older than IE-11 on desktop versions of
Windows. They are most likely using an un-patch-able version of Explorer.

Virii, Trojans and Hacks, oh my!

[https://www.microsoft.com/en-us/WindowsForBusiness/End-of-
IE...](https://www.microsoft.com/en-us/WindowsForBusiness/End-of-IE-support)

~~~
bigger_cheese
My work "upgraded" to IE 11 late last year. The problem is so much of our
internal infrastructure was built to target IE 8 (or earlier) that when our
information services guys deployed IE 11 they forced it to run in
compatibility mode.

Now you have to go through this endless dance of Enable/Disable compatibility
mode depending on what site you are trying to visit. We have a lot of non
technical users so as soon as you ask them to delve into menu options to use
some added functionality on a site you lose them.

Even technical users hate this so most people sideload chrome. However a large
number of workstation are locked down and those people have no option but to
continue with IE.

------
EdSharkey
Plug for test-driven CSS:
[https://github.com/jamesshore/quixote](https://github.com/jamesshore/quixote)

I've experimented with it on a green field project and got promising results.
Found I could refactor my CSS with confidence.

------
bbx
I agree with the Flexbox and DRY principles, but it's weird to still rely on
arbitrary naming conventions like SUIT when CSS modules have been around for a
while now.

Naming things has always been difficult, especially in CSS where it can lead
to merging/overriding/precedence issues. _Not_ having to _think_ about what
CSS class names are either available or possibly conflicting is a benefit from
CSS modules that increases productivity by an order of magnitude I've rarely
seen in CSS, especially in large codebases.

You've got a button and want to call it "button" and style it using ".button"?
Go ahead. It will only inherit styles if you _explicitly_ say so. The global
namespace remains healthy for each component you write.

------
prashnts
Personally, I very much dislike using CSS classes unless required. I prefer
having a clean markup with classes used only where they make sense.

For a context, I somehow can't wrap my head around writing something like:

    
    
        <div class="nav nav-inverse nav-hide-xs">
    

when `<nav>` makes more sense. Sure, if you have a case with alternate
"inverse" navbar, go ahead with a class `<nav class="inverse">`.

About the flexbox, ah, well, even now they have undefined behaviour on several
elements such as a `fieldset` [1].

[1]: [http://stackoverflow.com/questions/28078681/why-cant-
fieldse...](http://stackoverflow.com/questions/28078681/why-cant-fieldset-be-
flex-containers)

~~~
talmand
These days using "nav" instead of <div class="nav"> is the preferred method by
default. The other two classes are just modifiers that may or may not be
required. There's nothing wrong with them.

Also, I see "fixed" bug reports in both Chrome and Firefox when using flex
with fieldset. To be fair, recent fixes.

------
Roboprog
FWIW, I'm using Angular (1.x) on a project at work, rather than React. One of
the things I did recently was take the CSS file used in the project ("Few
Pages App", rather than SPA, which _had_ a common .css file), and turn it into
an Angular (javascript) "directive".

I wish I had done this earlier. I have no "compile" step, it's just straight
js plus the framework. However, I now have a mechanism to use variables for
any (new) stuff with repeated settings, inserted into the rest of the text in
the "<style> ... </style>" template.

------
kowdermeister
I've developed my last 5 projects (corporate websites with many different
layouts) with SASS + Foundation 6 an no naming convention. Instead I relied on
nesting selectors.

I can behave and usually not go deeper than 4-5 levels. It's a really neat way
unambiguously tell a CSS rule where it should belong to. For example I can
create a

    
    
        section.hero-block{ /* things inside are scoped */ }
    

CSS selectors who live outside are pretty basic, utility style ones, they
exists on one level, so they can be easily overwritten by the scoped ones if
needed.

~~~
Nadya
This is how I've developed projects for the past two years. Every module is
scoped. If it needs variations but contains the same HTML structure - it gets
a modifying class (.full, .half, .side, .footer, whatever)

If it has a different HTML structure - it is a different module entirely:
`.module.v1` VS `.module.v2`

Doesn't matter if 85% of the CSS is shared between v1 and v2. If the HTML
structure is different, it is a different version of that module. If you can
run a diff checker and return 100% the same HTML structure but you need a
different coat of paint, you add a variation class. _All modules begin as a
"v1"_. This prevents it from needing to be added to the scope selector if a
"v2" is ever added. I've yet to work at such a scale where the loss in CSS
performance was a problem.

Utility and State classes live in global space. Global being defined as
anything unscoped, not "everything in CSS is global space". Since everything
is scoped - I can safely reduce selectors. Very rarely does it go more than 3
levels.

I use some level of OOCSS but don't use it for things like `.floatLeft`. If it
is a style I will want to _remove later_ , typically for responsiveness, then
I don't want a class `.floatLeft` that is really `.floatNone` at a certain
size. I would rather take `.item` and change `float: left` to `float: none`
with a media query.

------
seag64
So, I don't do any front end work in my day-to-day, so this may be a stupid
question. This article starts out with how CSS gets a lot of negativity. What
alternatives are there? Do browsers understand anything but CSS for styling?

~~~
frankwiles
There isn't an alternative really. Like Javascript, it's all there is.

~~~
seag64
So are these other tools people are talking about some different methods that
just transpile back to CSS in the end or something like that?

~~~
gr3yh47
Yep (such as LESS, SASS, SCSS, etc)

------
zephraph
I think an important thing to note here is that this individual's team is very
small. If you have a small team that closely collaborates then scaling things
which take discipline (like CSS) becomes vastly simpler.

CSS is difficult because it takes so much effort to do things the "right" way.
It requires a good set of linting and testing tools or constant vigilance to
maintain a correct, robust system.

As the codebase or team grows the difficulty of that task increases. That, to
me, is why CSS often viewed in a negative light.

~~~
talmand
I believe you could say the same for a large number of coding languages out
there.

------
surganov
Recently I got into functional CSS:

[https://github.com/chibicode/react-functional-css-
protips](https://github.com/chibicode/react-functional-css-protips)

~~~
pluma
At that point you might just go full css-in-js and embrace inline styles.

I'm not sure which is worse:

A) having twenty classes on each element, each doing only one or two things

B) having twenty classes overlapping on the same one or two things

~~~
talmand
I would say both A and B are incorrect.

------
jorblumesea
Funny how all the original markup and languages are becoming the machine code
of the web. No one writes js anymore, just compiles into js. No one writes css
anymore, just SASS -> css. Html? Nope, directives or shadow dom.

