SCSS Code Organization and Abstraction

Phuse
Phuse
Published in
6 min readApr 15, 2013

A recent quest to come up with a definitive project template for organizing my .scss files led to a lot of thinking about how I approach coding designs, reading articles, trying out techniques, and reflecting on what actually makes the most sense for the kinds of projects I work on.

The result of my pondering and research ended up being both a template of .scss files that go into each project, and a concept for defining the elements that make up a web design. So here’s what I’ve come up with: it’s nothing revolutionary, but I like seeing how other developers do things, so maybe you will too!

Core Concept: Modules and Components

You hear a lot of developers talk about modules in all kinds of development. Modules are re-usable bits of something. In CSS, you might have a button module or a breadcrumb module, or anything that you might use multiple times within a site or app. Now, modules are great, and it’s always good to be as DRY as possible, but I’ve come to acknowledge that not everything is a reusable module, and if I start treating every element on my page as something I’m going to use again in another context, I’m usually just fooling myself and spending too much time trying to abstract something for the sake of abstracting.

I now recognize that the sites and apps I work on tend to comprise both modules and what I’m calling components. Components may not be the most accurate term here, but it’s what I’ve come up with. Components are all the bits that make up your web site or app that occur only once, or only in one context. Things like your page header or footer or sidebar. Sure, you could have multiple headers or sidebars or footers, but in a lot of cases, you know that you won’t. You might still have multiple instances of a component, but you’re only using it in the one context. If you need to use a component in more than one context, you should turn that into a module. I the main difference between a module and a component is context: a component is context-dependent, a module is not.

Markup

I’ve never been all that vigilant about commenting my code, but I’m really pushing myself to change that. Since I know I’ll have coworkers working on the same code that aren’t familiar with my little system, I know I have to make everything as clear as possible. I use a system of corresponding HTML and SCSS comments to make it clear to anyone reading the HTML where in the SCSS they can find those styles:

Designating a module in HTML: 
<!-- @module BUTTON -->
The corresponding module in SCSS:
/* -- @module BUTTON -- */
Designating a component in HTML:
<!-- @component PAGE HEADER -->
The corresponding component in SCSS:
/* -- @component PAGE HEADER -- */
File StructureI always have a main.scss file that imports all other scss files and compiles to main.css, the files I include are fairly consistent, but sometimes change a bit depending on the project:main.scss
|-- reset.scss
|-- vars.scss
|-- typography.scss
|-- utils.scss // includes all mixins and extensible placeholder styles
|-- base.scss // default styling for HTML elements
|-- layout.scss // grid and container styles
|-- modules.scss
|-- components.scss
|-- *responsive.scss // optional: if a larger site is responsive, I'll toss all my media queries in one place
The order here is important, both for css specificity reasons and scss inheritance reasons!

Example: Space Apps Toronto

The team at The Phuse is working on something pretty exciting this spring: we're helping organize a hackathon here in Toronto called the Toronto Space Apps Challenge, and my coworkers and I have been developing the event website.[caption id="attachment_2029" align="aligncenter" width="557"]
Props to my coworker Tom for the awesome design.
Props to my coworker Tom for the awesome design.[/caption]It's a fairly simple website in that it's only 3 pages, but there's a lot of content, a lot of images, and a somewhat unusual grid system going on (18-columns instead of the usual 12 or 16).Component: ScheduleTo illustrate my component/module distinction, I'll go over an example of each. In the ‘Schedule’ section of the Space Apps Toronto website, there are 3 schedule tables, one for each day of the hackathon.
Screen Shot 2013-04-06 at 6.06.40 PM
The .schedule-table element is repeated: there is one for each day, but it is context-specific: this layout is specific to displaying this kind of content. I could abstract this out to something more generic (and maybe later I will), but at this point that isn't necessary and makes the code harder to navigate.The code looks something like this:HTML<!-- @component SCHEDULE -->
<div class="schedule">
<div class="grid-6">
<h3>April 19<small>Friday</small></h3>
<table class="schedule-table">
<tbody>
<tr>
<th scope="row">6:00 pm</th>
<td>Registration opens</td>
</tr>
...
</tbody>
</table>
</div>
<div class="grid-6">
<h3>April 20<small>Saturday</small></h3>
<table class="schedule-table">
...
</table>
</div>
<div class="grid-6">
<h3>April 21<small>Sunday</small></h3>
<table class="schedule-table">
...
</table>
</div>
</div>

SCSS

/* -- @component SCHEDULE -- */.schedule {
margin-top: 60px;
h3 {
text-align: left;
}
}
.schedule-table {
width: 100%;
text-align: left;
th[scope="col"] {
border-bottom: 1px solid rgba(255,255,255,0.6);
padding-bottom: 10px;
color: #fff;
margin-bottom: 10px;
}
th {
width: 30%;
color: rgba(255,255,255, 0.5);
font-weight: 300;
}
td {
padding-top: 10px;
padding-bottom: 10px;
}
}
Module: CalloutOn the Space Apps website, I have several areas that are visually similar though semantically unrelated: the schedule for the pre-event party, the lists of media links on the press page, and the schedule for the NASA Youth Space Challenge page. This sounds like a good example of a module! I decided to call it 'callout' because it visually emphasizes the content inside it.
Screen Shot 2013-04-06 at 6.08.41 PM
The code looks pretty much the same as it does for a component, but it lives in a different file:

HTML

<!-- @module CALLOUT-->
<div class="callout">
<header>
<span class="number">APRIL 12</span>
<span class= "day">Friday</span>
<h3>Beer &amp; Post-its (pre-event party)</h3>
</header>
<div class="body">
...
</div>
</div>

CSS

/* -- @module CALLOUT -- */
.callout {
...
header {
.number {
...
}
.day {
...
}
h3 {
...
}
}
&.press {
...
}
}
On the Youth page, the schedule element is both a module and a component: It shares the callout styles with the press and pre-party schedule elements, but also has it's own context-specific styles associated with the schedule component. (I’m re-using the schedule element here, but it remains a component and not a module because the context is the same).<!-- @compontent SCHEDULE | @module CALLOUT -->
<div class="schedule callout">
</div>

Conclusion

I’m aware that this approach can seem backwards: treat elements as context-specific and abstract as needed, as opposed to abstracting everything and then adding specificity. I don’t have anything against the latter approach in theory, but in practice, I find I often end up with much messier code, because inevitably my re-usable modules need to be altered in one place but not another, a client or designer points out that actually those two elements should have different padding, or the text shouldn’t be bold in module instance #2, and suddenly the instances of my module are more different than they are similar, and at that point why even bother?Surprisingly, I’ve found it easier to abstract out a component into a module as needed than to add increasingly specific styles to each instance of a module as a design grows and changes, and it leaves me with modules that exist out of necessity, rather than just for the sake of abstraction.I’ve only been using this approach for 3-4 months, but it’s working well for me so far, and considering that after about a month of coding something I usually look at it and think it’s garbage, this is holding up fairly well. I’m always looking for ways to optimize my technique, and I’m currently experimenting with making heavier use of the Sass @extend function to create components as extensions of modules (but that’s another blog post...). I'm always looking for feedback with my coding techniques and methods, so feel free to leave your thoughts!

--

--

Phuse
Phuse
Editor for

Phuse is a remote-based design and development agency headquartered in Toronto. We craft websites, interfaces and brands.