Why CSS needs to borrow from programming languages
The job of CSS is to provide control over how the content of a document is displayed. Anything that falls under the remit of ‘controlling the display of content’ should fall under the abilities of CSS. Yet CSS lacks capabilities to allow truly flexible design, requiring layer upon layer of ‘tricks’ to accomplish certain objectives, requiring content to be structured ‘just so’ to achieve a display objective, or in the case of some designs proving instead to be completely incapable. Part of the trouble with CSS is the perception that it should be ’simple’, as though visual design and layout is a skill-set roughly equivalent to joining-the-dots and colouring in with a crayon. Yes, the syntax should be simple, but the capabilities of CSS should not. We as a community need to decide what CSS should be able to do, and petition the engineers to make it happen. Which itself would seem to require altering preconceptions of what ‘display’ and ‘design’ means on the web. A lot of people seem to be under a misconception that CSS should not have any ability to perform calculations, use variables, or perform logic tasks. That to do so would make it a programming language, and that CSS should not be a programming language (presumably because they feel a programming language is too complicated). But CSS most certainly should have these things, and without them it is destined to forever be a cludge, requiring cludges to wrangle the visual results we want.
Visual design is fundamentally about relationships between elements. For all of the artistic flourishes and creativity, it’s about relationships. ‘That yellow’ only grabs your attention because of its contrasting relationship with ‘that blue’. ‘This heading’ only works as a heading because of it’s exaggerated relationship to the size of the body text. And layout is perhaps the most fundamental (and most mathematical) area where relationships count for everything. There’s always a mathematical basis for how parts of the page appear in relation to other parts. That’s why good designers bang on about ‘the grid’ so often. That’s why good designers obsess over getting the right font sizes, the right line-height, the right column widths, the right size of thumbnail, the right number of thumbnails or panels on a row, etc. All of these things are about relationships of proportion. And CSS has no clue about relationships of proportion. CSS has no clue about relationships, period. And that’s why CSS as it stands right now, is not good enough. That’s why CSS without variables (true variables), without basic logic, without maths, can never be as flexible as we need it to be.
CSS’s positioning is a cludge. It’s a cludge because you can only position relative to the last positioned parent container. Well, that limitation in itself dictates that all positioning relies upon how the content is structured. And that means the presentation and the content are not truly separable. I understand why this is the case, it’s because the cascade works on the mark-up level - the cascade goes top-down but can’t traverse nodes. But that doesn’t change the fact that the problem still exists. Fundamentally, CSS should be able to traverse the DOM freely. We should be able to position any element relative to any other element. That’s the only way to achieve true separation of presentation from content.
CSS is ignorant of anything outside the cascade. CSS has no clue about any property or attribute of any element other than a parent element, from which it can inherit. So, if you have a three column layout where the two side columns are stylistically duplicates of each other, you have to specify everything twice. Because the two side columns are not aware of each other. And should you want them to both be the same height your choices involve faux columns, fixed heights, or some incredible hackery. Because you can’t tell CSS to make the height of the columns identical - because they don’t know about each other. CSS should be able to inspect the attributes on any element and apply those attributes back to the reference object. I should be able to write a rule for one div that tells it to look at another div and apply the same width, height, background colour, font face, and anything else I like. But I can’t, because CSS is ignorant of anything outside of the cascade.
CSS gives imperfect options for layout. Take the example of equidistant objects, have a look at what’s required to achieve this simple visual effect. Something as fundamental as this should not be so hard to achieve. And it wouldn’t be if CSS had basic math calculations combined with an awareness of the dimensions of boxes other than parents.
While I’m picking fault with CSS, let me say that CSS3 Variables are not variables. A variable is by definition variable. It’s something a program takes and maps a value to, the value of which can change during parsing. CSS variables are in fact constants. You define them and they don’t change. That’s not a biggie, constants are better than no constants, but the misnaming rankles me and I just had to get that out of my system.
Looking through the CSS3 specifications, it’s a welcome step forward but it feels like shuffling along in an old mindset when we should be leaping for new solutions. Many of the new modules merely addressing specific issues on what I feel is the wrong level. Parts of CSS are becoming rather like a framework, in that they provide pre-build blanket solutions to specific issues, but in so doing don’t allow a great degree of control. Take the ‘Advanced Layout module’. It’s a template system that works by having you define the template grid (as ASCII art, unbelievably) in the CSS and then defining content into the slots. Well that’s great if your website is templateable and you are happy to have the slots always in that layout. But it’s a fixed and limited solution to a more fundamental problem. Instead of compartmentalising chunks of mark-up via div IDs, to later be slotted into visual locations that you must first pre-define (basically cutting up your HTML into chunks so you can whack it into a ‘display table’) - we should be able to put any element in any place on the fly.
CSS has stagnated for years, and my worry is that the mindset of the people developing it is seemingly in the wrong place. CSS should be delivering low level tools with which we as designers can build high level solutions. It isn’t doing that, it’s providing high level solutions and foregoing giving us useful tools that we can adapt on our own. As such, there will always be designs that simply don’t work well enough, or that require hacks, in CSS.