I wrote my article on CSS, "Completely Sodding Stupid", back in August. Now it's November. This last year has gone past phenomenally quickly for me. I meant to write this follow up article about two months ago. Sorry about that!
I think the first thing to say is that if you don't want to receive a few hundred emails beginning "Completely Sodding Stupid Article"1 you should think more carefully when choosing a title.
That was intended to be linkbait - but even so it grabbed far more attention than I had anticipated. In fact it has received about 40,000 visitors since I wrote it. Here are a few pertinent links to the discussions that arose around it:
Of all the comments I think this observation is my favourite:
I love CSS. Except when I want to stab it in the eye. Which is always.- "Lukifer" on Reddit
I had expected the majority of the discussions to amount to idiots disagreeing with me on ideologically pro CSS grounds or idiots agreeing with me on ideologically anti CSS grounds. I was completely wrong. The majority of the discussions were thoughtful and nuanced. While the quality of the discussion was high, the quality of the emails2 I received was even higher. Go internet!
Cautionary Note
I don't think that "let's go back to using tables" is a viable solution. I don't use tables in my site design (check the source to this article if you don't believe me) and I don't propose them as a general solution to anyone else.
A handful of people managed to take away that interpretation from the original article, so I'll say it again just to be clear:
I do not support the use of tables as a "solution" to CSS layout problems
Just so you know where I stand. Tables are good for representing table based data. They are not good for layout in any other circumstances because they cannot easily be made accessible to users with visual impairments, and because they intrude into the semantic content of the document making re-styling of the page an intrusive manual process.
Insights
While my article title was linkbait, this was not in order to raise advert revenue. I have no advertising on this site. It was purely intended as a mechanism for getting some feedback on aspects of CSS that I found inexplicable. I think I learned a lot from the responses, so the exercise was successful.
Browser support
I consciously mixed together several flavours of whine under one complaint. While I acknowledged this in the original article, I shall reiterate it here. Some of the problems arise from browser bugs, the existence of legacy browsers, and lack of support for the full suite of CSS capabilities. If you are designing for a single modern browser platform you can disregard a lot of the points I complain about.
If you are designing for the real world of the web where old and incapable browsers still thrive, there is nothing to be done about this save wait patiently for the quality of the browsers to improve and the legacy platforms to quietly expire. With IE6 holding a 20% market share there will be people like me whining for quite a while to come.
CSS Version 3
A lot of the proposals for solutions to the problems I cited were, essentially, that I should use or wait for CSS3 features. I have a bit of a bee in my bonnet about this. Firstly, yes, CSS3 does fix some of the problems that I complain about. However, CSS3 is not a standard - it is still in development. It has been in development for ten years. This is ludicrous - ten years prior to the beginning of the standardization process for CSS3 the world wide web didn't even exist!
Because CSS3 doesn't yet exist as a standard the CSS3 attributes are not yet supported across browsers. I can use proprietary extensions to enable CSS3-like features in Firefox, Safari, and so on, but I have to assume that some of my users will be using browsers that use older features, and I have to assume that at some point those proprietary extensions will become deprecated, limiting their long-term utility.
Again I don't have a fix for this, except that perhaps we should perhaps have the CSS3 committees taken out and shot.
For some purposes (see "Curvy corners") CSS3 proprietary extensions are probably adequate because in their absence things degrade in a usable, if not aesthetically pleasing, manner. In general, however, CSS3 suggestions amount to a "nice try but I still need a
Style and Layout
This is the gut of the problem. It hadn't really occurred to me, but several respondents by email and in the discussion threads made the point:
CSS is a great styling language and a horrible layout language
It's true. If you just want to make text look different - change the font, size, margins, weight, colours, and so on, CSS simply couldn't be easier. It makes absolute sense as a styling language. It allows you to keep these issues quite independent of the semantics of the content.
On the other hand, if you want to change the layout of the content - move paragraphs around, align things next to each other, align things vertically on the page, calculate positions relative to other components on the page, and so on and so forth, then you will resort to positioning hacks3, compromise the semantic content by putting in a bunch of <div> elements that have no intrinsic meaning, or both. Or you'll get fed up with the whole thing and start whining about how table based layout was much easier. Which it was. Not better - easier.
Several commenters pointed out that dynamic layout is a problem pretty much solved in application design but horribly botched in CSS. If you look at the Java Swing API, you will see support for numerous different layout managers, each capable of laying out a page in a sane manner and reacting politely to changes in the window metrics.
I think that the layout aspects of CSS should be deprecated and moved into another standard - Cascading Layout Sheets or somesuch - but given the glacial progress on CSS3 this is not a practical solution.
CSS3 does include a table-like layout extension that shows some promise, but I'm not entirely optimistic that this will solve all our problems.
In the following link someone makes the argument of CSS layout versus CSS styling far better than me: http://news.ycombinator.com/item?id=282552. An email from Stewart Stremler made similar points.
Solutions
Here are the solutions that came up during discussion with respondents. Some of them I was aware of, some of them are simple fixes that I had no idea existed, some of them are hacky fixes that work but that I think support my point about the counter-intuitive nature of CSS. Some of them have no sensible solutions.
1. Curvy corners
No sane fix out side of CSS3.
There are the various hacks that I alluded to in the original article, using absolute positioning of bitmaps, or the use of Javascript. Then there are the CSS3 solutions that have not yet been standardized.
Some users made the point that these are not a legitimate part of the CSS specification - they felt that accommodating curvy corners was silly; why not allow for bevelled edges and other ornamentation if you allow for curved corners? Good question. The answer, I think, is that CSS should make it easy to do the things that people generally want to do. There wouldn't be so many hacks for this effect if it weren't in demand. I would certainly prefer it if CSS was powerful enough to express arbitrary decoration on page elements - but it isn't and until it is specific support for common use cases is reasonable.
To achieve curvy corners on most modern browsers (degrading to boring square corners on internet explorer) specify a border radius value for the element in question. For Mozilla and related browsers (Firefox etc) the proprietary attribute is -moz-border-radius. For WebKit and related browsers (Safari etc) -webkit-border-radius. The eventual standard attribute will (probably - that's the problem with unfinished standards) be border-radius. There are other related attributes allowing finer control, but a typical usage in my CSS files is therefore:
border-radius: 6px; -moz-border-radius: 6px; -webkit-border-radius: 6px;
Note that in the above I take a gamble and assume that the CSS3 attribute will be finalized as it currently stands and exhibit the same behaviour as the proprietary attributes. If that assumption holds true my page will one day look ok in future versions of Internet Explorer.
2. Vertical floats
Several people pointed out that floats don't really have much to do with vertical positioning, which I suppose is kind of true. So strike float from that - I just want a sane way to do vertical positioning. It doesn't seem to exist.
Classic example of where it's deficient: I want to place a piece of text in the exact center of the browser page, adjusting nicely if the user re-scales the browser.
Note that I do not want to center the top of the text in the page - it's the center of the element that should be centred. Here's one user's suggestion, which epitomizes what I hate about CSS "solutions":
top: 50%; margin-top: negative half of the inner element's height.
That fails badly to my mind because it requires you to know the size of the inner element. If I have dynamic content (and I usually do) it's impossible for me to know this in advance. Again, CSS is generally ok for people working on static content and prepared to use absolute or pixel based positioning - however I'm a web application developer however, and I almost never work with purely static content. At a bare minimum I expect text to be available in multiple languages.
As far as I know, something that can be clearly and simply stated - "center text in the page" is insanely difficult to do with CSS as it currently stands. CSS3 may address this (or it may not) but it's just ridiculous that something so basic is so hard to do.
One person actually suggested that centering the text on the page "ought" to be hard. Perhaps I failed to take into account the possibility of a sociopath element on the CSS committees?
3. Formatting for forms
This element produced some interesting feedback, but I don't think any of the solutions offered were really satisfactory.
One argument made was that forms were best handled with tables. I don't really agree with this. A form isn't a table; it just looks a bit like one. Here's where the analogy breaks down for me though - take a simple form field where the label appears above or next to the field:
Take a look at the markup for the first field:
<table> <tr><td>1. Name:</td></tr> <tr><td><input type="text" name="name" value=""/></td></tr> </table>
Now compare the markup for the second field:
<table> <tr><td>2. Name:</td><td><input type="text" name="name" value=""/></td></tr> </table>
They're quite different - and yet the semantic content is identical; it's a field with an associated label. Of course we don't have to use tables; there's a label element specifically for identifying this sort of property, but regardless of how we annotate the semantic relationship we make one of those to layouts layouts difficult to express unless we're prepared to resort to absolute positioning.
4. Floats within elements
I accept that this is just how float works, but what I don't accept is that there's no simple way to get the desired behaviour any other way.
One of the suggested solutions is "clearfix" - basically a hack that requires you to add structural markup (e.g. a <div> with a clear: both; CSS attribute) to force the element to contain its floated items. This solution is not very nice since it breaks the separation between content and styling.
Another is the use of the overflow: auto; CSS attribute to contain floats, but that then causes problems if you want to have normal content extending beyond the borders of the element, giving it scrollbars. Adding a floating caption to pre-formatted code that overflows the containing element would be an example of this scenario.
There do seem to be some hacky solutions to this problem, such as the "Easy Clearing" solution but none of them are what I would think of as intuitive - and there doesn't seem to be any clear reason for the deficiency.
We'll call that one half-solved, ok?
5. Graphical Buttons
Two solutions were commonly offered here - one of them mediocre, the other excellent.
The mediocre solution is the use of the <button> element. It looks like it ought to be what's wanted, but it has different semantics to the more commonly used <input type="submit" ... > approach making it (generally) useless.
The good solution, and one I was completely unaware of, is to use, er, CSS stylings on the input element(s). In fact you can give the input element a background-image property and even use the :hover and :active pseudo-classes to give it appropriate behaviour when you mouse-over and click it. Bad Dave for not knowing this.
There's always a fly in the ointment of course - apparently you can't use the pseudo-classes on IE6, but that seems like a relatively minor failing; you can provide Javascript where it's enabled and the failure mode is at least reasonably benign.
Particular thanks to Jimmy Tang for some of the details on this.
6. Column support
My complaint about lack of column support was not just about the difficulty of positioning aligned blocks of text adjacent to each other (ridiculously difficult to start with) but also about managing the overflow of text between blocks in the manner that we see every day from newspaper articles. The Gutenberg bible was (beautifully) typeset in this manner; actually Johannes Gutenberg seriously over-engineered the whole thing but that's another story. CSS takes us back to a point in history prior to the arrival of moveable type!
I'm going to disregard the current hacks for managing columns - none of the non-javascript options manage the flow of text between columns. Let's take a look at CSS3 instead.
The CSS3 spec allows for multi-column support in elements. I didn't acknowledge that in the original article and so far, so good. However, the implementations of this available in existing browsers shows a shocking usability flaw. I'm not sure whether this is innate to the standard or an artifact of those implementations, but for anyone planning to put dynamic content into form elements of this type they are practically unusable. I'm very worried that these are going to be locked into the standard as-is.
Text is allowed to overflow between columns, and with appropriate attributes set the browser will create and render additional columns to contain the extra text. So far so good. When the browser pane is full, however, the column elements are extended off the foot of the page. Aaargh! Look at the image to the left - this means an inordinate amount of scrolling is required as we follow the text between columns.
This is a real usability problem as anyone who has read column-formatted PDF files on a small screen will attest. The scrolling rapidly becomes tiring and annoying. The natural direction for this extension of the columns would be to the right hand side (or the right for right-to-left languages) of the pane, adding columns as necessary. There are other ways the problem could be managed (something similar to the eminently sane default behaviour when handling overflow between pages when printing these multi columns for example), but that seems to me the simplest.
I'd be interested to hear suggestions for how to bring this issue to the attention of the standards team - I assume it's not set in stone yet (if it is, why is the standard still a draft?)
7. Order Independence
The HTML markup should be independent of the layout. This means that for some elements their sequential order in the HTML shouldn't cause problems when you change the layout.
The sidebar given as an example here should certainly be associated with this section (7. Order Independence) of the document as a whole, but its specific position within this section is irrelevant. While changing the position from the right hand side to the left hand side is trivial, however, moving it from the top of the section to the bottom is a non-trivial exercise.
Another more fundamental example would be a chapter section within a book. Moving the glossary of a technical book from the front to the back is not something that the author would expect to be involved in - this would be the job of the layout artist or typesetter. However moving an entire section of content from one part of an HTML document to another requires serious mental fortitude for a CSS developer. Usually it is easier to manipulate the original content even though the change in position alters nothing about the semantics of the document.
I believe that this is another example of CSS's limitations as a layout language - while it's easy enough to make the sidebar look pretty, moving it around in the document will always cause problems. These problems are then compounded if you need to position elements relative to other elements which have themselves been moved around.
I hope that the changes in support for layout in CSS3 will start to make this sort of exercise somewhat simpler, but I have dark suspicions that it will always be problematic even in compliant browsers.
8. Widths on inline elements
The good: as innumerable people have now informed me, you can set the display: inline-block attribute on an inline element, at which point you can specify its width attribute.
The bad: Nobody offered a good explanation of why you can't set widths on inline elements in the first place. You just can't.
The ugly:
IE7 will only render an element as 'inline-block' if it would normally default to 'inline.' - Daniel FlaumD'oh! But still better than nothing.
9. Addressing text within textareas
Not really a CSS issue as such, having more to do with a limitation of HTML but this remained unaddressed. A few people pointed me towards <div> based wysiwyg Javascript editors in place of <iframe> based ones, but as far as I know it's not possible to make one from a plain old <textarea>. Sometimes the web development experience feels seriously crippled compared to rich desktop environments and that's not always to do with the limitations of the client/server and statelesss aspects of the platform.
10. A pony (file upload)
I didn't get my pony. Nobody really addressed this point. I still don't understand why the browser teams can't provide a slicker file upload experience - the web standards aren't really the constraints here; the implementations are just horrible.
Conclusions
Here's how I would summarise the status of the main gripes I originally raised:
| Gripe | Status |
|---|---|
| 1. Curvy Corners | No nice solution until CSS3 |
| 2. Vertical Floats | No nice solution (good discussion) |
| 3. Forms | No nice solution (good discussion and may be fixed in CSS3) |
| 4. Floats within Elements | No nice solution (good discussion) |
| 5. Graphical Buttons | Simple CSS solution (yay!) |
| 6. Column Support | No nice solution until CSS3 and some issues even then |
| 7. Order Independence | No nice solution |
| 8. Widths on inline elements | Nice solution |
| 9. Addressing text in textarea | No solution |
| 10. Ponies (file upload) | Not really addressed |
Given the evidence I'd say that most of the complaints I raised were reasonable points, but not all were about CSS as such. Two of them had nice solutions that I'm happy with. I also got some insight into the nature of the problems with CSS (layout versus styling) and learned more about the nice features that aren't yet standard in CSS3. Will they ever be? Who knows.
To the people who replied in the comment threads and by email: thank you very much. It was a fascinating discussion. As you may have noticed, this blog now has a comment feature enabled - further feedback is welcome there or by email to dave@paperstack.com.
Quotes
I received quite a bit of direct email and admired the thought that went into many of them. Here are some quotes that I particularly enjoyed (there were lots, these are just my favourites).
- As always the issue is not what should be possible but what is. - Adam van den Hoven
- [CSS] has always struck me as a poor implementation of a worthwhile ideal. - Stewart Stremler
- CSS is easy if you are a wiZZard and have absolutely zero design skills. - Paul Watson
Footnotes
1. It also raised my article to unexpected prominence for UK googlers using the search term "sodding" but I'm hoping the bounce rate is fairly high for them.
2. The one low-quality theme that kept re-occurring was people suggesting "obvious" fixes to CSS problems that required absolute positioning. These all seemed to come from static site designers - for what it's worth, let me reiterate: I build dynamic sites. I can rarely guarantee that the content of an element on the page will remain the same. Since I can't say how much text will be in the element, measures that require me to know the "size" of the element for positioning are completely useless to me. If you don't build dynamic websites, your insights into CSS are not likely to be helpful to those of us who do however useful they are in your personal circumstances.
3. By positioning hacks I mean absolute positioning, percentage based positioning, pixel based positioning, or anything else that will start to muck up the look of the page if the user does unexpected things to the browser pane, or uses a hand-held device, or does anything else that breaks the author's expectations. For example, a user with visual impairment elects to have a really big font and suddenly that 5em margin on the sides of the page leaves them with something like the mouse's tale from Alice.