Sharing Styles Across Brands and Sass Maps For Extensibility

Kyler Berry
Zumba Tech
5 min readNov 14, 2017

--

A quick Google search of “Sass maps” will give you some great articles on the ins-and-outs of this feature, as well as some of the more obvious use-cases for it. However, I wanted to highlight one way we use maps in order to keep our Sass partials reusable across brands.

Some Background

Earlier this year Zumba released a second branded site, Strong by Zumba — a new fitness program with a very different appeal, and along with it, a new look. From inception we knew that this site would live in the existing codebase inheriting all the features and capabilities of the existing Zumba site as well as share many of its base styles (layout, forms, components, etc), but it would have a new aesthetic and typography.

The Approach

As such, we attempted to @import and reuse as many of Zumba’s style partials as possible and then apply the new brand’s styles in an override partial to keep things DRY. In this way the base theme acts as a central repo of styles and new themes extend and alter as necessary.

Consider the following example:

Here we’ve established a nice Sass partial that styles .my-component. It includes a couple mixins and some other properties. We wanted to reuse much of the layout and other styles associated with Zumba so instead of repeating these styles for the new theme, we want to extend them:

In a new overriding partial, defined within a themed/strong directory, we import the existing partial from Zumba and add only the styles we want to override, ie: background-color. With this approach our new brand has retained the layout, and any other properties we’d previously defined in Zumba and we’ve taken advantage of the cascade to overwrite just the targeted style properties.

Problems

While this approach of extending our existing Sass allowed us to iterate quickly on the new site, it also created some problems. In particular, the original Zumba codebase was written with only one brand in mind, thus theme-specific properties became roadblocks. For instance, the Zumba theme’s typography was based on an in-house font: Zandes and the code base was littered with calls to a mixin for including that font’s variations: @include z-bold(), @include z-reg(), @include z-med(), etc.

Strong by Zumba’s theme however is based on a different typography set and in response, our Strong partials became overrun with countering calls to it’s font mixins: @include ach-reg(), @include ach-med(), @include ach-bold().

This quickly turned our lightweight partials into repetitive documents where old font definitions were being replaced piecemeal, and often, some would get missed causing conflicting fonts to be on the page simultaneously.

Challenge: How do we make our base theme more generalized, especially in relation to fonts and how can we prepare it in a way that it could be applied to any number of hypothetical (read: probable) brands in the future?

Show Me The Maps

This is where Sass maps came in handy. Instead of creating mixins that describe the font used, e.g. @include z-bold(), why not create mixins that ask for a font type and let the theme decide which font to serve, e.g. @include font('bold').

In each theme, we have a typeography.scss that defines our fonts and some high-level typographic styles. At the top of this file we now have a key-value pair of font-types to fonts. For the Zumba theme:

Now we can create a mixin that receives a string parameter that serves as an index of which font to use. Note: You may notice that the italic type uses the same font as light. This is intentional and the mixin handles this case.

We’ve defined a mixin that accepts a string, we check that the string exists in our map and set the appropriate font. This particular font has no italic variation so we default to the light variation and apply a font-style: italic if the type is italic.

The same concepts apply to the Strong by Zumba theme, but our font-map and the mixin implementation can change depending upon the needs of the theme.

As before, we’ve mapped some font-types to this theme’s fonts and create a font mixin declaration that is identical to the base theme. The difference being that in the Zumba theme, reg maps to Zandes-Regular and in the Strong by Zumba theme it maps to Archerus-Regular . Note: The font type keys that exist in the base theme need to also exist in the extended themes font-map.

The Effect

Now we can use our new mixin @include font('italic') everywhere and reuse partials across other themes without fear of font-mixup. Additionally, we keep our new theme’s override partials DRY because we don’t have to continually re-apply our fonts.

I understand this is not a scenario that fits many use-cases as it is a workaround to theme a project that was not originally built to be themed. But, hopefully it provides some insights on sharing an established style library across other sites or brands within your organization and encourages you to look for outside-the-box solutions with the tools you have at hand.

Other Known Issues

The idea of exploiting the cascade in order to extend existing styles works well, but becomes increasingly difficult as css specificity increases. This was a problem that occurred often and was a catalyst in pushing our team to incorporate BEM into our Sass-writing. BEM tends to force styles into having lower specificity as well as providing better context awareness for the developer.

--

--

Kyler Berry
Zumba Tech

Front-End Engineer @Zumba . Weekend Warrior and Delicious Coffee Maker (The coffee is delicious, not me)