Organizing Your CSS Code for Preprocessors

By Tim Severien

CSS preprocessors are probably one of the most useful things we have right now in front-end tooling. Whether you pick Sass, LESS or any other preprocessor, they’re great because they add so many features CSS never had. But I’m not trying to convince you use preprocessors, I assume you already do.

Instead, what we’re going to do is explore some different architectures you can use with your chosen preprocessor to help you find the one that suits you best. Even though the files are all listed as Sass files (i.e. scss), all the architectures can easily be adopted regardless of your preprocessor of choice.

Architectures?

One of the best features of a CSS preprocessor, file inclusion, allows us to distribute the code over multiple files. These files are later concatenated by the preprocessor. This allows us to have multiple files without bothering the browser with a long list of HTTP requests.

At first, you may be filled with excitement over this capability. That is, until you start using it on a large project. That’s where, if you’re like me, you’re stylesheet has become a distributed mess. In my case, I really needed a structure and a way to organize my code.

What options do we have? CSS is hardly programming, but we can’t blatantly copy a programming architecture. But how do you categorize the different portions of your styling? Pack your bags and put on your work shoes, it’s exploring time — Dora style (by that I mean sitting back and letting me do all the hard work).

As a note, I’m going to start all the architectures that I’ve personally defined with a folder called ‘base’, where I will put things you shouldn’t touch like resets and styles for included libraries.

Functional Distribution

This is a structure that you may end up with when initially starting with a preprocessor. Splitting functionality in separate files is actually a very logical thing to do. One for all variables, one for all mixins, etc. and finally one for the actual stylesheets. Let’s add a normalize.scss for the sake of realism.

  • /base
    • _normalize.scss
  • _mixins.scss
  • _variables.scss
  • screen.scss

Pros

  • A beautiful list of mixins and variables — yay!

Cons

  • All the styles are in a single file.

Conclusion

Okay, this is no good. We’ll end up with a massive script. We might as well not use a preprocessor at all. This is pretty useful combined with the other architectures though. In fact, we’ll do that. But just this? Not a good idea.

Katana Distribution

What if we divide our pages up in pieces, and style each part individually?

  • /base
    • _normalize.scss
  • /sections
    • _header.scss
    • _content.scss
    • _footer.scss
    • _sidebar.scss
    • _modals.scss
  • _mixins.scss
  • _variables.scss
  • screen.scss

Pros

  • Makes perfect sense
  • Unlikely to have double selectors

Cons

  • Can get messy, especially if you have many different appearances
  • Scripts can get pretty large, _content.scss in particular

Conclusion

Unfortunately, by using a structure like this, you’re motivating yourself to target styles to specific areas only, resulting in static CSS and a lot of double properties (eg. border-radius). You can avoid that a little using mixins and variables. However, this could be considered a valid structure for small and medium-sized projects.

Template or Page Distribution

By writing a different stylesheet for every template or page, it’s easy to look something up if naming is similar.

  • /base
    • _normalize.scss
  • /templates
    • _category.scss
    • _footer.scss
    • _header.scss
    • _index.scss
    • _page.scss
    • _single.scss
  • /pages
    • _home.scss
    • _about.scss
  • _mixins.scss
  • _variables.scss
  • screen.scss

You may note that the template names look very WordPress-like. I did that on purpose.

Pros

  • Well distributed
  • Easy to look up
  • Per template customization

Cons

  • We’re aiming for pretty specific elements again

Conclusion

This is another acceptable candidate for certan projects. In fact, this and previous architecture make a great couple, which could work nicely. This could work great on many medium to large-sized projects.

Design Terminology

I heard Chris Coyier describe his architecture in the screencast ‘A Modern Web Designer’s Workflow‘. As the title suggests, it’s for Web designers, meaning that it will feel comfortable for people familiar with design and it’s jargon.

What Chris doesn’t do is use folders, but they may be unecessary.

  • _normalize.scss
  • _buttons.scss
  • _footer.scss
  • _grid.scss
  • _header.scss
  • _icons.scss
  • _navigation.scss
  • _typography.scss
  • screen.scss

Pros

  • Makes sense (for designers)

Cons

  • Confusing for non-designers
  • Pretty messy
  • Can get duplicate selectors

Conclusion

I should mention that the list of files that Chris originally showed had triple the amount of files listed above. However this is a workable architecture. In fact, I usd it for quite a while.

The Hugo Cocktail

Earlier this year, Hugo Giraudel wrote a post about his Sass architecture. It turns out that it’s a mixture of everything we’ve discussed above – all of it.

  • /base
    • _normalize.scss
    • _typography.scss
  • /components
    • _buttons.scss
    • _navigation.scss
  • /helpers
    • _mixins.scss
    • _variables.scss
  • /layout
    • _grid.scss
    • _header.scss
    • _footer.scss
  • /pages
    • _home.scss
    • _contact.scss
  • /themes
    • _theme.scss
    • _admin.scss
  • /vendors
    • _bootstrap.scss
    • _jquery-ui.scss
  • main.scss

