CSSing like an Architect

It’s 2018 and I have been using JSS with React and Typescript for about a year now. I think it has some advantages that I’ll address, but the point of this post is not to sway others to use it. In my opinion, with the release of React in 2015, the CSS world exploded. Perhaps choosing a flavor of CSS(e.g. PostCSS, SASS, LESS, JSS, Inline-CSS) became more important than how CSS is written. So my hope is this post will encourage others to treat CSS like it matters, provide some examples of how to make that happen, and have a good time along the way.

CSS is what users interact with, it’s the first non-physical interface encountered. If the CSS architecture is poor, conforming to user requirements will suffer, which will lead to client loss, $$$ loss, and often product failure.

I first started writing CSS 10 years ago with “good” old Dreamweaver. When I look back over those 10 years one thing sticks out. It is not easy to write CSS in an organized way that is easy for others to understand. I still struggle to do that every day. However, with the release of React it became suddenly easier (after the learning curve). When I discovered the JSS+Typescript pairing, suddenly styling became type safe, creating an even better development experience.

Okay great, But why? I’ll share a few reasons below.

File and Code Structure

File Structure

Five years ago I used to lump my stylesheets all in the same folder. I mean…I usually had a organization scheme in mind, but it would always break down. It might have looked something like this(using SASS).


styles
  main.scss
  variables.scss
  base.scss
  pages
   home.scss
   about.scss
   etc...

This isn't the worst thing ever, but when you start getting into shared styles, or realize the home view is actually the largest view on earth, things break down. It becomes hard to find styles in files that have grown out of control.

Today with React, files stay small and are associated with a hopefully reusable Component.

So now my file structure looks something like this(JSS and Typescript):


styles
  variables.ts
  shared
    helpers.ts
components
  HomeComponent
    ContentCard
      index.tsx
      styles.ts
    index.tsx
    styles.ts

This is the least exciting part, but you get the idea. Now all Components have their own stylesheet. If you know the component name, you just have the find that component in the file structure then access its stylesheet. No more deep dives. No more global searches.

Code Structure

With react (and css-modules), styles become flatter. Let's take that old file structure. In home.scss you might see something like this:


...
.home {
  padding: 0px;
  margin: 0px;
	
  .content-card {
    background-color: white;
    
    .header {
      background-color: red;
      ...
    }
  }
{
...

In the new component based file structure, we automatically only care about its own styles so for a ContentCard we should just see:


export const styles: StyleRules = {
  root: {
    backgroundColor: "white",
  }
  header: {
    backgroundColor: "red",
  }
}

JSX file:

import styles from "./styles"

export const ContentCard = () =>
  <div className={styles.root}>
    <div className={styles.header}></div>
  </div>;

This being said, structure is important because it gives everything a place and a pattern for new developers to follow. We are not leaving a pile of CSS for someone else to parse and refactor. We are leaving behind a understandable code base and system for change, that can be reconfigured, added to, and even broken apart and rebuilt if needed.

Code Sharing

I'm just going to show you, because it explains itself.


helpers.ts
const helpers = {
  defaultPadding: {
    padding: 0px 15px;
  }
}

export helpers;

ContentCard/styles.ts
import { helpers } from "styles/helpers";

const styles: StyleRules = {
  root: {
    ...helpers.defaultPadding,
    backgroundColor: "white",
  }
}

If you didn't catch it. We just merged classes. Boom.

A couple more things.

Modular

JSS has a lot of options, one being modular styles (nothing new). This means your styles will not be considered global. In my opinion this is a huge plus. No more global cascades, nested selectors, and !important-ing !importants??. Those things do not help contribute to a system for change. When working on a modular/containerized CSS structure, I can feel confident that I won't be wreaking havoc across the application when I make a change.

Types

Because of Typescript, and material-UI StyleRules type. I never have to worry about writing styles. It will tell me when I do something illegal right when I make the error; something I think CSS has been lacking in for quite some time.

Treat CSS like it matters. Hope you got some ideas, and are now a step closer to CSSing like an Architect.

 


Top