

Why Stylesheet Abstractions Matter - chriseppstein
http://chriseppstein.github.com/blog/2009/09/20/why-stylesheet-abstraction-matters/

======
tptacek
We just ported our tree from straight CSS to Compass and without doing
anything clever at all, it's been a huge win.

Straight off the bat, going from CSS/Blueprint to Sass/Compass got rid of ~300
lines of styling, simply because Sass is so much more expressive.

Then we went through the code and extracted all the color literals and stuck
them in a variables file. Instantly we were able to play with site colors
without search/replace drama. The stylesheets themselves also got far more
readable, since you never have to work out in your head what a particular hex
string probably meant. Little things like that remove friction from the dev
process, and are totally worth it.

Of course, once we had all the colors in one place, it became obvious that we
had, for instance, 4-5 different oranges all within 15% of each other. We kept
the variable definitions, but made them all the same base color.

We repeated the same process with font sizes.

Finally, we went through all our markup and evicted the Blueprintisms, moving
them to the stylesheets via Chris' Blueprint Compass mixins. This was more
than a "semantic vs. visual" hygiene win. Playing with column widths involved
finding where Blueprint classes were passed in or coded into markup. Now
they're right there in the CSS, where you expect them to be.

We've got tons of opportunities to reduce the stylesheets further by macro-
izing or mixin-izing, but just by transliterating our code from CSS to Compass
we got a big enough win to be happy for this dev cycle.

Can't recommend Compass highly enough. Great work, Chris.

~~~
chriseppstein
Wow, that's awesome. Many people have it in their mind that sass and compass
are more of a "new project" or "rewrite" kind of thing. Thanks for sharing
your success with an existing project as a form of refactoring. That sounds
like exactly the right way to approach it.

~~~
snprbob86
We've used the css2sass tool for a smooth transition as well! The tool is
included in the haml distribution.

------
makecheck
I think it's a good thing to have these abstractions available, and as the
article notes it's better to keep these at a high level. It's not a call to
extend the CSS specification or to add support for abstractions in browsers.

I have always found it easier to avoid bugs when parsers are dealing with
canonical forms. In other words, make the browser support the absolute minimum
syntax required to achieve every effect in CSS. Anything that's merely
"syntactic sugar" should be handled at higher levels, and then "compiled down"
into raw CSS.

This restriction not only makes it easier for browsers to agree, but it means
that you're only likely to find quirks in your higher-level _tools_ : which,
importantly, are _outside the end user's domain_. Bad tools can be replaced,
or you can adjust your flow to insert post-processing steps that fix the
output. You don't need as many "debugging tools" because you can simply
examine the generated files to tell if something was interpreted correctly
(whereas, if a browser isn't seeing things the way you think, good luck
figuring that out without extra tools).

~~~
chriseppstein
Absolutely. Sass is a CSS generator and while it might spark ideas for how a
new in-browser stylesheet syntax would work, I don't think that it ever will
be that syntax for one crucial reason: an in-browser syntax has full knowledge
of the DOM to which it is being applied -- and that really changes how you
think about things.

