How I Structure My CSS (for Now)

When it comes to structuring CSS, there is no shortage of different naming conventions, methodologies, and architectures. Be it BEM, OOCSS, SMACSS, ITCSS, or CUBE CSS – over the last years, many different approaches to managing modular CSS have emerged. Some are offering strategies on how to split CSS into smaller, more manageable pieces, while others focus more on naming conventions for classes. Sometimes, it can be hard to grasp where the differences or advantages of certain methodologies lie, yet in the end, they all aim at the same: Providing structure and consistency, also known as “avoiding a mess”, when you are working in a team or with your present and future self.

No wonder there isn’t a new project where I don’t start to think about the structure of my CSS a bit and, over time, the way I organize and write CSS has changed a lot. The biggest change came when we all started to write CSS for components. But also preprocessors like Sass have clearly left their mark.

In this post, I will share my current take on CSS structure. It does not religiously follow any particular methodology, although people familiar with Harry Roberts’ ITCSS (“Inverted Triangle CSS”) will definitely recognize parts of his methodology. If you haven’t yet looked at ITCSS, I highly recommend it. What I like most, is the pragmatic, real-life approach and the principle of structuring your CSS in a way that gets ever more specific and explicit the farther down you go in the structure. This allows you to focus on the high-level styles first and makes it easier to deal with the cascade, inheritance, and selector specificity while keeping the number of classes – and the specificity! – as low as possible. There are, however, a few differences, and this is also what I’d suggest to anyone setting up their own structure: Take any methodology with a grain of salt and freely adjust it to your needs and the way you work.

The Folder Structure

This is how my folder structure currently looks like:


/scss/
├── 1-settings
├── 2-design-tokens
├── 3-tools
├── 4-generic
├── 5-elements
├── 6-skeleton
├── 7-components
├── 8-utilities
├── _shame.scss
└── main.scss

Let’s break it down a bit.

Settings

The first folder, 1-settings, is for all general project settings, so for the most basic high-level configuration. This might be a collection of global variables – either as Sass variables or custom properties.


├── 1-settings
│   └── _global.scss

Design Tokens

The second folder is for all styles regarding the visual vocabulary of the site. At this level, we are still not generating any CSS output. It is where we define variables for the typography, colors, spacing, media-queries, or any other attributes which you will use throughout the design. For these visual design attributes, the term design tokens has taken hold. Those design tokens could even be coming from your design system as a single source of truth.


├── 2-design-tokens
│   ├── _colors.scss
│   ├── _fonts.scss
│   ├── _media-queries.scss
│   ├── _spacing.scss
│   └── _typography.scss

Tools

The tools folder is where your global Sass mixins and functions live. Maybe you want to manipulate colors with blend modes or set the aspect ratio for a video container? Or clear your float, for example. I am not a heavy user of mixins myself, but I know many people who love them, so this is where to put them.


├── 3-tools
│   ├── _aspect-ratio.scss
│   ├── _blend-modes.scss
│   ├── _center.scss
│   ├── _clearfix.scss
│   └── _gradients.scss

Generic

Just like in ITCSS, the generic folder is the first one that actually produces CSS. It contains global box-sizing rules, CSS resets, or print styles – anything that should be set right at the beginning of your CSS but isn’t yet project-specific.


├── 4-generic
│   ├── _box-sizing.scss
│   ├── _font-face.scss
│   ├── _normalize.scss
│   └── _print.scss

Elements

Now that the most basic things are set up, we can start to style the building blocks of our front-end: Raw HTML Elements. Mostly without classes, we are now redefining the basic browser styles of headlines, buttons, links, lists, etc. and can make sure that all components in our design are using the same consistent base.


├── 5-elements
│   ├── _forms.scss
│   ├── _headings.scss
│   ├── _images.scss
│   ├── _links.scss
│   └── _lists.scss
│   ├── ...

Skeleton

Any modern web project that is built with components also comes with the need for a higher-level structure in which all the components can live: Wrappers, containers, grids, and all kinds of reusable objects that provide layout patterns. This is the skeleton of your site.


├── 6-skeleton
│   ├── _grid.scss
│   ├── _layouts.scss
│   └── _objects.scss

Components

