

How We Could Write Better CSS - colmtuite
http://www.colmtuite.com/we-all-eat-from-the-same-bowl

======
andrenotgiant
When you get to the level of abstraction demonstrated in the Facebook Margins
example, you have so many classes for each element that you may as well go
back to inline styles.

This also enables inconsistent UI in the front-end: some of my page-headers
can have .mbl "Large bottom margins" and some could have .mbs "Small bottom
margins".

~~~
mrxd
You're right that this example is no more semantic than inline styles, but
that's the extent of the similarities.

If you want to update all the large margins across the app, you can do that in
one place. That wouldn't be possible using inline styles.

You can also enforce style guide standards. Only three margin sizes are
allowed: small, medium, large. Inline styles obviously allow for much more
variability.

~~~
masklinn
> If you want to update all the large margins across the app, you can do that
> in one place. That wouldn't be possible using inline styles.

Sure can, your pages are generated, generate the styles from config or
constants. There, I fixed it.

------
sampl
Deeply nested CSS selectors in the source (like the ones in your MixPanel
examples) are often a sign of CSS preprocessors in use. Using a tool like LESS
or Stylus, MixPanel is probably including mixins in their styles that allow
them the same modular flexibility you describe _without_ cluttering the HTML
with confusing, non-semantic classes like "mrm".

Edit: your site's visual design is awesome, btw

~~~
mcmillion
This * 1000.

Just because the output isn't 100% optimal doesn't mean the input isn't sane,
maintainable, or clean.

~~~
nobodysfool
The same could be said of facebook. MRM means Margin Right Medium (it may be
that originally it was "Margin-Right-Medium" but the compressor made the
substitution to "MRM").

------
analyst74
I don't completely agree with author's opinion.

I think the Facebook Way (tm) has its pros, but using page-level specificity
is a great way to avoid specificity hell.

To be more specific, for a site with vastly different pages, it's best to have
page or section level class that limits the scope of each css definition, so
the person making change to one section of the site will not accidentally
break other pages. Also, with little base style, there is less need to
override styles with more specificity.

For such a site, CSS like this tend to be easier to maintain:

#home-page h2 { /* home page title styles _/ }

.news-item h3 { /_ news item title _/ }

#widget-page h2 { /_ widget page title _/ }

.widget-item h3 { /_ individual widget title */ }

~~~
protonfish
I agree this is a better way to do things, but if we want to be page-specific,
why not use separate style sheets? I know we are supposed minimize the number
of http requests but is having 2 external style sheets (1 for global styles
and 1 for page-specific styles) really too many? It will prevent parsing every
style for the entire site on every page load whether the page needs it nor
not, plus decrease collisions and other maintenance problems caused by too
much CSS in one bucket.

~~~
Jormundir
I think you both have missed the point.

When you code CSS the "facebook way" :(, you don't have to worry about
bleeding effects.

Want your h1 to have a margin of 35px or whatever? You give it the class
large-margin or something. You don't have to worry about affecting other h1's,
because they have the classes specific to the way they should be styled.

When you style in the way the root comment is suggesting, you do have to worry
about bleeding styles, because selecting h1 tags in one section may also style
an additional h1 tag you didn't mean to style.

The whole point is: don't select specific elements to style, rather, create
classes of types of styles, and, when creating an element, select the classes
of styles you want the elements to have. This way you don't worry about
bleeding styles, each element has the classes representing how they are
supposed to be styled, and you will never accidently over-select elements.

~~~
Jormundir
I see I slightly missed the root commenter's point myself.

There's a trade-off of consistency across your site. I personally think it's
not a good design choice to encourage different pages to have different style
sheets.

Anyways if you want more specific styles, don't create specific selectors,
instead create more specifically named classes so you don't lose the positive
properties of the facebook way (Can we please get a better name?).

~~~
analyst74
My examples must be misleading, I'm not against creating classes.

All I'm trying to say, is that in some cases (i.e. when you only need a
particular set of styles for a single page/section), limiting the scope of
those style definition can help dealing with specificity hell / bleeding
styles, and make the application more maintainable.

Obviously, this is a trade-off, a big one if you want your site to be
consistent across pages. But there will be occasions where one or more page of
a site/app is vastly different from other pages.

~~~
Jormundir
Selecting element types rather than creating new classes is what causes
bleeding styles.

~~~
protonfish
Until you get class-name collisions or your classes are applied to elements by
other developers without you knowing. So you create more unique classes and
every element ends up having 12 classes applied to it. Classes are no solution
to bleeding styles.

------
nwienert
This article is a few years behind the latest best practice.

What this is is basically "Object Oriented CSS" that became popular years ago
and was later refuted by many in the community for it's numerous downsides,
namely in maintenance cost, code-clutter and slow performance on old browsers
and mobile.

With a preprocessor like SASS you can have OO and have semantic class names.
Take that margin example. You could define class names that add varying types
of margins. But you don't use them in HTML. You create a semantic class for
specific use cases that @extend's the margin class you need.

