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".
Whenever I'm writing CSS and I start getting to the point where I question whether or not I might as well be using inline styles, I know I'm doing something wrong and take a step back to evaluate where I went wrong.
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.
I had a similar experience recently when I was using many compose-able CSS styles. My solution was to use a preprocessor and make an aggregate style; for example:
<li class="u-paddingLarge t-important">
would become:
<li class="MyImportantItem">
with the SASS being:
.MyImportantItem {
@extend .u-paddingLarge;
@extend .t-important;
}
You can avoid writing inline styles, keep things DRY, and still have compose-able styles.
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".
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").
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:
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.
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.
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?).
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.
I don't why you guys refer to it as the "facebook way", the name you're looking for is right there in the submission title: a way to write better css. And facebook is host of one example of it.
Breaking styles into multiple css files is definitely the natural next step, a necessary one when your css files are growing past thousands of lines.
If performance (minimizing http requests) is not a big deal, then that'll be end of story. But if it unfortunately is a problem, current tools generally support combine/minimize them into a single file, but not dynamically choosing based on page requested.
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.
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.
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.
CSS sucks,period.
When people come up with an improved standard then we can discuss about writing better CSS. Today ,without CSS preprocessors, writing CSS is a nightmare. We'll write proper css when we get a proper language ( and when the box model get fixed on every browser). Until then I dont want to here about "agreeing on a standard for writing CSS". The spec should be the standard.
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/
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).
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...
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).
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.
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.
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.
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.
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.
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.
Although the context of hierarchy is useful in CSS, there isn't a need to specify the styles with the hierarchy. That increases the specificity as a side-effect, which is a bad thing for maintainability. SMACSS suggests showing the hierarchy in class names instead. For example: use .main-dialog-heading{}' instead of '.main-dialog .heading h2 {}'.
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..
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
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.
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.
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.
It is not the frameworks that are bringing about the change. http://oocss.org/ and 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.
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".