How I Struc­ture 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
│   ├── _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.

~

106 Webmentions

  1. @matthiasott Thanks for sharing. Never thought about more folders than „components“. Some time ago people already gave me strange looks for splitting my CSS in a lot of files but after seeing your setup and all those folders I feel better 😅 I was always struggling between „everything gets its own file“ and put it all in 3 CSS files. Nowadays I mostly use TailwindCSS so I don’t have to think about it ...
  2. @matthiasott clearfix? Really? Ok, here is a now useless secret in case you still need layouts with float somewhere: display: block; overflow: hidden; position: relative; on the parent. In case it’s ie10 you need to add a width as well.
  3. @matthiasott also, here’s sort of my version of this from earlier this year. I don’t know that my setup is rock solid but it was fun to research and explore it. What I think has been telling is that I didn’t touch my personal site for about 6 months and coming back to it didn’t take too much time to get reacquainted. https://wbrowar.com/article/code/css-for-me-in-2023 CSS for Me, in 2023
  4. @wbrowar Yes, that’s one thing that I might change going forward. The _globals file was meant to be for fundamental settings that don’t necessarily are design tokens or are deriving from design decisions. But I’m practice, globals was mostly empty in all my projects 😄. When I wrote the article in 2020, I was still using Sass in my projects. These days, it is very often vanilla CSS with Custom Properties. ...
  5. @matthiasott I really liked reading about your approach and how you divvied up different parts for different purposes. One thing I’m wondering about is the order between Globals and Design Tokens. Are the things in these folders rendered or because of SASS are they all stored as SASS variables and used in later imports? I think I’m curious to know what one of the design token files looks like as well as that ...
  6. @phillip Oh, that looks much better than the huge preview in Ivory 😅
  7. @matthiasott as a marketing Heini: might get you more clicks tho 😂
  8. @matthiasott I love shame.scss where all the !importants dwell that keep us from needing a doctor 🤗
  9. “How I Structure My CSS (for Now) · Matthias Ott – User Experience Designer” Is ITCSS the most influential CSS strategy that nobody really talks about? See it’s influence almost everywhere these days. matthiasott.com/notes/how-i-st…
  10. An example of how to structure CSS matthiasott.com/notes/how-i-st…
  11. A lot of folders, but when it comes to sass structure I've often found breaking down more to be useful. I really like the idea of this structure - matthiasott.com/notes/how-i-st… I like the idea of taking preferred aspects from different methodologies to produce something that suits you
  12. How do you structure and organize your CSS these days? SMACSS, Atomic CSS, BEM, OOCSS, ITCSS, CUBE CSS? What worked for you, and what didn't? (matthiasott.com/notes/how-i-st…)
  13. How I Structure My CSS (for Now) · Matthias Ott – User Experience Designer matthiasott.com/notes/how-i-st… #CSS
  14. How I Structure My CSS (for Now) matthiasott.com/notes/how-i-st…
  15. 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…
  16. 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…
  17. "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).
  18. I loved the way @m_ott showed how he is structuring his CSS, I already started to make a similar but smaller structure this year. I'll definitely have great inspiration to build my next CSS structure from this post. Thanks Matthias! matthiasott.com/notes/how-i-st…
  19. frontendfront: How I Structure My CSS (for Now) matthiasott.com/notes/how-i-st…
  20. How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
  21. How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
  22. How I Structure My CSS (for Now) · matthiasott.com/notes/how-i-st…
  23. A great post, i even learn some useful ideas! How I Structure My CSS (for Now) matthiasott.com/notes/how-i-st…
  24. _shame.scss が;あ;る;の;い;い;ね;。;scss し;ば;ら;く;作;っ;て;な;い;け;ど;、;負;債;の;集;約;こ;う;や;っ;て;作;っ;て;た;の;思;い;出;し;た; matthiasott.com/notes/how-i-st…
  25. How @m_ott Structures CSS (for Now) matthiasott.com/notes/how-i-st…
  26. 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…
  27. How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
  28. How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
  29. How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st… #css #scss #structure
  30. 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…
  31. How I Structure My #CSS (for Now) matthiasott.com/notes/how-i-st…
  32. How I Structure My CSS (for Now) matthiasott.com/notes/how-i-st… #CSS #FrontEnd #FrontEndDevelopment #webdev
  33. 📝 How I Structure My CSS (for Now) 🔗 matthiasott.com/notes/how-i-st… #html #css #javascript #webdev #dailydevlinks
  34. How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
  35. How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
  36. How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
  37. @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.
  38. 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
  39. How I Structure My CSS (for Now)matthiasott.com/notes/how-i-st…
  40. こ;れ;が;俺;の;ITCSSだ;!;な;や;つ;だ; matthiasott.com/notes/how-i-st…
  41. Thanks for sharing, Marc! Glad you found it interesting. 🤗
  42. How I Structure My CSS (for Now) · Matthias Ott – User Experience Designer matthiasott.com/notes/how-i-st…
  43. This is great and makes a lot of sense!
  44. 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
  45. 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!
  46. Splendide demonstration de DRY appliqué aux fichiers CSS 👏😎--> How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
  47. How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
  48. How I Structure My CSS (for Now), by @m_ott matthiasott.com/notes/how-i-st…
  49. How I Structure My CSS (for Now) · Matthias Ott – User Experience Designer matthiasott.com/notes/how-i-st…
  50. Thank you! :) That idea is actually by @csswizardry. I added the info + link to the article.

4 Reposts

ⓘ Webmentions are a way to notify other websites when you link to them, and to receive notifications when others link to you. Learn more about Webmentions.