Now you have the best of both worlds. Less, semantic class names, with the
flexibility and consistency of the OO style.

------
ultimatedelman
while the mixpanel CSS is awful, the facebook CSS is not much better. any time
you have to use a class that is descriptive of what the element should look
like (for instance, .mas, which presumably stands for Margin All Small),
you've tightly coupled the structure to the presentation and failed at CSS.
While the article gets the idea mostly right, the counterexamples it uses are
just as bad practice.

~~~
Pxtl
The Facebook CSS is so utterly specific that they may as well use style
attributes directly.

------
cliveowen
I think there's a big need for an agreed upon standard for writing CSS.
There's a lot of beginner stuff out there, but what sorely lacks is an
idiomatic way to write proper CSS. You should write base styles and extend
them, but to what extent? How should you group the properties? Heck, how
should you structure the whole thing?

We need this. I've been thinking the same thing as the author for quite some
time, I'm glad someone has at least put the idea out there.

~~~
sriharis
I think [http://smacss.com](http://smacss.com) is what you're looking for.

~~~
cliveowen
Thank you! I never heard of this, it's exactly what I was looking for.

------
sriharis
Endorsed! I am also a SMACSS fan. And I say "Keep the specificity minimum" as
a mechanic to write more maintainable and scalable CSS. I also have another
mechanic - "Don't nest CSS", and here's my explanation for why:
[http://sriharisriraman.in/blog/2013/09/08/dont-nest-
css/](http://sriharisriraman.in/blog/2013/09/08/dont-nest-css/)

~~~
antidaily
Not to mention, nested is always slower.

------
pothibo
Nice article! One more important reason why to use class instead of tags: CSS
rules are read from right to left. That means the browser will first gather
all the h[1-6] and then it will filter the headers down with the other rules
from there.

If your CSS rules are applied to classes, it will gather the classes first
then filter it down (Resulting in a smaller set in the first place).

CSS processing will be much faster.

~~~
sriharis
That is so true. Github had a lot of performance issues in their diff pages
and they solved by using one-to-one mapping class-names and keeping the
specificity as low as possible. Here's more on that:
[https://speakerdeck.com/jonrohan/githubs-css-
performance?sli...](https://speakerdeck.com/jonrohan/githubs-css-
performance?slide=11)

------
russelluresti
While I will not argue that the mixpanel css is pretty bad (specifically the
duplication making it harder to maintain and increasing the code size), but
that margin example from FB is just as awful.

I know that there's recently been a backlash against the entire idea of the
"separation of concerns" \- but having your markup define your style margins
is a bit insane. If suddenly you wanted 10px margins instead of 5 you have to
grep your entire codebase for .m∗s (limiting the length of the string to 3
characters) and updating all those to .m∗m (or just defining both .m∗s and
.m∗m to be 10px, which is just as dumb).

But, yes, most of the points in this article are somewhat accurate if not a
bit outdated. Try not to use element selectors (and instead apply a class),
avoid code duplication, write efficient selectors, etc.

(Note: asterisk changed to low asterisk and I hate markdown or whatever other
text styling syntax HN is using).

~~~
Jormundir
Isn't what you're describing the easy way to change a site?

~~~
russelluresti
Normally, sites will have more views than they have CSS objects. So if you're
doing OOCSS it would be easier to just update all the objects (css files)
instead of updating all the views.

------
al2o3cr
The way FB implements margins is terrible, there's nothing "semantic" about it
- it's basically a single level of abstraction above whacking style tags onto
elements directly.

------
paultannenbaum
While I agree with the general idea behind the article (object orient your
css), I think the second demonstration involving margins is an example of
OOCSS gone wrong.

If you are injecting your markup elements with classes like "mbm mts mrl" (or
padding, or anything else that is essentially just a css property), this is
not much different than just inlining your styles. If you want this level of
reusability in your css, use sass and create these as placeholders. From there
give your dom element a some kind of class(es) that can extend several of
these placeholder values.

Ian Storm had a very well written article that hits on this more:
[http://ianstormtaylor.com/oocss-plus-sass-is-the-best-way-
to...](http://ianstormtaylor.com/oocss-plus-sass-is-the-best-way-to-css/)

------
chrischen
It could be that Mixpanel is using something like LESS and nesting stuff for
organization.

------
specialist
CSS did not, could not, solve the problem of disorganized, inefficient
document production, typography, layout, style management, etc.

Meaning, the Mixpanel abuse of styles is an old problem.

What CSS has over most all DTP and word processing apps is that CSS is
declarative and explicit and discoverable. With CSS, styling is source code,
and can be managed as such.

Or not, like Mixpanel apparently has done.

------
bichiliad
I'm a bit confused. I'm not a CSS expert by any means, but aren't h tags
supposed to represent hierarchy, and by styling them differently in different
places (apart from, say, colors or something) largely breaking the information
hierarchy? It was my understanding that well-styled pages set up headings
properly so that styling one heading different ways didn't need to happen.

~~~
stan_rogers
Yes and no. In HTML 5, the hierarchy can be much more local/contextualized
than in previous versions, so an h2 in an article can be at quite a different
level than an h2 in an aside or at the page level. While it _is_ possible to
represent that hierarchy in CSS relative to the local context consistently
across the entire page, it's not always desirable. On the other hand,
arbitrary styling of headings does throw the baby out with the bath water;
there should be a consistent and obvious visual hierarchy (corresponding with
the semantic hierarchy) within each of the context types.

------
fournm
I don't know, after dealing with hundreds of jsps and javascript files adding
margins in all variety of ways when they should be a consistent size (that of
course, has changed over time and not been changed everywhere) in an
enterprise codebase I'll take the Facebook approach for margins any day over
just directly modifying style properties..

------
cespare
Was that Mixpanel css written by hand? Maybe it's just slightly inefficient
css generated by sass/less/stylus.

------
wyck
This post is a little over the top, the examples are both legible and work,
there is no need to get dramatic over CSS.

------
ryanSrich
I find that following a prefix method works quite well for organizing a lot
CSS. For example (using sass):

    
    
        .home-header-h1{
            font-size: 20pt;
            padding: 0px;
            margin: 0px;
            line-height: 1.3;
        }
        .home-header-h1-blue{
            @extend .home-header-h1;
            color: blue;
        }
        .home-header-h1-green{
            @extend .home-header-h1;
            color: green;
        }
    

This helps keep classes out of your HTML and avoids large amounts of nested
CSS. Here's the compiled source:

    
    
        .home-header-h1, .home-header-h1-blue, .home-header-h1-green {
              font-size: 20pt;
              padding: 0px;
              margin: 0px;
              line-height: 1.3; }
    
        .home-header-h1-blue {
              color: blue; }
    
        .home-header-h1-green {
              color: green; }

~~~
tommmmmm
But with classes with "green" and "blue" in the names, you're still mixing
meaning and presentation and hurting maintainability. See:
[http://thecodelesscode.com/case/95](http://thecodelesscode.com/case/95)

------
colmtuite
OP here.

Thanks for the feedback. A lot of people seem to be getting hung up on the
sass thing. I'm all for sass, I don't think using 15 CSS classes for margins
is the best way to handle this. I just wanted to use a watered down
illustration for those who don't yet understand sass. Ideally, this should al
be abstracted into variables/mixins/extends.

My main point though, is that I'd like to see us working together to decide
what the best approach is, then apply that across the board. I don't see any
reason for us to continue doing things slightly differently.

Whether you use CSS, SASS, LESS or any other preprocessor, we should be
writing reusable CSS. At the moment, that is not happening across the web.

~~~
ianstormtaylor
Extremely confused by the fact that there's no article navigation on your
site. I just wanted to read more...

~~~
colmtuite
Yeah, sorry mate. I just hacked it together. My CSS is horrendous too :)

I've two other articles: [http://www.colmtuite.com/three-reasons-why-
wireframing-tools...](http://www.colmtuite.com/three-reasons-why-wireframing-
tools-suck) [http://www.colmtuite.com/a-more-flexible-development-
framewo...](http://www.colmtuite.com/a-more-flexible-development-framework)

------
habosa
The problem with the abstractions of Facebook is that you then need to always
remember the "rules" of the website you're working on. If you're a Facebook
software engineer adding a section to some docs somewhere, you have to thing
"do we use .mbm or .mbl for our page headers? Damn, I'll check some other
source".

The ideal CSS, in my opinion, is just the opposite. The developer writes Plain
Old HTML and includes a stylesheet, and the new page looks instantly
consistent with the rest of the website. That's how you enable anyone to work
on the project. If a new UI is needed, the designers will change the css and
instantly all pages will look good.

------
masklinn
> What if you want a h4 to look the same as a h3? What if you have two h3 tags
> that you want to style differently?

Now you add customization classes to these special cases instead of shoving
them every-fucking-where.

------
pan69
In my opinion CSS is very object oriented and the cascading nature of it is
very much like inheritance. The problem is that a lot of CSS folk don't come
from a programming background, let alone an object oriented programming
background so "thinking in objects" isn't something they've learned.

A good place to start doing well structured CSS is to separate the layout from
the style. Doing this will give you a much better grip of your CSS and makes
for easier future changes and adjustments.

------
SolarUpNote
The author's wish is coming true. CSS techniques are already becoming unified
through frameworks like Bootstrap and Foundation.

~~~
sriharis
It is not the frameworks that are bringing about the change.
[http://oocss.org/](http://oocss.org/) and
[http://smacss.com](http://smacss.com) are bringing about this change.
Bootstrap's CSS techniques are written with a heavy bias on OOCSS, and by
doing that it is setting a good example. I'll give you that.

------
gprasanth
I recently started working on UI development. Some useful stuff I found:

    
    
      1. LESS - http://lesscss.org/
      2. LESS Elements - http://lesselements.com/
      3. Pure CSS - http://purecss.io/ [cool stuff, but not LESS.]

