1 Comment

CSS is a Mess – Applying the SRP and the Law of Demeter

At the last SoftwareGR event, Jonathan Snook gave a great talk titled “CSS is a Mess.” I was particularly interested because, while I’ve always tried to organize my CSS thoughtfully, I’ve often found that the end result isn’t as clean as I’d hoped.

Jonathan’s talk is full of great tips to help organize and clean up your CSS, but a couple points really stood out.

The Law of Demeter – It’s for CSS too!

Most developers will cringe when seeing code of this sort:

thing1.getThing2().getHairStyle().getColor().getRedComponent();

It’s a clear violation of the Law of Demeter. However, we don’t always recognize the same problem here:

#signup-page #sidebar ul li a {
  color: #336;
}

Jonathan suggests that you avoid styling based on context like this, as styles created for one component will likely be needed in other places and end up being duplicated. These styles can also apply more generally than expected, requiring nested content to “undo” some of the settings to render correctly. A third pitfall is that as the html structure changes or content is moved around the page, these deep selectors will of course break, and some of these breakages may be subtle enough to go unnoticed for a long while.

Try instead to limit selector depth to immediate children using child selectors, and make modules and states that can be used throughout the application.

The Single Responsibility Principle – Also for CSS!

Another really interesting point Snook makes is that you’re much better off using new html elements for each responsibility. For example, something like this seems reasonable:

<div id="container" class="grid">
    <div id="item" class="grid-col card">...</div>
</div>

The “grid-col” class provides layout styles for the #item div and the “card” class provides the content appearance. One problem here is that styles in “grid-col” may compete with styles in “card” and cause conflict. Another problem is that since the layout and appearance are tied to the same element, it’s difficult to swap in some other content.

The structure would be much more accepting of changes to the content if the #item div were restricted to layout concerns and had a child div focused on the appearance of the specific content. Once this is done, the content can be swapped out for some other component without losing any of the layout constraints.

There’s a ton more great advice in Jonathan’s talk, and I’d recommend checking it out. You can also visit the SoftwareGR YouTube channel to see videos from other recent events.