Style Sheet Swag: architecting your applications styles
Aside from applying that killer layout and visual design to your project, stylesheets need to be organized in a way that effectively communicates markup and style relationships and allows for quick and easy modification. A good measure of a well architected front-end is how easy it is for a new team member to jump into your project or for a new team to it take over. If your methods for organization and selector naming aren’t consistent and easily communicated to or understood by others, you're probably creating a lot of code debt and certainly creating a higher than necessary barrier to entry for newcomers to the project.
This is how we do it.
Thanks to the partials feature in css preprocessors like Sass, less.js, and Stylus, we can organize our stylesheets better than ever before. We work with Sass because it comes built into rails and it’s awesome.
From the very start, all the apps we build come with a gem we built called Flutie. Flutie provides a stylesheet reset and most importantly, a method that adds a class name to the body element of every page. The body class name is made from the name of the controller and action responsible for generating that page. This allows us to target specific pages by using the unique body class and it also helps us semantically model our stylesheets directory after our views directory. So if we have a Clips controller with an Edit action and we have an associated view for that action called
views/clips/ then the body element in that view would get a class of
.clips clips-edit and in our stylesheets directory we should create a sass partial called
_clips_edit.scss, if we are going to be applying styles to that view. Instead of namespacing the .scss files you could group your style sheets in folders (ex:
clips/_edit.scss) the same way the rails views are organized. Organizing your styles in this way makes it much easier to find the styles you're looking for when working between the browser's inspector and your text editor.
Variables, Mixins, Extends, etc.
So what about all the variables, mixins, extends, and other great stuff you can do with Sass and most other preprocessors, where do they go? We have found that organizing our variables, extends, mixins, animations and general base styles (default styles for things like typography, links, etc) in partials to be very useful. These partials are usually namespaced with
_base or kept in a folder
base/. So in a typical project I will have
_base.scss, _base_variables.scss, _base_mixins.scss etc.
Often times we will build components of an application to be modular. So to keep the styles for these components modular as well, we create “shared” partials. If in your application you have a header component that maintains all or the majority of its styles across multiple views in your app, create a partial called
_shared_header.scss or put
_header.scss into a “shared” folder. If you have a view,
clips_index.html.erb for example, in your app that is sharing the header with another view (
clips_edit.html.erb lets say) but needs a slight tweak, target the header component in the
_clips_index.scss stylesheet partial and make the
clips_index.html.erb view specific tweaks there.
Generating the css
Now that we have our styles logically organized we create a file, often called
screen.scss, in which we import all of our partials with the
@import directive (ex:
@import “clips_edit.scss”;) to render the single stylesheet our app will use. The order in which you import these files is important as the import will render the contents of the imported files in the order they are imported and these are cascading styles sheets after all, so make sure you are importing your variables and base styles at the top.
As a consulting shop, one of our goals is to deliver clean code that our clients can continue to easily work with and grow after we are done working on the project. From the front-end perspective, an important piece of making that happen is keeping our markup and styles clearly organized by constantly using agreed upon methods. All code should look like it was written by one person, regardless of the actual number of contributors. Trying to work in a large application that has no clear reasoning for the structure of its front-end can feel like battling a kraken with a countless number of limbs. So even if you will be the only person ever working on a project, your future self will certainly appreciate the efforts you make now to keep your styles organized, modular and easily modified.