Ember Theming

Theming a web application typically involves swapping out stylesheets or moving CSS classes around. But what if you have a single page application? It’s a little tricky, but EmberJS and SASS make it incredibly easy.

Goals

There are two primary goals that I wanted to achieve:

Swap Themes Quickly

Rather than have code change colors, fonts, etc. on the fly, it makes a lot more sense to already have those styles pre-defined in CSS.

Be Extensible

When exposed as an Ember Addon, our implementation should allow for 3rd parties to add their own themes easily.

How It Works

This implementation assumes a few things:

The bulk of the theme-switching work is done by a theme service and some SASS mixins.

Let’s Get SASSy

Let’s first look at the SASS code. There’s a $themes map declared. It’s written so that there are base themes and themes within the base. For example, suppose you had different areas of your application to theme, but they should still be a part of your overall theme (like a namespace):

  • foo-primary
  • foo-secondary

In this example, foo is the base theme and primary and secondary are the sub-themes.

The properties of the map are arbitrary, but they are what you’ll refer to later on in CSS, sort of like a theme API. Think of it like “for this div.class-name, use the primary color for the background”.

Note: We will be using a data-theme attribute on HTML tags. I thought this was cleaner than swapping class attributes and the intent is clear in the markup.

Here is a gist of the SASS functionality to make theme switching happen. I’ll come back to using it momentarily.

Theme Service

Now let’s take a look at the theme service. Anything that’s going to consume this service will be able to:

  • bind to the current theme
  • set the base theme
  • set the sub-theme

Theming Your Application

How you determine when themes change is up to you. But here’s an example of swapping themes at a route:

Determining what you want to theme is also up to you. Let’s assume you have a component, here’s an example of using the theme service:

Two things to note:

  • Your component injects the theme service
  • Your template has a div with a data-theme attribute that is bound to the theme.name.

As the theme.name property changes, your data-theme will as well.

Last, to wire this all together, you have to style your div with the theme property you want. For example:

Only the first couple lines are relevant, the remainder displays what the resulting CSS will look like.

Extending

In the SASS code, it merges a property $theme-additional if it exists into the $themes map. If this code were available as an addon, you could add your own themes as follows:

  • Create your own theme map, so long as it is named $theme-additional.
  • Make sure you @import it prior to $themes.

Wrapping Up

If you thought this was interesting, found a way to make it better or wound up doing something awesome with it, I’d love to hear about it.

Here’s an example of theme switching in action:

B Impact Assessment — Theme Switching

If you want to view theme switching live and you want to make a difference in the world, why not try Measuring What Matters Most? You can also view a full gist here.

Web Development, Ember, JavaScript


Originally published at jonpitcherella.com on April 2, 2016.