Tuesday, February 9, 2010

Guest post: Jonathan Slenders on CSS

In a previous post I wrote my idea's on how I would expect CSS to work. Jonathan is much more knowledgeable on the subject and wrote me a very interesting and insightful response. Since it was too long for the comments section, we decided to post it here as a guest post.


To begin with, use { display: inline; } instead of { float: left; } for the horizontal menu.


I understand your argument that a designer should be able to write his style sheet independent from the HTML to which it eventually will be applied. Working this way, would however require a third mark-up language to define the matches between the HTML elements and the style. But because a designer usually wants to see his changes in the CSS directly reflected in the resulting page in the browser; it causes that he too will need to maintain that third file. Too much overhead, in my opinion.

CSS should be applied directly to the HTML, and the designer should have knowledge of the HTML structure. I'd say, if the structure of HTML documents didn't change as often as they do in reality; it wouldn't be bad to write the structure conventions in an XML schema (or DTD-like format).

You say "I think the programmer should not be aware of the CSS class structure that the designer will use". It's weird, because it's actually the person who writes the HTML, who is responsable for choosing appropriate class names.
In my opinion, the most important guideline here is to use semantic class names.
Never write
<div class="italic"> text</div>

This requires not only a superfluous CSS rule: .italic{font-style:italic;}, but also moves styling back to the original HTML like it was years ago. Even, <i>text</i> or
<div font-style="italic">
text</div>
would be better, because they tell the same, but don't depend on a redundant CSS rule. There is a reason why the text has to be italic, maybe because it has to be emphasized or because it's a news title, use that as a classname.
<div class="newstitle">
or </div>
<div class="emphasize">
are much better. (Though, I would replace the latter with <em>text</em>, the HTML element reserved for emphasized text.) In CSS we can then write  .newstitle{font-style:italic;}.</div>


You came up with "inherit: .horizontal-menu;" to avoid redundancy. It can already be avoided, and the recommended way to to so is by using a comma-separated list of selectors like:

p.class1,
p.class2,
p.class3 { color: blue; font-size: 120%; }

This avoids declaring three times the same for each element. Unfortunately, this syntax forces the design declaration of class1, class2 and class3 to be in the same place. This could become hard to maintain, in larger CSS files. For instance, I usually group all the styling for news items together, the styling for blog entries together, etc... But suppose that a small part of a news items needs to have the same styling as a small part of the blog, there's no way to keep on that CSS structure.
Therefore, I defenitely see the advantage of your "inherit: .horizontal-menu". However, this syntax could result in obiguous declarations without proper priority rules. The current priority order is already complicated (inline CSS has priority over document level CSS, which has prority over external included CSS. The order of the rules is also of importance, and finally the "!important" declaration gets priority over everything. More specific matches like "body p" could also ofter get priority over a simple "p".) I guess that adding inheritance your way would even more layout declarations to be combined: those of all the parent nodes (e.g. in case of color:inherit), the inline declarations, document CSS, external CSS, all the inherited CSS declarations. I would design CSS like this:

%horizontal-menu { display: inline; }
.my-main-menu { inherit: %horizontal-menu; }

Similar to yours, except %horizontal-menu is never applied directly to any HTML element, it shouldn't match any class name, and is used like a preprocessor to the interpreter.

There are probably enough discussions about what's wrong with CSS, it shouldn't have been flat and CSS selectors should've been replaced with XPath. But this is the way HTML and CSS work are historically grown. The first designs were pure HTML. Positioning was always done with tables. Colors, font-styles and other styling was done by adding styling tags to the HTML. (e.g.
<div color="red" font="Arial">
text</div>
) It feels to me like CSS was designed to avoid repeating this layout tags on every single HTML element, but it didn't ever intend to totally separate the design from the data.
It happens too often that I need to rewrite my HTML to get a specific design. For instance, if I want to create a nice border around the site by using 8 background-images (one for each corner, one repeated for each side), I always end up nesting eight divs like
<div class="container1">
<div class="container2">
... </div>
</div>
and use one
<div>
for each background image.

Finally, a perfect website should be like:
html = data
css = design
javascript = behavior

and classnames are used to glue these together. But because of the limitations of CSS, desigers have to adjust the HTML to get their CSS working.

No comments:

Post a Comment