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.
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 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
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)
- 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 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:
:root {
--black: #000000;
--background: var(--black);
}
body {
background: var(--background);
}
What you did here was:
- Declared a variable called
--black
. - Declared a variable called
--background
, and passed the--black
value to it. - 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
.paragraph {
font-size: var(--baseFontSize);
}
GOOD
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.
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):
Borrowed from the free Figma course
Some examples of Design Intentions:
::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.
::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:
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:
::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
::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
::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.
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/
- I used this site to create shades/tints of colors: https://www.cssfontstack.com/oldsites/hexcolortool/
- This site was used as inspiration.https://www.happyhues.co/
- Finally, I borrowed (really stole) a lot of concepts from Tailwind CSS: https://tailwindcss.com/docs/box-shadow/
Top comments (1)
This is nice, Thanks