You know how you can extend
things in CSS preprocessors? (If not, you can learn about it here.) Sass can do it. LESS can do it. Stylus can do it. While it’s a feature you want to be careful with (see here and here), I find it pretty useful sometimes.
At a recent CodePen Meetup in Chicago, I heard Sam Allan do a quick presentation on LESS’ ability to do (reference)
imports, which I had never seen before.
They look like this:
/* Normal import */
@import "colors-or-whatever.less";
/* Reference import */
@import (reference) "less-for-reference.less";
A normal import will grab the contents of that file and dump it into the file asking for it. Super useful. Concatenating files is a vitally important feature of preprocessors. A (reference) import doesn’t do that. In fact, it doesn’t put anything at all into the file asking for it. The code in that file is just now ready to use, either by calling a mixin within it or extending a selector within it.
That’s a pretty powerful concept. It means you could import an entire library but just use the bits and pieces you want.
Have you ever wanted to use a CSS framework or library but thought it was too much?
As in, a bunch of code that you don’t think you’ll ever use. Including the whole library seems like overkill, not to mention not ideal for performance. You could pick it apart yourself, but then that kinda wrecks the upgrade path.
With (reference) imports you can import whatever you want and then just extend the bits you want out of it. It might be weird, but you could import a bunch of libraries and just pick and choose parts, getting just the output you need.
Example
Say you really dig Pure CSS. Mattia Migliorini has a port of it in LESS. It’s full of good stuff, but it’s 33 KB and maybe you don’t need all of it.
Within it, there is a .pure-button
class, Pure CSS’s take on the button. If you wanted to use it, you could do this:
@import (reference) "https://s3-us-west-2.amazonaws.com/s.cdpn.io/18728/pure.less";
.my-button {
&:extend(.pure-button all);
}
And hey look, I can call my version whatever I want. And, if and when the library updates, I just update it. Assuming names didn’t change, I get the changes.
(The all
keyword you see above means “extend all it’s nested stuff too” and that’s totally optional, which is another kinda awesome thing LESS extends can do.)
Here’s that demo:
See the Pen GpjzOj by Chris Coyier (@chriscoyier) on CodePen.
More
Again, credit to Sam Allan for showing this to me. He has more demos on the subject. Some of them he calls “Semantic Remapping” because he uses selectors he feels are more semantically appropriate than what the original library used.
See the Pen Semantic Remapping — Framework Centipede example by dehuszar (@dehuszar) on CodePen.
Awesome! This trick is going to help reduce the overall size of my Main CSS file dramatically.
Uowwwww, gratz man!!!
Great article. I had never used imports with references, I now see how useful it is.
(srry for my english)
Looks like the people have been talking to SASS about this for a little while https://github.com/sass/sass/issues/1094
It’s interesting to see LESS and SASS compete for developer mindshare. I thought LESS was behind SASS in features (and there are arguably more SASS projects), but in this case, LESS did something SASS hasn’t done yet.
If only there was a UI framework with reasonable defaults that didn’t have to be semantically remapped…
I felt this way early on in my exploration of all you can do with this simple trick, but I actually think there is great value in having your framework use visual and utility classes to describe what what you are implementing. They just tends not to be semantic. But with this trick its pretty easy to use BEM, SuitCSS, or ACSS to define your components and just map them back to the more frameworky classes.
I get into more details here.
Whoops. Bad link. Try this instead.
Awesome. CSS Bloats have become a pain for us since we LESS as our pre-processor. This should definitely help.
Love the idea. Wish to see something like that in next Sass version. Well written Chris, as always!
Can’t Stylus do that? At least its plugins. And afaik Stylus plugins are just .styl files that you import and call whichever functions you need.
Hi Chris. This is nice :)
And anyway, it is also possible use several Import options together.
Aside of being a reference, classes in library.css are now reusable as LESS mixins.
Hey Chris! Thanks for the shout-out, much appreciated.
I should have a follow-up article on the Sass/Stylus/PostCSS versions of the strategy shortly.
This is really neat. I feel this way about grids from frameworks. I would love to take bootstrap n say look here’s one behavior I want (col-xs-6 col-md-4 col-lg-3). I always use it in that exact combination. I’d like to call it .box or whatever. Don’t give me entire grid. Just give me this behavior. Brilliant!
The follow-up article mentioned above is still forthcoming, but I postponed it so I could release PostCSS Reference, which brings the concept detailed above over to the postcss world.