The beating heart of the project. This is where we design the components of the UI. In a few recent projects, I sometimes distinguished between larger modules and smaller components, but you can also nest components into each other and do without the additional distinction. Use prefixes, if you like, and also a naming convention like BEM can make a lot of sense. I have recently settled on a BEM-like but more simplified naming convention: Just use the simplest but most descriptive class name possible and separate elements within other elements with a simple dash, like .card and .card-content. Sometimes – for example, when I work with Fractal – the CSS for individual components might also live in another folder, together with the HTML and JavaScript code. In this case, the components folder might be empty, or contain references via @import.


├── 7-components
│   ├── _accordion.scss
│   ├── _card.scss
│   ├── _hero.scss
│   ├── _pan-galactic-gargle-blaster.scss
│   └── ...

Utilities

Another folder? Yes, but this is definitely the last one. The utilities folder contains utility and helper classes and, most importantly, states and modifiers like .is-active or .visually-hidden. Those styles override the styles in the previous layers and are often set via JavaScript. I really like the suggestion by Andy Bell in his CUBE CSS methodology to use data-attributes to change the state of components, which is also useful in terms of the higher specificity.


├── 8-utilities
│   ├── _modifiers.scss
│   └── _states.scss

_shame.scss

This file, which is another idea by Harry Roberts, is a place for all the shameful CSS solutions like quick fixes and hacky things that might solve a problem for the time being but should be solved properly later. Make sure to document all those nasty hacks with comments, though: Why did you solve it this way? Do you already have an idea on how to solve it better? What is needed to solve it? And so on…

Putting it all together

Finally, the main.scss file is where all the individual files are combined. I prefer to explicitly import each file in a new line instead of importing whole folders because I have more control over the source order. But this is only my personal preference, of course.


@charset "UTF-8";

// 1. Settings
@import 
	"1-settings/global";
  
// 2. Design Tokens
@import
  "2-design-tokens/colors",
  "2-design-tokens/fonts",
  "2-design-tokens/media-queries",
  "2-design-tokens/spacing",
  "2-design-tokens/typography";
...

And that’s it. A structure like this has served me well in recent projects because it keeps everything tidy. The resulting CSS is also much cleaner and it is easier to find the right piece of code when you have to make changes or do bugfixes.

I asked on Twitter the other day which CSS methodology you all prefer and the results were, as was to be expected, mixed:

People all like to use their own flavor of CSS, which is great. If you use a methodology or folder structure that you would like to share, write a post about it and I’ll happily link to it here. It would be interesting to see how you structure your CSS.

For future reference, here’s the whole folder structure again:


/scss/
├── 1-settings
│   └── _global.scss
├── 2-design-tokens
│   ├── _colors.scss
│   ├── _fonts.scss
│   ├── _media-queries.scss
│   ├── _spacing.scss
│   └── _typography.scss
├── 3-tools
│   ├── _aspect-ratio.scss
│   ├── _blend-modes.scss
│   ├── _center.scss
│   ├── _clearfix.scss
│   └── _gradients.scss
├── 4-generic
│   ├── _box-sizing.scss
│   ├── _font-face.scss
│   ├── _normalize.scss
│   └── _print.scss
├── 5-elements
│   ├── _forms.scss
│   ├── _headings.scss
│   ├── _images.scss
│   ├── _links.scss
│   ├── _lists.scss
│   └── ...
├── 6-skeleton
│   ├── _grid.scss
│   ├── _layouts.scss
│   └── _objects.scss
├── 7-components
│   ├── _accordion.scss
│   ├── _card.scss
│   ├── _hero.scss
│   ├── _pan-galactic-gargle-blaster.scss
│   └── ...
├── 8-utilities
│   ├── _modifiers.scss
│   └── _states.scss
├── _shame.scss
└── main.scss


-

This is the 51st post of my 100 days of writing series. You can find a list of all posts here.

~

68 Webmentions