------
nostrademons
While I think stylesheet abstraction is a good idea, most programmers
(including the author) don't seem to use all the abstraction mechanisms that
are already available in CSS. For example, the change-all-the-colors-on-the-
page-at-once problem would go away if webmasters factored all the elements of
a given color into a single rule:

    
    
        span.fl,
        span.a,
        a.link,
        cite { color: #ef88bb; }
    
        body, div.leftnav, div.logo { background-color: #333; }
    

You're also supposed to rely on the cascade for fonts and stuff: set them once
on the body and then let all descendants inherit them.

There're some real problems when you want to set, say, the border color of one
element to the color of a bunch of others, but a lot of the CSS maintenance
problems I see (and have written ;-)) come from developers just going through
the list of elements and writing the properties for each. The cascade was
supposed to save you from this; CSS _already_ has a pretty powerful
abstraction mechanism.

~~~
chriseppstein
That code is not more maintainable. You've centralized a single color but now
you've duplicated a selector.

The single-rule output mode of Sass is an output optimization mode we plan to
add to sass for runtime performance. You should write code the way you think
about things and let your tools do the heavy lifting for you.

~~~
nostrademons
Styles change more often than selector names. If you're using semantic
selectors, they shouldn't change much at all.

This is a problem with any sort of abstraction. When you write a function in
normal code, you duplicate the function name and call signature in exchange
for centralizing the body. In Sass, you're presumably duplicating the variable
name in exchange for centralizing its definition. The same goes here, except
s/variable name/selector/.

------
chriseppstein
If you don't "get sass", please take a couple minutes to read the article --
if you've never had to live the life of a front-end engineer, you have no idea
how hard it is to do that job with the tool that is CSS. Balancing browser
support, design, and constantly changing requirements is hard. Doing it
without a form of abstraction at your disposal is lunacy.

I would also like to point out that this post is not an advertisement for
compass or even Sass. It's a rebuttal to the people who think any advancement
in stylesheet technology is unnecessary. Sass is an implementation of these
ideas and compass shows their power in action. But it really is an argument
for a new approach.

~~~
nimbupani
I agree. Sass has made my projects a lot easier to manager and more intuitive.
There is less code bloat than before.

------
daleharvey
he misses out 2 of the major disadvantages, 1\. you add a dependancy / stage
of complexity in the build stage, 2\. you lose a direct mapping from your dom
elements to your css, ie I can click inspect something in firebug and see on
what line of what css file I need to change

and to be honest since I dont find css that hard to manage those tradeoffs are
enough to put me off using one.

also worth mentioning css variables have been introduced, just waiting for ie?
now

~~~
misuba
Is there a client-side Sass-to-CSS parser? Seems totally doable, and it would
address build-complexity problems.

~~~
chriseppstein
There's this: <http://github.com/clr/sassijs/>

But I've not tried it yet and it's not provided by the Sass team so YMMV. It
probably doesn't support the most recent sass syntax.

------
yannis
From my own experience if you understand the cascade principle and specificity
well you can get away with very compact and well written CSS files. Multi-
classing is another area where developers are only now leverage to its
maximum, for example if you have a look at the way the jQueryUI CSS works, by
for example specifying the items you wish at the end of the file as additional
classes you can introduce quite a bit of additional functionality in a much
simpler way than calling functions.

For example:

    
    
        .box{define only properties that you 
               do not want to 
               change from box to box
             }
    
        .boxColors{background:#fff;
                    color: #f60}
    
        .arial13{font-family:arial;font-size:13px
    
        <div class="box boxColors arial13"></div>
    
    

This way your classes can be used as 'functions'. As a rule, define typography
and colors and opacity this way and you can keep it simple.

CSS was developed as an abstraction to HTML. Any abstraction to the CSS other
than adding pre-processors would create serious integration problems with the
DOM model and JavaScript. (See a good discussion of this at
<http://people.opera.com/howcome/2006/phd/#ch-problems> by Håkon Wium Lie the
original developer of CSS).

Any productivity pre-processors our our business and not of the spec
developers.

~~~
nostrademons
I hate CSS that uses class names as stand-ins for typographic properties. You
might as well just use font tags, because that's what you've reinvented.

Instead, I'd rather have CSS classes each represent a semantic attribute of
the element being styled. So instead of <div class = "box boxColors arial13">,
you might have <div class=tabbedPanel>. In your stylesheet, you style
tabbedPanel with the appropriate background, border, font, etc.

Also don't neglect the value of containment selectors - if you want to style
all tabbed panels a certain way, but _only_ if they're in the main results,
you can do:

    
    
        #results .tabbedPanel { ... }
    

No need for an extra CSS class on them.

~~~
yannis
I am well aware that you should try and minimize classes in the HTML.

However, on large sites where, multiple people might be publishing pages with
slight variations, it is preferable NOT to touch your CSS too often. The
multiple class method gives you some means to control it. It also adds
tremendous flexibility for libraries (see jQuery UI's method of handling
multiple classes for styling widgets).

Naming your class="tabbedPanel" has added no semantics to your contents and
there is no such thing as 'a semantic attribute' defined nowhere. It is just a
good naming convention that helps the developer and the designer. Simply there
is no semantic meaning to a <div> it is just a container.

How would you handle two tabbed panels, one that is red and one that is blue?

~~~
nostrademons
> How would you handle two tabbed panels, one that is red and one that is
> blue?

Why is one red and the other blue? Surely there's some functional difference
between them? I'd rather call them <div id=hot class=tabbedPanel> and <div
id=cold class=tabbedPanel> if that's what they're really representing.

I have nothing against multiple classes - I've written a fairly-well-used
JQuery UI Combobox plugin, and I follow the normal JQuery UI conventions for
class names there (ui-combobox, ui-combobox-item, etc.) I do have something
against replicating typographic conventions as class names - note that it's
class=ui-combobox-item, not class="displayblock height1em border1pxsolidblue
fontweightbold".

~~~
yannis
I would have done it as follows:

<div class="box hot"> and <div class="box cold">, hot is selected and cold it
has been dropped in a 'recycle' container.

I also try to minimize id's, for example I could have <li class="cold"> as
well.

I do agree with you that one should not just map all the CSS attributes into
classes. Perhaps my example was not a good one. However, three or four
additional sets of classes, has increased my own productivity, especially
during development. I keep a partial CSS file with 5, 6 generic sets. Most
large newspaper sites use this method. It all depends in what one needs to do.
In this method the style sheet is 'more abstracted', it does not know about a
box.cold. If you skinning a wordpress template, you better off to offer the
box.cold in the stylesheet, but then you must provide a second style sheet to
offer the box.hot! This method also allows a bit of presentational flexibility
for new page designs, without playing with the main CSS files or adding
another CSS file. Somewhere, along the line there is a golden line I guess.

------
leeand00
Chris's Stylesheet abstraction (Compass) has gotten me out of alot of tight
places in the past. I really like the idea.

------
vicaya
It seems that most of the benefits listed can also be achieved using any
decent template system to serve the css files.

~~~
chriseppstein
Indeed it can. My bar is a little higher than "decent" though. The design of
your site is arguably the most important piece since it's the only part that
your users see. Having a domain specific language like Sass or LessCSS makes
good sense -- you want to make your front-end engineers as productive as you
can.

------
jonny_noog
_We have the same in web design. Grids, buttons, tabs, menus, font rhythm, etc
are all considered standard elements for a website._

Tell that to a Flash developer. This is one of my pet peeves with Flash sites.
No interface standardisation.

------
altosz
I use it in most of my projects that is why I've developed the plugin for
Grails to use CSS Compass framework - Grass

------
bprater
Does anyone know if a future CSS spec will encompass these types of
abstractions?

~~~
tptacek
I hope not. If it did, the "abstractions" would ossify and we'd have to live
with their quirks and bugs for the next 10 years. I'd rather the standards
people work on defining a useful, reliable, flexible lowest-common-denominator
syntax, and the framework people work on making sure we never have to use it
directly.

~~~
chriseppstein
As one of those framework people I can tell you that CSS as it stands is not
up to that job yet. Some very basic features are needed on the CSS side, but
I'm going to reserve my thoughts on that for a future blog post when I've
thought about more thoroughly.

------
unthinkingly
I just changed 4 projects to use SASS with Compass: there is no other way now.

