I got into a discussion with Aaron Swartz the other day, based on his statement that “CSS is the best design I’ve seen to make web pages that look good”. I argued that such a statement was meaningless given such a small sample of designs for the same thing, and that CSS has many warts. Here are a few, along with how I would go about fixing them.

First, the box model is just more complex than it needs to be. We don’t really need padding and borders and margins as separate concepts, because they all do basically the same thing. A much cleaner model would be to pick one term, define an order – inside out or outside in – and allow specification of arbitrarily many “layers” all at once. You could also do away with the separate xxx-left and yyy-top attributes in favor of expanding the current width/type/color tuple to include sides. With appropriate defaults, the following old- and new-style definitions would have the same effect:

	padding:       3px;
	border:        1px dashed green;
	margin-left:   5px;
	border:        3px, 1px dashed green, 5px left;

This approach would make the relationship between an element and its visual presentation much clearer than it is now, without needing such arbitrary definitions as “rendered content” vs. “containing block” and such, and with no sacrifice of flexibility or precision.

The only case where the above doesn’t really work is tables. In general, CSS needs to get over its anti-table bias, and also get past the political infighting that has led to supporting two completely separate models (“separated” vs. “collapsing” and they can’t even agree on verb tense) for table formatting. More specifically, the problem with tables is that the spaces between cells belongs more to the table itself than to the cells (or rows or columns) and conflicts can arise between how the cell/row/column specifies what should go in such a space. IMO the best way to resolve that would be to have style rules carry an explicit priority value, so you can just look at the priorites instead of having to scurry back to the spec to see which takes precedence over what. Certain priority ranges could be reserved for user vs. publisher style sheets, which would also get rid of all that arbitrary !important junk.

Second, the whole notion of floats can just go away because the CSS approach barely works even for things like a simple three-column layout (and not at all for four). In addition to eliminating section 9.5 itself, that also lets us get rid of section 9.7 (“Relationships between ‘display’, ‘position’, and ‘float’”) and 9.8 (“Comparison of normal flow, floats, and absolute positioning”). Heck, practically all of sections 9 and 10 could and should be reduced to a couple of paragraphs with no loss of flexibility or precision. If there are simple, clear rules for how boxes relate to other boxes (which includes nesting), and for what formatting can be applied within a box, there’s no need at all for 90% of that verbiage.

Tables really are the appropriate metaphor for a lot of formatting, which is why so many people still use them despite all the pressure to use CSS. The only problem with tables is that HTML doesn’t account for different media and CSS does, but there are cleaner ways to “bridge that gap” than floats and their friends as they currently exist. For example, consider the following as a hypothetical layout for this site:

	#topnav {
		nesting-step:   1;
		position:       top 150px;
		border:         10px bottom;
	}
	#leftnav {
		nesting-step:   2;
		position:       left 150px;
		border:         3px, 1px dashed green;
	}
	#rightnav {
		nesting-step:   2;
		position:       right 200px;
		border:         3px, 1px dashed green;
	}
	#main {
		border:         10px left/right;
	}

It’s so simple that it hardly needs any explanation except to say that “nesting-step” defines the (ascending numerical) order in which special-purpose areas are “carved out of” the parent box (in this case the entire document). Therefore, 150 pixels are carved from the top first, then 150 and 200 pixels from the left and right from the remainder, then the borders are applied within the boxes thus defined.

Another common need is for columns within a box. Here’s a simple way to do that:

	#main {
		columns:            100px 60% 40%;
		column-separator:   1px solid black, 3px;
	}

In other words, we’ve defined three columns. The leftmost is 100 pixels wide and the other two divide the remaining space 60/40. Columns are separated by a one-pixel vertical black line plus three blank pixels on either side. Voila! In two lines instead of fifty (and without JavaScript or server-side scripting or other non-CSS crutches) a completely “fluid” three-column layout has been defined and the browser can do the obvious right thing balancing text between the columns, etc.

There are some very basic suggestions for how to clean up CSS. Sure, they could use some further tweaking to do everything that people really need CSS to do. The problem is that CSS is too hard for browser vendors to implement consistently, and too often yields results that no sane person could want or expect. That kind of flexibility – the flexibility to create pages that look like dog vomit on some or all browsers – is not a positive thing. CSS is a terrible design.. It’s a big bucket into which everyone on the standards committee threw their share of junk, resulting in a barely-comprehensible mess of internal contradictions and redundant functionality and grey areas. A simplified CSS would make it easier to produce excellent-looking web pages, and allow browsers to render those pages faster, and there would be no negatives to offset those positives. Maybe my ideas aren’t the best ones, maybe there are others that are even better, but if CSS is the best design you’ve seen then you need to get out of the W3C pig wallow more.