I just read this article about CSS, essentially aiming to define some techniques to enhance maintainability. I appreciate the author’s attempt to bring an engineer’s eye to the discipline of document styling, and it’s a conversation that certainly needs more contributors, but I feel this article simply furthers the current state of confusion and resulting apathy in the community.
Based on the innacurate assessment that HTML has value without CSS (ever use Google Docs without CSS?) whereas CSS cannot exist without HTML (isn’t that what all those wildly popular CSS frameworks are?), the author argues that separating style from the intended document context is good architecture. Doing this results in an explosion of generic utility declaration blocks, with little rhyme or reason. Are these blocks the product of refactoring, or does a design architect/dictator craft them? How fine- or coarse-grained should they be? How do you guard against all the normal baggage of non-semantic naming and global utility code? How do you prevent their direct use from HTML documents? How do you mitigate or control repetition and mixin explosion? How are they managed in source artifacts? Without context, the code has little focus. There is no disciplinary framework to prevent it from becoming a massive ball of spaghetti.
It’s funny that the author even attempted to make this point while criticizing non-semantic CSS framework naming at the same time. Simply put, abstraction is not an end. Separating style into document agnostic utilities and document-aware glue is over-engineering that reminds me of EAV modeling. But on this premise, the author advocates using non-parameterized mixins as an abstraction mechanism to make it easier to re-use declaration blocks. I fail to see how this is any more maintainable than using selector groups. In fact, we only end up with repetitive CSS that takes longer to process. (The author would do better to use the ‘extends’ feature of Sass or Stylus to effect this misguided approach.)
It’s the culture, stupid
Although the author goes on to touch on cascade management, the focus of the article is this non-parameterized mixin-centric architecture. The root problem with this is the false premise that declaration blocks are a common or ideal candidate for re-use, but I understand why the author presumes this. While I rarely find declaration blocks ripe for re-use, I commonly see the undisciplined grouping of selectors that represent design subjects that have no conceptual commonality. This is akin to refactoring Person and Street to derive from a common base class because they both have a Name. Why is this so common? Because engineers take a dim or dismissive view of the visual designer.
The visual designer’s job is to inspire, with as much fidelity as possible, the user’s mental model with the product’s information architecture. He achieves this by carefully synthesizing user research with product research into visual and interactive subjects. This is a discipline requiring great expertise and depth, but is usually treated by developers as a strictly upstream process. The correct approach is to use design artifacts as a reference point to engage in deeper requirements gathering, to understand the intention behind various design decisions and attributes, much like one would with a business subject matter expert. This conversation should be on-going and should touch on everything from color to spacing. The information gathered is the raw material from which a maintainable, well-designed stylesheet collection can be built.
I prefer to think of the stylesheet as authored by an individual who advocates for the visual designer. His goal is to capture the underlying concepts and the relations intended by the visual designer in a way that is idiomatic to CSS (or whatever hypothetical stylesheet language is used). On the other hand, the document template author typically advocates for performance (DOM, transport size, template processing), marketing (SEO), usability (accessibility), etc. The two must collaborate to create a document structure that is suitable to both. In practice, these roles are performed by the same person. It’s difficult, but not impossible, for the same person to switch hats and advocate for all concerns. After all, this is just another application of the Single Responsibility Principle.
Make no mistake, there’s enough blame to go around. Perhaps visual designers can be faulted for not disclaiming any implied completeness of mockups or other simple artifacts, triggering on-going engagement with the developers. And, as stated, managers and technical leads can be faulted for not explicitly directing visual design interviews by front-end engineers. Most troubling might be that visual designers themselves lack a clear conceptual discipline when creating visual designs. Even if they were to be interviewed, one would only discover that their creations were driven by inarticulable instinct and intuition. But this is no excuse. Project commisioners trust the development team to raise flags about project risks like these. Thus it’s incumbent upon the developer to demand and drive a deeper explanation of the visual design (or to communicate the risk to ongoing front-end development agility). That should generally manifest itself in seeking more methodical, conscious visual designers. Worst case, the developer is forced to infer underlying concepts and relations from artifacts. With understanding of the cultural problem and the importance of encoding the design’s intent, this can at least be done consciously to avoid arbitrary and inappropriate CSS design. Regardless, change begins with no one but the front line developers.
Without respect for the visual designer, front-end developers lack crucial information to craft nuanced implementations, and managers have no reason for allocating resources to do this. But if maintainable, adaptable CSS is important, then proper visual design requirements gathering is crucial. So the solution to improving the state of CSS starts with refocusing the development process and resources on the visual designer’s intent. And when intent is properly represented, not only can more informed, nuanced code be crafted, but a particular set of patterns and anti-patterns also emerge. Only then should pre-processors be brought in. Otherwise, one ends up writing articles like the one cited, which treat symptoms superficially because of misdiagnosis. Prognosis: more pain.
One such pattern takes the technique mentioned in the 37signals citation to the logical conclusion, to use child selector chains to create groups of related rulesets that effectively form isolated sub-stylesheets capable of representing complex visual subjects. Another is simply to name magical strings and numbers using pre-processor variables to effect proper re-use. These two techniques alone go a long way toward crafting maintainable, easy-to-use, massive web UIs. An anti-pattern is using selector groups to effect cross-subject re-use; I have found it’s rare to for a visual designer to intend a specialization hierarchy of visual subjects. I hope to find time to expound on this in the future.
In the meantime, I hope we can begin giving visual designers the respect they deserve.