CSS: Our best practices are killing us
slideshare.net
slideshare.net
I attended the talk and the workshop. What is interesting is that it genuinely challenges. Some CSS designers who I really respect did not 'buy in' to her theory even after spending a day with her. However, as a programmer, who has since used the OOCSS in a context 'for real' I found that it does live up to its promise in practice (unlike the CSS 'semantic html/best practice' story, which sounds great in theory but so often becomes spaghetti in practice)
So, let's say you (or your team) is tasked with 'add a new calendar widget to the right column'. What you build, obviously spans across quite a few different places you're going to need a bunch of code and db access in the back end, some sort of template for layout of your html, some js, probably, and some css changes to make it all happen. You can do the code layer by refactoring some of the existing methods and keeping things 'elegant' per the original design.
For the HTML, its almost certainly going to be an additive process, but that's OK because its a good way to know you are not messing with existing functionality, and hey, this is a new thing we're displaying here, so that's OK.
For the css, the 'elegant' way to do it, is to refactor the existing classes. For instance maybe you realise the calendar is kinda a mix of the style for that upcoming events widget, and the new calendar look, maybe you refactor out what is common into a '.narrow_widget' class and just define the bit that is particular to the calendar in the '.calendar_widget' class. But unfortunately, in practice, one little change to CSS can affect things just about anywhere in the site, and it might all come acropper on any of a large number of browsers in a large number of contexts and pages..
With no automated tests, what is a developer to do? Understand the elegantly designed stylesheet and carefully refactor it, or just go for the additive approach? Almost certainly they add a bunch of css rules at the bottom of 'page_styles.csss' with a bit more specificity than before, as pages get built and features added.. these rules gain ever more and more specificity...
As nicely put by mokkos below, this is basically a recipe for 'developers getting into a firebug-hack mentality leading to overwrites by specificity until it gets too big and messy to maintain'. And I dont think you can really blame them.
So, instead of asking the developers to do the impossible, the solution offered, is, basically 'developers don't write CSS' but put some of the display logic into the HTML. You don't require that every new feature has to involve 'css guru to add some 'special' CSS for this particular widget or ask the developer to do CSS, the developer can do 'layout' control in html and get the job done, by relying on a toolkit of battle tested HTML/CSS patterns that are supported by the included oocss.css file.
This means violating the sacred principle of 'semantic html' - because to achieve this you have to put some of the presentation logic into the HTML.
The 'semantic html' way to do it would be to write the minimal html to represent what the thing you are saying is - ie its a list of dates - so use ul, li with p tags for the events, and then add a class like 'calendar_chooser' around the lot and then carefully tweak the CSS to get it to 'look right'.
The OOCSS way is you have certain basic widgets - not functional level widgets - but really fine grained, low level display widgets (eg 'a box with something on left and some sort of text area on the right') defined in the CSS and as a developer you know that if you add a <div class="media_box"> around each of the date boxes inside your calendar, you can be sure the little label text for each event, showing what the event is (if any) will appear on the right of the date (or something like that).
That sounds terrible, because the html, is going to be a whole lot more wordy - you need to specify in your html essentially how you want things to look - and it violates the principle of semantic html. It would be more 'elegant' to just say that for an <li> within a .calendar_widget the date goes on left and the event text on right. But this is a much more practical solution for the real world.
As a developer you are not writing CSS, just adding divs and giving them classes. You might tweak the layout with margins but there are common css classes to for things like 'medium margin on right' that mean that margins can be made consistent across the site, etc.
Because the OOCSS library is supposedly well designed you can be confident that it will work OK for any browser at any width, and for device or whatever. So its a bit like a return to dreaded tables, in that the developer writes HTML, gets things to look how they want and they are done. (I imagine that correspondingly OOCSS would have to suffer from similar problems of not being able to reflow content for a completely different device or context, but in practice, just how far do we need to go with this - i mean you want to lose a column from right for mobile and move nav to the top or whatever, but I've never heard of a need to, for instance, completely redesign the look of things within an element like a calendar widget to make it look right on a mobile device).
Bottom line you think you'll end up more html, but less CSS. But, in practice it appears that (especially across large sites like facebook) you end up with considerably reduced page size in both HTML and CSS overall.. at least that's what Ms Sullivan's stats appear to say.
Something like that. So kinda like moving back to tables, just not all the way.
a) back-end developer who provides the controller, model and a shell view (this could be anything from a basic HTML structure through to raw JSON)
b) front-end developer who has responsibility for building sane markup and clean CSS. It’s in their best interests to keep the styles maintainable: a little extra time writing markup that integrates into the existing styles and refactoring existing CSS to cope with the new modules is worth it in the long run.
Even if you are not - dont they accomplish the same thing ?
I apologize to others for the lack of context that the slide by itself gives. I got the summary of this talk from a co-worker who actually went, so I had the context in back of my mind. The slidedeck naming is still too sensationalist though for what it's actually about: over time, css gets degraded because developers get into a firebug-hack mentality leading to overwrites by specificity until it gets too big and messy to maintain. I'm still not too clear what she's proposing as a solution to this though; she does give an example of her success at facebook, but that example is a one-time fix, not necessarily a practice that stands on its own over time.
So, I'm not a web designer. I've used CSS before, but just in very small amounts to get basic "here I am" pages up. I'm a systems programmer. That means I spend my days in languages like C, C++ and Python for scripting. I sometimes drop down to assembly. It sounds like she's describing basic good programming practices.
Although the slides do mention sass an lesscss at the last side, I think 'stylus' is a much better css language.
http://learnboost.github.com/stylus
IT has powerful abstraction facilities in the form of functions and mixins.
Here's an example of how powerful it can be:
vendor(prop, args)
-webkit-{prop} args
-moz-{prop} args
{prop} args
border-radius()
vendor('border-radius', arguments)
Having this abstraction, we can: button
border-radius 1px 2px / 3px 4px
And the output will be: button {
-webkit-border-radius: 1px 2px / 3px 4px;
-moz-border-radius: 1px 2px / 3px 4px;
border-radius: 1px 2px / 3px 4px;
}At what point do we decide that it's not that "you're doing it wrong", but that there were actually some design choices that, in retrospect, maybe weren't such a good idea? I'd say that when we have other languages that compile into the language just to overcome these issues (CoffeeScript,Less,SASS,etc.), we've about reached that point.
Pretty much all of it. I remember being a bit surprised when they first released CSS at just how impotent it was. Over a decade later, I now realize my younger self would have gotten himself stuck in a morass of Turing completeness, but CSS goes too far the other direction.
Decoupling styles (which may contain several rules) from matchers, then allowing a match to apply multiple styles, and permitting simple variables (which I would be OK with restricting to simply "either a single variable or a single string" and not permitting concatenation or anything complicated) would have not significantly increased the complexity, avoids the Turing Tarpit [1], and would have been powerful enough that while the other languages would still have inevitably have emerged eventually they wouldn't have been necessary.
HTML had enough pragmatism in it from day one to survive being academicked. CSS is a classic example of how a beautiful theory can back you into a corner and everyone's too busy chanting the beautiful theory's mantra to notice they're doing it in a terrible way.
("You Must Decouple Content From Presentation." "That's a great idea, but don't you think that we should have something like a variable that represents a color?" "You Question The Value Of Decoupling Content From Presentation." "No, it's just that anybody with a couple of years of experience programming knows that you shouldn't hard-code constants into your files, let alone do it fifty times in a single file." "This Is Declaration, Not Code." "There's no difference; spend some time with Lisp." "You Will Burn For Doubting The Decoupling Of Content From Presentation, Heretic. A Thousand Curses On Your Websites." I've had this conversation a few times, though mercifully it has been a long time now.)
(Oh, and if you want to blow someone's mind, ask them why it's so important to decouple content from presentation. I'm sure some people here can at least articulate a reason but in general people can't, it's just a mantra. Then the mantra answer became "Semantic Web", but then try to get a definition of Semantic Web out of them... and if you get that far, ask where the semantics come from. There's been a staggering amount of what is nearly religion surrounding CSS and it shows in the engineering. Oh, and don't suggest that as long as your content is stored cleanly somewhere, it's OK to apply styles in another layer on the server... if it's not CSS, it's not Semantic and it's not Decoupled. Regardless of the actual architecture behind it.)
I click on the link, I get a slide-deck. No text, no audio, just a bunch of slides with various numbers on them.
Am I missing something? Is this something where a bunch of people saw the presentation live and are now upvoting it here? If so, is there a video link to the live presentation?
Posted about ten minutes before you.
It would be better as a web page, but the content is still worthwhile.
I think the approach she takes to solve the problem is wrong though. HTML and CSS like her OOCSS approach promotes is just nasty.
<div class="unit size1of3">
<b class="top"><b class="tl"></b><b class="tr"></b></b>
How is coding the layout into the HTML any different from the table based layouts we were doing ten years ago? This is going back to tying your styling directly to your HTML.Bringing mixins into CSS would solve this in a much nicer way. Define your fonts and columns in a couple of reusable mixins, and then define your site-specific content mixing and matching your reusable components.
How is coding the layout into the HTML any different from
the table based layouts we were doing ten years ago?
It is not. Three things irritate me when talking of CSS: reset stylesheets, grid frameworks and oocss.Luckily SASS solves or alleviates most of the problems they are supposed to solve.
If you're familiar with the CSS precedence rule, these slides might read like blog post; they did for me.
Strangely, I rarely see the precedence rule brought up in CSS documentation or tutorials. Not until I read "The Ultimate CSS Reference", by Tommy Olsson & Paul O'Brien. I highly recommend this book.
"Coding by Firebug" as it's called in the slides, probably refers to what I used to do before reading the above-mentioned book: tweak styles, wonder why they weren't taking effect, then add classes or IDs to the markup until something sticked. This is the "increasing specificity" also noted in the slides.
Once I understood the CSS rule of specificity - inline, id, class, element - I stopped polluting my markup and CSS.
Nowadays, I generate CSS with SASS partials (templates within a Ruby on Rails app), compiled together by Compass. Each partial starts with an ID at the top, with other ids, classes, or elements nested underneath. These are compiled into CSS - and I'm sure at the CSS level there is TONS of duplication - but this doesn't worry me one bit; my source code is DRY.
I suspect this is what Facebook and the other sites mentioned in the first few slides do too, so the rule duplication is probably not such a code smell as one might think.
I'm not entirely sure what she's suggesting since I'm reading the slides without any context, but it seems, given the thing about cutting down css file size for Facebook, the method she's suggesting reduces duplication in the actual css file.
How about showing us how to actually solve the first problem?
For anyone wanting to know more about this presentation, check out her Object Oriented CSS: https://github.com/stubbornella/oocss
- don't add any extra elements
- don't add classes
- use descendent selectors exclusively
the second two i've never heard in my life, and i'm quite sure the first is not a myth.
in that example, classitis is when you give a class "item" to every li element, the using .item to style it while the alternate way to do it is using the descendent selector (.parentcontainer li). Nicole Sullivan is saying this can lead to specificity war over time.
Avoiding non-semantic elements and non-semantic classes, however, restricts you to using descendant selectors (and multiple declarations), which, as she points out, creates another maintenance issue in the form inheritance conflict resolution (specificity).
more info: http://reference.sitepoint.com/css/collapsingmargins
This is not true of padding (unless you count a bug in IE8 where percentage-based padding-bottom collapses on the margin-bottom)
To visualize it, http://hicksdesign.co.uk/boxmodel/ is probably the most oft-cited example - certainly the one I find most helpful.
In that case, use margin.
When you have complex pages, with several nesting levels, this can save much, much time.
Now you've got comments saying in correct things, and you risk all sorts of confusion.
The same rule applies to commenting methods in code really, you don't comment what the code does exactly - just what the intention of the code is.
If you want something accessible with a "modern" JavaScript-based web application, you're almost bound to rewrite most parts of the interface for a pure HTML version, if at all possible and/or desirable. Quite often less effort than jumping through hoops to have something that degrades gracefully.
Now I think this will only get worse. At one point in time, it might be better to regard HTML as the Gopher of its time and consider a next step. Probably won't ever happen, as the sheer ginormous size of the "legacy" web makes any endeavors in this direction almost futile.
Does anybody remember PostScript-based GUIs? We're throwing a lot of barely-connected ideas and syntaxes into a browser to emulate NeWS/DPS -- poorly.
http://www.stubbornella.org/content/2010/07/01/top-5-mistake...
When I start a project, if I'm working from scratch I usually rewrite a lot of the css every day, just to achieve the look I'm going for. Once I standardize some things like how text flows, some layouts, and forms, it's time to develop a nice list of css classes you use frequently and tinker with them as needed. Endlessly rewriting css gets you nowhere.