Photo of Matthias Ott
Matthias Ott
Thank you! :) That idea is actually by @csswizardry. I added the info + link to the article.
Photo of ng-gunma
ng-gunma
How I Structure My CSS (for Now) · Matthias Ott – User Experience Designer matthiasott.com/notes/how-i-st…
Photo of Emanuel Saramago
Emanuel Saramago
How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of Pietro Grandi
Pietro Grandi
How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of lvdesign
lvdesign
Splendide demonstration de DRY appliqué aux fichiers CSS 👏;😎;--> How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of Craig Buckler
Craig Buckler
How I Structure My #CSS (for Now), by @m_ott: matthiasott.com/notes/how-i-st… That's my general approach, although Matthias is more structured. The shame file is a great idea!
Photo of Dennis Erdmann
Dennis Erdmann
Du planst dir ein eigenes (CSS-)Framework aufzubauen (so wie wir mit dem Nutshell Framework)? In diesem Artikel gibt es ein paar Anregungen, wie du die Dateien strukturieren könntest matthiasott.com/notes/how-i-st… #css
Photo of Jeff
Jeff
This is great and makes a lot of sense!
Photo of tyankatsu
tyankatsu
こ;れ;が;俺;の;ITCSSだ;!;な;や;つ;だ; matthiasott.com/notes/how-i-st…
Photo of Square Balloon
Square Balloon
This is a neat way of organising your SCSS matthiasott.com/notes/how-i-st…. Having had many a discussion with @BarclayWorks I think some of my thinking is in here. What do you make of it @intergenr8r ? #scss #designsystems #css #design #webdevelopment #webdev
Photo of Angus McIntyre
Angus McIntyre
@m_ott Your tips on structuring CSS at matthiasott.com/notes/how-i-st… are very useful & clear. Thanks! One minor issue: the example ‘main.scss’ shows subdirectories without prefixed numbers, i.e. ‘design-tokens/’ rather than ‘2-design-tokens/’, so I don’t think it works as written.
Photo of Raul Mena Montes
Raul Mena Montes
How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of Mathieu BZ
Mathieu BZ
How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of Saabbir Hossain
Saabbir Hossain
How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of Master Owl ????;
Master Owl ????;
In this article, @m_ott shares his nicely structured, well-thought-out way of organizing stylesheets in his projects. _shame.scss made me laugh. 😂;matthiasott.com/notes/how-i-st…
Photo of Pascal
Pascal
How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st… #css #scss #structure
Photo of Alejandro Barba
Alejandro Barba
How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of visioncan
visioncan
How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of jamescalvinIV #BlackLivesMatter
jamescalvinIV #BlackLivesMatter
I'm a huge fan of knowing how others structure their applications, especially styles. I thought this was a good explanation. How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of Speckyboy
Speckyboy
How @m_ott Structures CSS (for Now) matthiasott.com/notes/how-i-st…
Photo of ????; Satoshi Takeda
????; Satoshi Takeda
_shame.scss が;あ;る;の;い;い;ね;。;scss し;ば;ら;く;作;っ;て;な;い;け;ど;、;負;債;の;集;約;こ;う;や;っ;て;作;っ;て;た;の;思;い;出;し;た; matthiasott.com/notes/how-i-st…
Photo of tixiE
tixiE
A great post, i even learn some useful ideas! How I Structure My CSS (for Now) matthiasott.com/notes/how-i-st…
Photo of Frank Seno
Frank Seno
How I Structure My CSS (for Now) · matthiasott.com/notes/how-i-st…
Photo of Frontend Daily
Frontend Daily
How I Structure My CSS (For Now): matthiasott.com/notes/how-i-st…
Photo of Artesis ????;????;
Artesis ????;????;
How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of Wayne Green
Wayne Green
How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of CSS Basics
CSS Basics
How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of Front-End Front
Front-End Front
How I Structure My CSS (for Now) matthiasott.com/notes/how-i-st…
Photo of Gary Stevens
Gary Stevens
frontendfront: How I Structure My CSS (for Now) matthiasott.com/notes/how-i-st…
Photo of Geoffrey Crofte ????;
Geoffrey Crofte ????;
"How I Structure My CSS (for Now)" matthiasott.com/notes/how-i-st… I do like the fact that ITCSS has a name. I work like that for several years now and to me it's the right way to structure it because of the way CSS intrinsically works (cascade and inheritance).
Photo of black Funshine
black Funshine
interesting . . . always looking for ways to improve my setup, I could see giving this a whirl! How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
Photo of Shubham Verma
Shubham Verma
If anyone interested how to structure there css project. I found this blog very useful. Like the idea of `shame` css. It definitely help you in scaling your css as well. #freeCodeCamp #100DaysOfCode #CSS #CodeNewbie matthiasott.com/notes/how-i-st…
Photo of Joulse
Joulse
How I Structure My CSS (for Now) matthiasott.com/notes/how-i-st…
Photo of Kav
Kav
How I Structure My CSS (for Now) · Matthias Ott – User Experience Designer matthiasott.com/notes/how-i-st… #CSS
Photo of Mazik Solutions
Mazik Solutions
How I Structure My CSS (for Now) matthiasott.com/notes/how-i-st…

Likes

Reposts