Better control of css with scoped contexts

After working on a few typography led sites recently (including this one) it became apparent that there was some control lacking applying margins and list-styles to elements in a reliable and predictable way.

Single direction margins

Something Harry Roberts suggests to manage spacing on a page is to ensure that margins are only ever applied to the bottom of elements, in a single direction.

While this is great for typography, you don't want to add margins to everything in a blanket fashion; especially on root elements as there are probably parts of your design that need custom styles without margins or with different values.

Root elements

Often content is created using a WYSIWYG editor in a CMS and you don't have control of what markup is output. You have to make sure that all root elements can work together in any combination as you won't have the opportunity to add classes.

If you set all your root elements to have the same margin, you will end up having to override a lot of them for UI elements unrelated to content. This could be one reason behind Eric Meyer's reset removing all margins as opposed to Normalize that just ensures consistency. Combine the two for a better reset.

Scope styles for different contexts

One way to solve the issue of haphazardly overriding styles is to only apply certain styles when elements are within a container with a specific class. Creating different container classes (contexts) allows you to scope different types of styles together.

You gain complete control over typography with vertical rhythm while never having to override a margin for a UI element. Nothing has a margin applied until you manually add it (in the case of UI components) or add a class to a container.

Taking some liberty with the BEM naming conventions means it's easy to quickly see which styles control which styling for child elements.

Font size and line height

Line heights are applied within .context__rhythm and make sure that they match the vertical rhythm based on the font size. You can use pixels, ems or rems. This ensures that everything will line up and create a 'base' rhythm.

You also probably don't want to include margins when there isn't already a 'base' rhythm on the elements you're targeting. It's easy to forget a class so the .context__margins class must a sibling or descendant of the .context__rhythm class.

Flourishes

Stylistic content -- styles that don't affect vertical layout, like bullets -- applied within .context__flourish ensure that you know all of your styles have no list-styles or extra padding, borders etc. until you place them within a specific class.

Markup

The markup is straight forward as you simply apply a class to a container. You may end up adding some extra <div> tags with more complex projects but the befits of knowing exactly how the child elements will behave is worth the extra markup.

Using Sass

Sass makes is easy to set contexts. The following examples are simplified to show you the principles. You can see the full gist and open in your browser to see how it works.

Maintainability

The examples shown are just to give you an idea about the methodology. You can use Sass to make things much more robust and maintainable by using maps and loops to do all the heavy lifting for you. There's also the fact that you can use rems with px fallbacks for IE as opposed to using ems.

Have a look at a more complex example or see it in action on emilylhardy.com