Recently companies have been sharing their process for CSS, and I thought I’d talk about CSS on Noodles. Note that all of this is about the app, not the homepage — those are two separate projects.
- Overview of the CSS
- Preprocessor and Libraries
Overview of the CSS
- SCSS to make my life easier
- Formatting generally follows GitHub's CSS Styleguide and @mdo’s Code Guide for CSS. Single dashes, plenty of spaces, mostly classes.
- No styleguide
- 17 stylesheets in total, concatenated then served as one
application.cssweighs in at around 11kb. There are roughly 250 selectors, according to cssstats.com, and 360 declarations.
- My main rule for writing code: keep it simple.
Preprocessor and Libraries
As I mentioned, Noodles uses SCSS. I’m using only basic features (nesting, variables for colors, fonts, and sizes, extends, and a few mixins), but it makes me more productive and promotes consistency in design.
As far as libraries go, I’m using Bourbon in a few places. I love the syntax of Bourbon, and it avoids the nasty vendor prefixes of flexbox —
@include display(flex) and
@include justify-content(space-between) are so simple. And unlike most libraries, Bourbon doesn’t add anything to the CSS until it’s used. I keep a few classes such as
.flex-between to restrict the regurgitation inside my CSS.
Beyond Bourbon, I am using Autoprefixer to make my life easier. Add the gem and you'll never have to think about it. Vendor prefixes are just taken care of.
Basscss is terrific for some projects, though including the whole library is a lot of bloat. Instead, I wrote a few helper classes such as
.text-center. No bloat, but all the benefits.
There are 18 stylesheets (listed below), but SCSS
@imports concatenate them before serving as one
cook.css are compiled separately from
application.css by Sprockets. This minimizes weight and allows for more styling that doesn't slow the entire app down.
Here’s the file tree:
app/assets/stylesheets/ ├── _mixins.scss ├── _variables.scss ├── application.scss ├── cook.scss ├── editor.scss ├── base │ ├── base.scss │ ├── grid.scss │ ├── printer.scss │ └── type.scss └── modules ├── bio.scss ├── buttons.scss ├── flash.scss ├── forms.scss ├── modals.scss ├── nav.scss ├── recipe-list.scss ├── recipe.scss ├── tabs.scss
Files are imported alphabetically for the sake of code organization. You must import variables and mixins before files using them, so alphabetization in import list => import zen.
Linting the SCSS is incredibly informal. After making any substantial changes, I manually run
scss-lint from my terminal to check for issues. The frequent error pages from Better Errors resolve all syntax issues in advance, so linting just leads to better code.
Similar to many websites, I have all the CSS (and images/JS as well) delivered by a CDN. For Noodles, I use Amazon CloudFront. For every 1 page request that hits Heroku, this saves about 4 more from hitting the app server for assets (icons, stylesheets, JS). I pay about 12¢/month for CloudFront, and at scale it could easily save you a lot of money on Heroku.
If you're curious, here's how to set it up in Rails:
config.action_controller.asset_host = "assets.getnoodl.es"
Then, set a new CloudFront distribution to the root of the site (the CF DNS). There's no complex configuration here, just type in the domain.
When you push to Heroku, the assets are precompiled, fingerprinted, pushed to CloudFront, and asset links point to
I don't worry a ton about the performance of the CSS itself, but instead minimize the weight of the file. Compared to most websites, Noodles has very little CSS — and there are several "pure CSS" components such as tabs (which I open-sourced).
There are a few tag selectors as well, which I should clean up. But in general, I don't have much code debt and it gets cleaned up fairly regularly.
So that’s a “detailed overview” of CSS on Noodles! Ask questions in the comments below, and if you haven’t, check out Noodles.
And make sure to enjoy the holidays! Family > CSS :)