CSS is unnecessary given a layout language with means of abstraction and combination

CSS, a language for specifying visual appearance on the web, is … so complex that it has never been implemented correctly; yet, successive versions specify even more complexity. At the same time, it is so underpowered that many elementary graphic designs are impossible or prohibitively difficult, and context-sensitivity (or anything computational) must be addressed externally. Most CSS lore is dedicated to describing the tangles of brittle hacks needed to circumvent incompatibilities or approximate a desired appearance.

I’ve recently been looking at various client-side development technologies, in particular Elm. As a functional programming language, Elm isn’t terribly exciting, but something I enjoy about the language is that it provides a sane combinator library for describing layout, as opposed to the pile of hacks that is HTML+CSS and explicit DOM manipulation in Javascript. Elm’s author has stated that this is not a bug, it’s a feature. Elm provides the escape hatch if you need it, but it is entirely possible to use pure Elm for layout without giving a thought to the DOM.

Update: Elm now has a rather nice story for integrating with (and building new abstractions atop!) HTML/CSS. See the elm-html library.

As a result of this bold stance, there’s been some inevitable discussions on the Elm mailing list about how to use CSS in conjunction with Elm layout and graphics. But a separate stylesheet language is generally unnecessary when using a real language for describing layout, as you can use the normal means of abstraction and combination provided by the language to factor out whatever layout or styling decisions one wishes to be able to modify in a centralized place. CSS, you’ll recall, was yet another dubious web technology that sprung up to solve a short-term need, in the void of HTML having no means of abstraction. As it became more widely used, CSS accumulated lots of features, features which might have been regular libraries if CSS or HTML had any means of abstraction or combination. Seeing a pattern here? Means of abstraction and means of combination are important, and first-order hacks are no substitute for supporting these capabilities properly. For some reason I’m reminded of the quote about C++: “an octopus made by nailing extra legs onto a dog”.

What of the arguments in favor of CSS that “designers are familiar with it”, “there’s a huge ecosystem”, “it’s the pragmatic choice” etc etc? There are a couple unspoken assumptions here that don’t hold up to scrutiny—one is that abstraction is in general not to be trusted. We can blame Spolsky for infecting our industry with that meme. A little reflection on the history of software reveals abstraction as the primary means by which humans make increasingly complex software possible and comprehensible. Hence why we’ve moved away from assembly language in favor of high-level languages. Blanket mistrust of abstraction, to the point where we should actively avoid including means of abstraction in software technology, is absurd.

The other, more serious unspoken assumption here is that designers are all idiots who can’t be bothered to learn anything new, even if it makes it vastly easier to reason about layout code and compose more complicated layouts from simpler components. I am certain that competent designers can quickly become productive using a set of layout combinators like what Elm provides. Of course there is a learning curve, but having a compositional layout library and means of abstraction pays for itself very quickly. Abstraction and compositionality always win long-term—just as high-level programming languages won out over assembly language, so too will layout combinators in a real language eventually win out over the pile of first-order hacks seen in CSS-based styling.

It’s true that in using a language like Elm for layout, one loses the ability to cut and paste random CSS found on Stack Overflow in cargo-cult fashion without understanding what it does. I consider this limitation a feature. Layout code can and should be managed using the regular tools that programmers have developed for managing complexity and factoring out duplication.