20 Inspirational, Free Tools For Better Typeface Pairing
Five Ways to Hide Elements in CSS
Introducing the CSS clip-path Property
Inline CSS in Jekyll
Jump Start Sass: Architecture in Sass
The following is a short extract from our recent book, Jump Start Sass, available for free to SitePoint Premium members. Print copies are sold in stores worldwide, or you can order them here. We hope you enjoy this extract and find it useful.
Architecture has always been one of the major pain points in CSS development. Without any variables, control directives, macros, or object inheritance, CSS code tends to be long and repetitive—a single ever-growing file. While it’s technically possible to split plain CSS into multiple files that reference each other with
@import, the additional HTTP requests make that a poor solution. As you’ve seen, Sass has an answer for every piece of the architecture puzzle—but what’s the best way to put it all together?
Ask ten experts, and you’ll receive ten different answers—most of them involving (or aided by) Sass. OOCSS, SMACSS, Atomic Design, ITCSS, and BEM are all popular systems for CSS architecture, but there are many more. If you’re using a front-end framework such as Bootstrap or Foundation, there might be some architectural opinions already built in.
These are all solid systems, none of which were designed with your project in mind. CSS architecture is hard, so it’s a mistake to trust any one-size-fits-all solution. There is no “right” answer that works for every team on every project. We’d recommend learning them all, and then mashing together the best parts to create a system that works well for you.
Let’s start with a broad discussion of the building blocks, and then look at the ways we can fit them together.
Multiple Files and Folders
Breaking your code into multiple files is one key advantage to using a preprocessor, and forms the basis of any architecture. With Sass, there’s no harm in breaking your code into the smallest logical units and organizing it into multiple files and folders. We recommend taking full advantage of it.
Sass has bestowed new power on the CSS
@import rule, allowing you to combine Sass and CSS files during compilation so they can be sent to the browser as one single file. This is the only place where Sass has stepped on the toes of an existing CSS directive, so it behaves differently in Sass than it did in CSS.
As mentioned, the CSS
@import directive allows you to reference one CSS file from another. Importing is handled by the browser and requires additional HTTP requests—since the importing file has to be parsed before the
@import directive is discovered. If you have a chain of files importing each other, those imports will happen in sequence, blocking the document from rendering until all the CSS has loaded. For that reason, most people avoid CSS imports entirely.
Using CSS imports, you can reference another CSS file using relative or absolute paths, even adding a media query rule for conditional imports. Even though Sass provides different functionality under the same at-rule, there are various cases in which Sass will fall back to the vanilla CSS output, such as when:
an imported file has a
a filename begins with
the filename is a
@importhas any media queries
The following will compile to standard CSS imports, even in Sass:[code language="css"] @import 'relative/styles.css'; @import 'http://absolute.com/styles.css'; @import url('landscape.css') screen and (orientation: landscape);[/code]
Sass Imports and Partials
Sass imports look similar to CSS imports, but the imported files are compiled into one single output file, as though their contents (including variables, mixins, functions, and placeholders) were copied and pasted into place before compilation. This type of Sass import will only work on files with .sass or .scss extensions, but you can leave the extension off when importing (as long as there are no similarly named files). In fact, we recommend dropping the extension whenever you can, for simplicity. It’s also possible to import multiple files in one command, or import files into a nested context: