Code Like it's 2020

Because we use Autoprefixer, we are able to write our code as if all our properties are fully supported. When compiled, Autoprefixer will of course convert any properties that have special requirements as far as compatibility is concerned and add prefixes to them as needed.

That includes things like Flexbox, CSS3 properties, and many more! This also means that we should not be using mixins for prefixing. Remember that Autoprefixer uses data from caniuse.com to determine what will be output — so properties that don't have enough browser support should probably still be avoided (or at least used with extreme caution).

A Note On Attribute Selectors

A common use case is to target input types. For example input[type="text"].

It's important to realize that the element selector is not necessary here. If you think about it, we are actually increasing the specificity needlessly. Attribute selectors have the same specificity as a class. The above example has the same specificity as input.someClass

All we really need is [type="text"], because that is sufficient for targeting text inputs.

In summary: attribute selectors should be used alone, just like classes.

Class Naming Convention

We use a modified version of BEM that we call CSM (Component, Sub-component, Modifier). At it's core, it's virtually identical to BEM, but our exact syntax is slightly different. Basically:

Name Spacing

The first thing you'll notice when going through Customer Success's CSS is that all of our class names are prefixed (aka: name-spaced) to one of two letters: c- or t-, meaning _component_ or _template_ respectively. See the below table for more details on Mobify's namespacing practices.

Because we work on top of our client's markup and javascript, we need to make sure our class names will never conflict with their class names. By prefixing/namespacing our classes with c- or t-, we can be assured that 99.9% of those situations are avoided.

Size Units

Use pixels for fixed-width elements.

Use percentages for fluid-width elements.

Use pixels for font-size because it offers absolute control over text.

Use unitless line-height in conjunction with font-size because it acts as a multiplier of the pixel value.

Context Sensitivity

There are certain types of styles that are context sensitive, but tend to be written with no regard to that context. As an example, absolute positioning:

// Action Bar
// ===
.c-action-bar {
position: absolute;
bottom: 0;
}

This is difficult to maintain because this CSS does not communicate anything about what's happening. What is this class absolutely positioned relative to? Good luck trying to figure that out, because chances are you're going to have to manually load up the page that this component exists on and inspect it to find it. That's assuming you know what page this component is used.

A better approach is to build code that is contextual aware. For example:

Exceptions and variations

Sometimes we break out of this convention to add to the readability of our stylesheets. This occurs especially often with long comma separated property values like gradients, shadows, transitions, or includes. These can be arrange across multiple lines and indentation levels to help with diffs and readability.