CSS at Say Media

You won't believe the shocking things this Say Media employee has to say about CSS properties.
Avatar:
Smith Schwartz
Author:
Publish date:
Social count:
20
You won't believe the shocking things this Say Media employee has to say about CSS properties.

We Style Multiple Sites with One Codebase

Something that’s largely different about the work we do at Say Media versus the other CSS writeups out there is that our codebase provides style to multiple sites with different designs. Tempest, our digital magazine publishing platform, powers sites like Biography, Fashionista, ReadWrite and well, you guessed it, Say Daily. Each site has its own unique set of Sass variables (along with other custom assets like SVG and images) that gives each its own particular look and feel. This means our Sass development is super interesting as each new feature, bug fix or refactor is rolled out to multiple sites at once. 

CSS Naming Conventions

We use our own hybrid of SMACSS and OOCSS. Currently, our class names are divided into six categories:

Layout ( .l-layoutname )

Layout classes should only define the structural presentation of container elements. These specify size and position apart from the site skin. A good example of this is the wrapper class .l-full-width which is used as a parent class on any page of any content type that is meant to expand to full width.

Module ( .m-modulename )

Modules as the core elements that make up the content and functionality of the page. For example, m-story is the class name for a story (we use this as a generic term for post or article). These generally represent the core content of each element on the page.

Module Component (.m-modulename--component )

This is used for the subelements inside a self contained module. For example, m-story--copy is the class name for the wrapper of body text that is one part of m-story.

Sub-Module ( .m-modulename_submodule )

These are variants of a module that are different enough to require a submodule. These are an extension of the core module. An example is .m-follow_twitter, a specific type of follow button on an author page. 

I’m interested in exploring the removal of this category of classes as it’s not been widely used and seems to be misused more often than not.

Module Modifier ( .m-modulename.mm-modifiername )

This is used for small chainable changes to a module. It’s possible to combine multiple modifiers with a module. An example is .mm-has-svg, a generic modifier we give to elements that contain svg.

State ( .is-statename )

State classes are used to represent different states of a module, not changes to the module. Examples would be .is-disabled, .is-read, .is-selected. These are classes that generally are added and removed with JavaScript.

LibSass Logo

LibSass

We made the big switch from Ruby Sass to LibSass about 5 months ago and it’s been a great change. Although we miss out on some great features from Ruby Sass like (@extend), our compile times are so much faster and workflows are more smooth. My hunch is that lots more folks will be making the switch in the near future, especially as LibSass gains features and improves documentation.

Order of Properties

We’re just beginning a new era of implementing an internal Sass style. Each Sass file should adhere to the following style.

Here are some good habits when writing your Sass files:

Here are some good habits when writing your Sass files:

  •  @includes should come first.
  • Plain properties should come next in alphabetical order (for a large team, alphabetizing can be quite helpful as it standardizes location of properties).
  • Nested media queries for the original class are next.
  • Do not add properties or includes for the parent class after nesting. This is quite confusing and messy, and often leads to confusion or duplication of code.
  • We use $variables as much as possible, this creates ‘one source of truth’ for faster updates and keeps our CSS consistent across multiple sites.
  • One class per line, one property per line. 
  • Do not add properties or includes for the parent class after nesting. This is quite confusing and messy, and often leads to confusion.
  • We use $variables as much as possible, this creates ‘one source of truth’ for faster updates and keeps our CSS consistent across multiple sites.
Here's how NOT to style your Sass files

Here's how NOT to style your Sass files

We have an internal wiki for documentation, but not everyone (myself included) takes the time to look this over when there are documentation updates. So, we’re starting the process of becoming much more liberal in commenting our Sass. That way, it’s easier to keep these notes more up to date with our code.

That said, we avoid writing inline TODO or FIXME. We have a robust ticketing system that is a much better place to keep track of those items.

We Use Bourbon

bourbon-logo2.png

I’m ok with this, but interested to revisit this decision. I like the simplicity of Bourbon and the mix-ins it provides, but I’m curious to try AutoPrefixer as it seems to be becoming the standard for vendor prefixes. I’m not sure if using both would be in conflict and/or how much pain removing Bourbon might cause, but should be something we think about in the near future.

Size of Our Team

Our CSS can be updated by about 40 different engineers and designers on any given day. That’s why it is so !important to be vigilant about upkeep and refactoring.

Refactor As We Go

Every time we add a new feature or bug fix, my hope is that we all follow the campsite rule of leaving the code just a little bit better than when we found it. While there’s not always time to refactor every single line, even just cleaning up property order and whitespace can go a long way, one little bit at a time. Keeping our codebase tidy is a great habit to have. In life as in code, one should Always be Knolling.