Pros

  • Small files
  • Looks organized

Cons

  • Too many files and directories

Conclusion

This structure can work well for large projects. As I mentioned earlier, tt’s takes almost everything what we’ve discussed and mixes it into one architecture. Personally, I sometimes find this structure to be a little overkill. On the other hand, I don’t work on many large-scaleprojects.

A last word

These are merely examples of architectures. I have yet to discover the ‘perfect’ one, if one exists. Even if it does, it is a personal preference anyway. Either way, it’s an important matter to think about thoroughly. If you can avoid creating a mess, especially up-front when you are creating a new project, you should.

Previous

ECMAScript 6: Jump in, the water is warm!

MEAN Stack – A Quick Start Guide

Next

16 thoughts on “Organizing Your CSS Code for Preprocessors”

  1. I’m rather software programmer than CSS writer, and I’m wondering what are the benefits of using many files if they are small in size… When I’m programming I can easily find myself in 5k file. Isn’t that true for CSS?

    • Because programming languages are more complex than CSS syntax, CSS is easier to read, but it’s harder to recognize two different blocks of code. Two blocks can look awfully alike, so there are little to no reference points.

      What CSS really needed is manageable code. In programming you put relevant code into files, like in object-oriented programming and when you’re using libraries.

      So we’re not splitting the stylesheet based on file length, but rather relevancy, just like you would in programming.

  2. I like the SMACSS approach. Snook has an article on applying SMACSS to preprocessors. It’s similar to the Hugo Cocktail you mentioned but it seems like the organizing principles behind SMACSS are much stronger. (Depth of Applicability, Modules, States, etc…)

    If you haven’t read SMACSS I highly recommend it. https://smacss.com/

    Sample Directory Structure
    +-layout/
    | +-grid.scss
    | +-alternate.scss
    +-module/
    | +-callout.scss
    | +-bookmarks.scss
    | +-btn.scss
    | +-btn-compose.scss
    +-base.scss
    +-states.scss
    +-site-settings.scss
    +-mixins.scss

    Master file
    @import
    “site-settings”,
    “mixins”,
    “base”,
    “states”,
    “layout/grid”,
    “module/btn”,
    “module/bookmarks”,
    “module/callout”;

    • +1

      Organization & consistency in SMACSS make it very useful in large (and small) projects, especially when there are multiple front-enders involved.

  3. I lean towards the first basically. My biggest reason is I can import the separate sheets into a separate “old IE” master sheet that does not contain media queries so as to deliver a desktop only layout to these old browsers.

  4. I like distributing folders as much I like distributing files. I don’t have any specific rules, but I create structure that I feel I can benefit most in project I’m working on. Often I have similar structures. Thought I share a structure from one of the project:

    ├── application.css.sass // File without any styles, just requires other files in order I need.
    ├── overrides
    │   ├── _base.css.sass
    │   ├── _date_picker.css.sass // Override some styles from date picker from jQuieryUI
    │   └── _media.css.sass // Query media
    ├── pages
    │   ├── _base.css.sass // Quite large file with common code for all pages. h1, a, p and so on
    │   └── _home.css.sass // Overrides pages/_base.css.sass
    ├── partials // Some people call it sections or components.
    │   ├── _alerts.css.sass // Styles list of alert types
    │   ├── _carousel.css.sass // Just one carousel
    │   ├── _forms.css.sass
    │   ├── _header.css.sass
    │   ├── _modals.css.sass
    │   ├── _pagination.css.sass
    │   ├── _user_access_log.css.sass
    │   ├── _user_lists.css.sass
    │   └── _ajax_loader.css.sass
    ├── settings
    │   ├── _base.css.sass // Small file with all basic variables. I try to use as little variables in sass as I can.
    │   ├── _mixins.css.sass // Small file too.
    │   └── _sprites.css.sass
    └── vendor
    └── jquery-ui-1.10.4.custom.css.scss // Originally it wasn’t scss, I just added scss so I can require it in application.css.sas

  5. Im just getting to grips with SASS on a clients Magento project as the framework we are using on it utilise the pre processor, so far it makes sense and has made the project a lot easier, but dont know as if I would use pre processors in other smaller projects moving forward.

  6. Good topic that doesn’t get enough coverage. I don’t get the ‘too many files’ argument from a complexity point of view. Any good text editor has a shortcut for fuzzy search so it’s not like you need to wade through folders and files to open something (though if your mind is blank files and folders are a great way of reminding yourself of relationships). There is a definite argument against lots and lots of files from a processing speed point of view, but I’d take the hit there over poor file organisation any day.

Comments are closed.