Component Theming illustration

Why we're moving to component theming

Profile picture for user Rob
Rob Bayliss
CTO

A week ago, we released Mannequin, which we’re calling a “Component theming tool for the web.” I wanted to explain what we mean by “Component theming,” and to explain why we’re (belatedly) switching to this approach for our Drupal development.

Our Story

We used to be terrible at theming. Five or six years ago, the sites we built were consistent in one way - they all had inconsistent page margins, big cross-browser issues, and enough CSS to theme a dozen sites. As a developer, I used to hate jumping betweeen our projects, because each one had it’s own rats-nest of CSS, and every time I made a change, it broke parts of the site that nobody even knew existed.

That changed when we discovered Foundation. Foundation solved the vast majority of our consistency and cross-browser problems right away. It was a night-and-day shift for us. We’d just apply a few simple classes to our markup, and our theming was “roughed in”. Some custom styles would be written to cover the rest, but in general we were writing much less code, which made the bugs easier to find and fix. There was still a pretty major problem though - small changes still had a tendency to break things in unexpected ways.

These days, we’re starting a new chapter in our journey toward front-end excellence… the shift to Component theming. Component theming is theming based on chunks of markup (“Components”) rather than pages. If you haven’t read Brad Frost’s excellent Atomic Design, you should. It’s a great intro to the topic, although the terminology is a little different from what we’ll use here… Atomic Design is as much a specification for design as it is for development, and what we’re primarily interested in here is the development portion (theming).

What we’re changing

Long story short, for many of our newer projects, we’ve been shifting away from using globally available utility classes (such as Foundation’s .row and .column), and toward theming specific classes that are only used by the templates under our control. To use a very simple example, let’s consider how we might theme something like a grid of images:

Foundation Markup:

See the Pen Foundation - Card by Rob Bayliss (@rbayliss) on CodePen.

Component Markup:

See the Pen Foundation - Card by Rob Bayliss (@rbayliss) on CodePen.

The thing that’s immediately obvious is that we’ve gotten rid of the Foundation layout classes. This forces us to handle the layout ourselves, and to do that, we’re targeting the markup we know this component uses directly. What’s more, all of our CSS we’re using for this component is scoped to the ImageGrid class, so there’s no chance it will leak out into the global styling. We might say that this component is very isolated from the rest of the system as compared to the Foundation version, which is going to depend on the unscoped .row and .column selectors. As a result, when the client adds feedback at the end of the sprint that the first image in the grid is 1px off, we can make that fix without touching anything but the ImageGrid CSS. That is to say - refactoring just got a whole lot easier.  For example, imagine that we’re shifting toward a CSS Grid layout, and we want to shift this component over without breaking the rest of the site.

Component Markup with CSS Grid

See the Pen Foundation - Card by Rob Bayliss (@rbayliss) on CodePen.

This is a pretty significant change on the component scale (swapping layout systems), but as long as we’ve properly scoped our CSS, there’s no danger of this change leaking out to the rest of the system.

But what about shared styles?

There will always be shared styles. Even if we added no unscoped CSS or utility classes, browsers have their own stylesheet that would change the look of your components. The key is to keep these as minimal as possible. We’ve still be applying the following two Foundation mixins globally on the projects where we’ve been working with components:

This gives us a good global baseline that gets shared by all components, but you need to be extremely judicious about what gets included in unscoped CSS, since changing it later on will affect every single component (exactly what we want to avoid).

How we’re changing

Last week, we released Mannequin, a tool for isolating your templates as components and rendering them with sample data. Going forward, we plan to use Mannequin on all of our new projects from the get-go. Rather than writing extremely Drupal-specific templates, our front end developers will be writing a much cleaner version in Mannequin, then we’ll be wiring it into Drupal using what we’re calling “glue templates.”

Mannequin does not dictate that we use a glue template here - we could be writing a single node.html.twig and use it with Mannequin just fine. But glue templates give us two important benefits. First, we’re free to reuse the component template just by writing another glue template that includes it, keeping our project DRY while making things nice and discoverable by leaving the Drupal defined templates in place. Second, writing our templates without considering Drupal’s funky data structures means we can work with developers who don’t know their nodes from their assets (non-Drupal developers). As much as I poke fun, we’re excited to be leaving a lot of the Drupalisms behind.

That’s all for now!

Next week looks like a a busy one! If you’re going to BADCamp and are interested in Component based theming, please find us to talk, or come to our session on Mannequin!  Also, look for a blog post next week with a step-by-step guide to setting up Mannequin for Drupal.  

comments powered by Disqus