This post is part of the series ‘Making ubuntu.com responsive‘.
When working to make the current web style guide responsive, we made some large updates to the core Sass. We decided to update the file and folder structure of our styles. I love reading about other people or organisations Sass architectures, so I thought it would be only right to share the structure that has evolved over time here at Canonical.
Let’s get right to it.
I won’t describe each file as some are self-explanatory but let’s just go through the core files to understand the structure.
core.scss contains the core HTML element styling. Such as
ul, etc. You could say this acts as a reset file customised to match our style.
core-constants.scss is home to all variables used throughout. This file contains all the set colours used on the site. Base font size and some extra grid variables used to extend the layout.
core-grid.scss holds the entire responsive grid styles. This file mainly consists of generated code from Gridinator which we extended with breakpoints to modify the layout as the viewport gets smaller. You can read more about how we did this in “Making ubuntu.com responsive: making our grid responsive”.
core-mixins.scss holds all the mixins used in our Sass.
core-templates.scss is used to hold full pages styling classes. Without applying a template class to the
<body> of a page you get a standard page style, if you add a template class, you will get the styles that are appropriate for that template.
Web team front end working on the web style guide.
Divide and conquer
Patterns were originally all in one huge scss file, which became difficult to maintain. So we decided to split the patterns file apart in a pattern folder. This allows us to find and work in a much more modular way. This involved manually working through the file. Removing all the components styles into a new file and import back into the same position.
Our mission when setting up the naming convention for our CSS was to make the markup as human readable as possible.
We decided early on to almost use a object oriented, inheritance system for large structural elements. For example, the class
.row can be extended by adding the
.row-enterprise class which applies a dark aubergine background and modifies the elements inside to be display correctly on a dark background.
We switch to a single class approach for small modular components, such as lists. If you apply the class .list the list items are styled with our simple Ubuntu list style. This can be modified by changing the class to
.list-canonical, which apply their corresponding branding themed bullets to the items.
The decision to use different systems arose from the desire to keep the markup clean and easy to skim read by limiting the classes applied to each element. We could have continued with the inheritance system for smaller elements but that would have lead to two or more classes (
.list-canonical) for each element. We felt this was overkill for every small component. For large structural elements such as rows it’s easier to start with a
.row class and have added functionality and styling by adding classes.
We mainly use mixins to handle browser prefixes as we haven’t yet added a “prefixer” step to our build system.
A lot of our styles are quite specific and therefore would not benefit from being included as a mixin.
A note on Block, Element, Modifier syntax
We would like to have used the Block, Element, Modifier (BEM) syntax as we think it is a good convention and easy for people external to the project to understand and use. Since we started this project back in 2013 with the above syntax, which is now used on a number of sites across the Canonical/Ubuntu web real estate, the effort to convert every class name to follow the BEM naming convention would far outweigh the benefits it would return.
By splitting our bloated patterns file into multiple small modular files we have made it much easier to maintain and diagnose bugs within components. I would recommend anyone in a similar situation to find the time to split the components into separate files sooner rather then later. The effort grows exponentially the longer it’s left.
Introducing linting to the production of the guidelines will keep our coding style the same throughout the team and help readability to new members of the team.
Read the next post in this series: “Making ubuntu.com responsive: ensuring performance”
- Modular CSS with Sass & BEM
- Autoprefixer: A Postprocessor for Dealing with Vendor Prefixes in the Best Possible Way
- Scalable and Modular Architecture for CSS