How to Write Beautiful Sass
The following is a short extract from our book, Jump Start Sass, written by Hugo Giraudel and Miriam Suzanne. It’s the ultimate beginner’s guide to Sass. SitePoint Premium members get access with their membership, or you can buy a copy in stores worldwide.
Clean, beautiful code should be a goal in every project. If other developers need to make a change, they should be able to read what is there and understand it. Readable code is the core of maintainability, and the first step towards readable code is a good linter. Like a good spell-checker, the linter should catch all your small typos and formatting mistakes, so it’s not left to others to do so. It’s the first line of defense before a good code review with other developers.
There are several great linters for Sass: scss-lint is a Ruby gem, and the newer sasslint and stylelint, which are npm packages for Node. Both allow you to configure linting rules for your project, such as maximum nesting levels, leading zeros on decimals, and organization of properties in a block. You can even create your own rules as needed.
Sass Guidelines are handy for organizing your project, setting up your linters, establishing naming conventions, and so on. Written by Hugo, it’s an opinionated styleguide for your code; it might not all work for you, but it’s a great place to start.
If you’re using Sass variables, functions, and mixins, it’s recommended that you document how they work. Toolkit authors will find it particularly important, but anyone who has extensive tooling built into their projects should also consider documentation for their team. Another great tool from Hugo is SassDoc, an npm package that parses your Sass comments and generates a beautiful static site with your documentation.
Here’s the SassDoc comment for our tint(..)
function in Accoutrement-Colors. It starts with a general description, and then explicitly documents each parameter and the expected return:
/// Mix a color with `white` to get a lighter tint.
///
/// @param {String | list} $color -
/// The name of a color in your palette,
/// with optional adjustments in the form of `(<function-name>:<args>)`.
/// @param {Percentage} $percentage -
/// The percentage of white to mix in.
/// Higher percentages will result in a lighter tint.
///
/// @return {Color} -
/// A calculated css-ready color-value based on your global color palette.
@function tint(
$color,
$percentage
) {
/* … */
}
Using the default theme (from which there are several to choose, or you can design your own), SassDoc converts that comment into a static website, as shown below.
Testing is also important if you are doing anything complex with functions or mixins. It’s a good way to ensure your code won’t break any time you make adjustments, but it can also be helpful in developing new features. If you write the tests first, you’ll know exactly if the feature works correctly when your tests pass!
True is a unit-testing toolkit from yours truly, written in pure Sass so that it works anywhere Sass is compiled. The core testing happens in assertion functions: assert-equal(..)
, assert-unequal(..)
, assert-true(..)
, and assert-false(..)
. These are organized into tests, and can be grouped in test modules. Here’s an example of True testing our
tint(..)
function:
@include test-module('Tint [function]') {
@include test('Adjusts the tint of a color') {
@include assert-equal(
tint('primary', 25%),
mix(#fff, color('primary'), 25%),
'Returns a color mixed with white at a given weight.');
}
}
When compiled, True will output CSS comments with detailed results, and warn you in the console if any tests fail:
/* # Module: Tint [function] */ /* ------------------------- */ /* Test: Adjusts the tint of a color */ /* ✔ Returns a color mixed with white at a given weight. */ /* … */ /* # SUMMARY ---------- */ /* 16 Tests: */ /* - 14 Passed */ /* - 0 Failed */ /* - 2 Output to CSS */ /* -------------------- */
What does it mean that two tests were “output to CSS” in this example? Those tests aren’t shown, but they are testing mixin output. Using pure CSS, True can only confirm the results of function tests, so mixin tests are simply output to the CSS where they can be compared manually (gross) or with a CSS parser (better!). To make that easy, True integrates with JavaScript test runners such as Mocha, and has a Ruby command line interface written by Scott Davis. Either one will parse the CSS output completely, including the output from mixins, and give you full results for both function and mixin tests:
Luminance [function] ✓ Returns luminance of a color Contrast Ratio [function] ✓ Returns contrast ratio between two colors Contrast [function] ✓ Dark on light ✓ Light on dark ✓ Default light fallback ✓ Default dark fallback ✓ Multiple contrast options contrasted [mixin] ✓ Dark on light ✓ Light on dark Tint [function] ✓ Adjusts the tint of a color Shade [function] ✓ Adjusts the shade of a color Color [function] ✓ Named color ✓ Referenced color ✓ Adjusted color ✓ Complex nesting of colors ✓ Multiple adjustment function arguments 16 passing (11ms)