A lot of start-ups don’t have the budget for a dedicated CSS expert. Developers know enough about CSS to make things work, and so companies get by with the knowledge that they have, and often that’s “good enough”. To the end-user, as long as the design looks nice, it doesn’t really matter how the CSS is structured. But in the development cycle, there can be a lot of frustration when your CSS isn’t scalable and maintainable. People resort to using !important  when they need to overwrite something someone else has done. Developers struggle with specificity, and finding where a chunk of CSS lives. They often repeat work styling a specific text input, not realizing that some other developer did virtually the same work 6 months ago.

I wanted to share a few tips and resources with the companies that experience these issues; a few hours’ research and reading can infinitely improve the scalability, readability and maintainability of your CSS, even if a CSS expert is not yet on your payroll.

Naming Conventions

There are a few naming conventions out there for CSS. It doesn’t matter which you use, but you really should use one. Pick a standard for your organization, and teach it to anyone that writes CSS. Some examples of naming conventions are BEM (Block, Element, Modifier) or SMACSS (Scalable and Modular Architecture for CSS, developed by Ottawa native Jonathan Snook). A good naming convention sets classes for your elements that are perhaps a bit verbose but extremely clear. The class names we’re using at Martello look something like this:

Naming conventions in UX Tips blog

We prefix things to show our future selves or new developers the intent.

  • mds (Martello Design System) shows that this is a CSS class that we applied.

It doesn’t overlap with classes from external libraries, and as we go backwards through our product to improve our CSS, we can see what we’ve covered already. We never target mds-prefixed elements with form logic or JavaScript because if someone re-styles an element, we don’t want it to break that JavaScript.

  • js tells us that this button is being targeted by JavaScript, and so we shouldn’t remove that id or the element without addressing our JavaScript first.

Our classes are long, but they tell us very clearly what they’re doing for the code without having to render the page.

Additional Resources:

Using a Pre-Processor

If you’re not using a CSS pre-processor, you should be. LESS and SCSS (formerly known as SASS) are the two most popular options. SCSS is my preference, but it doesn’t really matter. A pre-processor extends CSS to allow for some scripting, variables and importing of partial files. At build time, it compiles everything into a minified, valid CSS file that you can ship with your product.

Because I’m using BEM as my naming convention, each block gets its own partial. That way I know just by looking at my class names where the CSS for this element lives. Anything that starts with mds-form lives in a partial called __form.scss

Then we can collect all of our partials into a single list to be compiled.
Lines of code - UX blog

It’s absolutely no hassle to find where CSS lives because we have a good naming convention and use a pre-processor to compile our partials into a single CSS file.

Additional Resources:

Design System (or Pattern Library, or Style Guide)

A design system helps to define individual components for your application in a single resource that all developers can access. Suppose you need to add a button to your interface. You would go to the design system, look up the button component, and grab the appropriate code snippet to paste into your code. A good design system should be at least pseudo-open source: perhaps not accessible to the public, but anyone in your organization should be able to write to it. If someone wants to contribute a new component, they should have some method of doing that. If you ever need to change the theme in your app or change how much padding or margin a certain element has, there’s one place to change it because you’ve got a naming convention, a pre-processor and everyone’s been pulling from the same design system. There’s no duplicate buttons that look very similar because everyone’s using the same class names for the same components. When someone needs a new component, they create it and add it to the design system.

Many of you are familiar with the Salesforce CRM. They have an API that allows developers to add their own plug-ins. Salesforce wants those plug-ins to look like the native application, so they make their design system available to all plug-in authors. Check out the Lightning Design system. The lead designer is Jina Bolton who stresses that Clarity is more important than Efficiency, which is more important than Consistency, which is more important than Beauty. That’s a great philosophy when laying out your pages. Make it as clear as you can FIRST, and only then, after it’s as clear as it can be, try to make it as efficient as it can be. Then make your processes and interactions consistent with the rest of the application. Finally, after all those other things have been prioritized, then try to make it look beautiful.

There are many tools that help you generate a design system. A bit of initial work on setting it up dramatically reduces the workload to make your application easier to develop down the line. I’ll be speaking at CSSDevConf 2017 in New Orleans about applying a design system to a legacy product.

Additional Resources:

Final Thoughts

  • Learn about specificity – always use classes as selectors for your CSS, never id
  • !important is often a sign that your CSS isn’t structured as well as it should be. Try to avoid it!
  • Send one of your developers to CSSDevConf 2017 – he or she will learn huge amounts about keeping your CSS in check