Building your own Modern CSS Design System
Tags: css
Published: 2020-07-27 15:38:14

---
title: Building your own Modern CSS Design System
published: true
description: There's a lot of ways to tackle CSS. I want to introduce you to Modern CSS Design Systems, which uses CSS variables to declare your key design elements. 
tags: CSS
//cover_image: https://direct_url_to_image.jpg
---

There's a lot of ways to tackle CSS. I want to introduce you to Modern CSS Design Systems, which uses CSS variables to declare your key design elements. 

Let's jump right into an example. Choose a new theme by clicking on any of the buttons in the top-right. 

{% codepen https://codepen.io/rockykev/pen/bGEJyjm default-tab=result %}

All those buttons did was change the values of the CSS variables. Rather than writing a completely new theme file, you change a dozen or two lines and boom -- new theme! Very powerful stuff.

> I took this course by the amazing [Scott Tolinski](https://www.leveluptutorials.com/tutorials/modern-css-design-systems/) to understand Modern CSS Design Systems. I always struggled with writing clean CSS, and this methodology gave me a lot of tricks. 


## What are design systems

Major companies use design systems to create a standard design so their components look consistent across their entire suite of software - typically by loading those values in a JSON file. Using an example: In their design system, Uber may include their brand colors, 8 different logos depending on screen size, what type of icons to use where, and even the ratio of their border-radiuses. [More info on Design Systems](https://www.invisionapp.com/inside-design/guide-to-design-systems/)

This post is only taking the role of the CSS developer. 
Building your CSS design in this way will allow you

* To switch themes on the fly ([like in my example](https://codepen.io/rockykev/pen/bGEJyjm?editors=1000)) 
* Build a strong CSS system that can tolerate changes
* Or even use a company-wide design system to programmically change your designs as needed 

The free [Figma course on design systems](https://designcode.io/design-system-in-figma) will help fill in a lot of blanks.

## Starting your CSS Design System

### CSS Variables
You should understand how CSS variables work. 

It looks like this: 

```css
:root {
  --black: #000000;
  --background: var(--black);
}

body {
    background: var(--background);
}
```

What you did here was: 
1. Declared a variable called `--black`. 
2. Declared a variable called `--background`, and passed the `--black` value to it.
3. Changed the background color of the body to the `--background` variable.

If you decide to make the background red, you have to change the `--background` variable.

Why not pass our black color `#000000` directly to our `--background` variable? We'll cover that in a bit.

### Classless CSS

You should also get the concept of classless CSS. Classless CSS is defining the design directly on top of the core css. 

BAD
```css
.paragraph {
	font-size: var(--baseFontSize);
}
```

GOOD
```css
p {
	font-size: var(--baseFontSize);
}
```

It'll make you write cleaner, smaller, better CSS, instead of declaring a new class for every. single. element.

Check out this whole list of CSS Frameworks, and check out the [classless section](https://github.com/troxler/awesome-css-frameworks).


### Declaring Design Intentions 

You want to identify the intentions of your CSS elements. 

What are intentions? They are kind of like this image (minus the colors): 
![](https://images.ctfassets.net/ooa29xqb8tix/4p5RK1m91esG8wG2QO8wwy/51ef299dbbc56e39e725eae63dab3798/design-system-all.jpg)
Borrowed from the free Figma course

Some examples of Design Intentions: 

```css
::root {
    --siteBackground: var(--lightGrey);
    --siteLines: solid 1px var(--grey);
    --borderRadius: 1.2rem;
    --bodylineHeight: 2.1;
		
    --headerBackground: var(--darkBlue);
    --footerBackground: var(--headerBackground);
}
```

These are global variables you can call within your site. 
Notice that I called `--headerBackground` inside the `--footerBackground` variable, making them the same color. 

```css
 ::root {
   --headerBackground: var(--darkBlue);

        --footerBackground: var(--headerBackground);
	--cardBackground: var(--headerBackground);
	--formInputBackground: var(--headerBackground);
	--blockquoteBackground: var(--headerBackground);
}
```

I can even do this. The footer, cards, form inputs, and blockquotes all match.


### How do you declare them?

BAD: 
```css
h1, h2, h3, h4, h5, h6 {
    font-family: 'Prata', serif;
    font-weight: 400;
	...
}

body {
    font-family: 'Preahvihear', sans-serif;
    line-height: 1.65;
	...
}

```
You declared your header/body CSS directly, starting off a pretty fragile design pattern. In the future, stakeholders want to switch out all the fonts, across multiple CSS files. It already sounds like a nightmare. 

GOOD: 
```css
::root {
    --headingFont: 'Prata', serif;
    --headingWeight: 400;
    --bodyFont: 'Preahvihear', sans-serif;
    --bodylineHeight: 1.65;
}  

h1, h2, h3, h4, h5, h6 {
    font-family: var(--headingFont);
    font-weight: var(--headingWeight);
	...
}

body {
    font-family: var(--bodyFont);
    line-height: var(--bodylineHeight);
	...
}

```

Let's go with another example: 

BAD 
```css
::root {
    --green: #b2c16c;
}

body {
	color: var(--green);
}

a {
	color: var(--green);
}

textarea {
	color: var(--green);
}
```

In that BAD example, the colors are being called directly. 

GOOD
```css
::root {
   /* Define colors as colors */
    --green: #b2c16c;
	
    /* Define color intentions*/
    --siteBackground: var(--green);
    --linkColor: var(--green);
	--formTextarea: var(--green);
}

body {
	color: var(--siteBackground);
}

a {
	color: var(--linkColor);
}

textarea {
	color: var(--formTextarea);
}
```

Congrats! You just made your CSS code anti-fragile! If you change the color intentions, you modify the rest of the design! 

## Stripey.CSS 

I built Stripey.css as a learning tool. I also went wild with design intentions, just to see how much I can change.

To make a new theme within stripey.css, you copy the `::root` into it's own class (like I did with `.theme1 .theme2 .theme3`) and swap variable choices on the click event. 

It's the absolute easiest way to make a dark mode, oled mode, floral mode, etc.

{% codepen https://codepen.io/rockykev/pen/bGEJyjm default-tab=css, result %}

## Questions

** 1. Are you declaring everything as a 'design intention'?**

It's a pick-and-choose battle. I still hardcode a lot of key elements, like padding or alignment. The goal is that you modify only a small subset of CSS variables to create a massive change. Each one of stripey.css' theme is roughly 100 lines of CSS (most is duplicated from the default!

** 2. Classless CSS? I need classes!**

Me too buddy! Classless CSS systems are just templates with another name. Build on top of them. 

** 3. Why stripey.css? There's no stripes.** 

My cat buddy Stripey died while I was going through the course. It's in honor of that little furball.

## Additional resources: 
* I used this site to pick out header/body fonts: [https://type-scale.com/](https://type-scale.com/)
* I used this site to create shades/tints of colors:  [https://www.cssfontstack.com/oldsites/hexcolortool/](https://www.cssfontstack.com/oldsites/hexcolortool/)
* This site was used as inspiration.[https://www.happyhues.co/](https://www.happyhues.co/)
* Finally, I borrowed (really stole) a lot of concepts from Tailwind CSS: [https://tailwindcss.com/docs/box-shadow/](https://tailwindcss.com/docs/box-shadow/)