DEV Community

loading...
Cover image for How To Plan Scalable CSS for Large Projects?

How To Plan Scalable CSS for Large Projects?

jenc profile image jen chan ・5 min read

Having worked on a couple large projects, I feel myself start to form opinions on how CSS is implemented across multi-module single page apps. Here's some brainstorming and questions I have on the subject.

Preamble

I'm particularly inspired by the "You think you know CSS" series by hoangbkit and Rachel Andrew's work on CSS grids

0. Defining best (and not-best) practices

Company-wide, this step is the easiest of the rest.
Bad practices can be weeded out during code review and put to bed.

I discussed and learned some best/not-great practices in an old post

1. Preprecessor Choice

Usually this is decided by a tech lead, or maybe the command line version of the JS framework comes with a baked-in pre-processor. I'm in belief of leveraging whatever these preprocessors have to offer when they're used.

SASS

PostCSS

Styled Components

Pertinent to the following choices are whether a company or product already has a design system or style guide. If there is one, the logical approach is to go deeper on enforcing CSS patterns.

The latter two also endorse a "CSS in JS" approach I've never tried before, but seem to go along the lines of a "write once and reuse your component", with any more common styles being easy to import from a global style resource.

2. CSS Methodologies/Patterns

A lot of the following philosophies have overlap with each other. And where they differ, I see many merits for different stages of development.

BEM

Example of BEM

BEM, or Block Element Modifier style is something to get used to and when I first entered development seem to have quite a following. I think I see it in a ton of frameworks too (Ng-Material, ahem!)

While this syntax is more semantic than atomic pattern and makes attempts to build scope into selector naming, it's not needed if we use SASS or JS frameworks which provide nested scopes. The result of its implementation is insanely verbose.

Example: menu bar

  1. The default component styles go into a selector called .navigation
  2. Writing another selector called .navigation__li to style all the list items under a navigation
  3. Then using .navigation__li--active to indicate the active state of a list item

...and having to declare all of the styles above inline just to indicate an element is active with navigation navigation_li navigation_li--active

Now rinse and repeat for all different states or needs related to an element.

Atomic (also known interchangeably as "Functional CSS")

Atomic CSS example

Atomic is a library and also an ethos around using units of aliased style to implement classes on the fly, like inline-styles.

While great for prototyping a design fast, I'm not crazy about this approach.

Example: a heading with a container
Having to remember to use Bd to create a 1px border anytime I want it on a particular element. Then, if that element contains text, I'll be using Lh(1.5) to indicate it has a line height of 1.5em and f1 to stand for a font size of 3em

Now for every heading I end up with:
<div class ="f1 Bd Lh(1.5)"></div>

It's illegible, and gets really tiresome if I have many pages with many headings to style. An extended tirade by Adam Silver right here.

However, tachyons is an atomically-principled library that has few enough classes to make rapid prototyping in code possible, and my go-to when I need a landing page fast.

DRY (Don't Repeat Yourself)

DRY example

In Maintainable CSS, Adam Silver defines the DRY grouping as a strategy for applying semantic classes to reusable groupings of style.

I like to take this further and think about components coded as Sass mixins to be included/reapplied wherever they're reused in an application. (Au contraire, some may hate this idea as it requires the parsing of the imported authoritative style file every time)

SMACSS

SMACSS, pronounced "smacks" aka "scalable and modular architecture for css"

SMACSS file organization

This involves separating styles in terms of base styles, modules, components and state, in addition to creating classes for frequently coupled styles attributes.

Parts of the SMACSS methodology
It's very similar to maintainable CSS but includes more opinions on nesting and specificity.

OOCSS

Not quite object-oriented in the traditional sense, and otherwise thought of as the original "modular"

Design structure, container and content

According to its ideator Nicole Sullivan, the point of OOCSS is to:

  • Separate structure and skin
  • Separate container and content

Example of object oriented CSS

Before googling it, I didn't even know that OOCSS informs much of what I've learned to be today's efforts at modular CSS: to write style by component.

3 CSS style-guide?

Does this serve as more reading for fellow devs who are already short on time, or serve to better reinforce design consistency?

I think this is team dependent. If the company is design-focused and organized, this could be very helpful. When I first started trying to level up my JS for industry however, the Airbnb style guides for writing ES6 were insanely intimidating.

4. Popular Libraries

I prefer to direct you to this brilliant post by Huang b Kit on popular libs.

5. Grids and responsive grids

If you've received designs your team is probably going to need to agree on grid columns and breakpoints or things will get dicey when you merge your branches in.

A typical design grid is 12 or 10 column that snaps down to 1-4 on a small device. If a CSS lib leverages flexbox or flexgrid, it's possible to implement responsiveness without media queries.

6. Organizing components for development

I'm not well versed on this part but I've heard a ton of good things about using Storybook to test and develop components in isolation prior to handing over to other devs.

Questions

In a dream world I would love to write the styling once and just reuse it anywhere I want. Then I realize there's a couple of layouts, maybe-conflicting assumptions between how I imagined a layout to work, and how it works to a different dev. This involves a lot of communication and agreement.

I'd like to hear about how you settled on a CSS strategy in your team or company. What do you find most effective for smaller or larger teams? What have you discovered to be good things to agree on before and during dev? What is your experience with writing CSS in JS? Have you enjoyed alternates to Sass and less?

Discussion (4)

pic
Editor guide
Collapse
mattwaler profile image
Matt Waler • Edited

Using a utility framework like Tachyons and Tailwind has been the only way I've ever been able to scale a website without also scaling up my CSS every time I work on it again.

Collapse
jenc profile image
jen chan Author

Can you explain how you work with it? With tachyons I get so tired of applying multiple classes to the same divs or headers when there's over 5 views. Do you group the classes and apply them?

Collapse
mattwaler profile image
Matt Waler • Edited

I personally use Tailwind, and I generate very immutable and practical classes and reuse them everywhere.

It might seem tiresome "applying" multiple classes to elements, but you would be "applying" them repeatedly in your CSS anyways had you been doing this in a more traditional way! In this way, you're recycling style application across elements.

My personal website is built with TailwindCSS and is publicly available on Github. Here are the links to both!

My Site
Repo
Homepage Markup

Thread Thread
jenc profile image
jen chan Author • Edited

My tab-switching laziness knows no bounds! You're right. Either way we'd have to write the plain css at least once unless the project is using plain ol' default bootstrappy styles .