Awesome
postcss-simple-extend
A PostCSS plugin that enables you to extend placeholder selectors in CSS.
Use this plugin to define a rule set with an abstract, extendable selector — a "placeholder selector" — to which you can, later on, add concrete selectors from other rule sets.
The functionality should mirror Sass's @extend
with %
placeholders (a.k.a. "silent classes").
Unlike Sass's @extend
, however, this plugin does not enable you to extend real selectors: i.e. you cannot @extend .classname
or @extend ul > li + li > span a
.
That key difference makes this plugin much more simple, and arguably much less dangerous.
Many of the potential problems with Sass's @extend
simply do not apply to this limited, more simple version. Smart Sass users often recommend to only ever @extend
placeholders (cf. Harry Robert and Hugo Giraudel): with this plugin, that recommendation is enforced.
If you are looking for a more full-featured @extend
, check out postcss-extend
.
A Note on "mixins" & "extends": Mixins copy declarations from an abstract definition into a concrete rule set. The simple extend supported by this plugin clones a concrete rule set's selector and adds it to an abstract placeholder selector. If you would like to use mixins, as well — or instead — have a look at
postcss-mixins
.Also think about this: Should you use an
@extend
instead of a@mixin
? The answer: maybe not. Given the fact that@extend
s don't actually reduce generated file size (after gzip), and the CSS generated by mixins is easier to read and understand, you might not want to introduce@extend
s to your codebase. Just consider.
Installation
npm install postcss-simple-extend --save
Version 1.0.0+ is compatible with PostCSS v5+.
Lower versions are compatible with PostCSS 4.1+.
Example Input-Output
Input:
@define-placeholder gigantic {
font-size: 40em;
}
.foo {
@extend gigantic;
color: red;
}
.bar {
@extend gigantic;
color: orange;
}
Output:
.foo,
.bar {
font-size: 40em;
}
.foo {
color: red;
}
.bar {
color: orange;
}
Usage
Note for Sass enthusiasts: This plugin does not support %
selectors. It uses the custom at-rules described below, instead. (Because I didn't want to hijack the %
character, and potentially clash with other transforms.)
Define Your Placeholder
With @define-placeholder
, you associate a rule set with a placeholder selector, which you will later extend with concrete selectors.
You can also use @define-extend
or @simple-extend-define
, if either of those better fits your mind and situation.
@define-placeholder simple-list {
list-style-type: none;
margin: 0;
padding: 0;
}
/* or @define-extend simple-list {...} */
/* or @simple-extend-define simple-list {...} */
@define-placeholder
at-rules, and the placeholder names (e.g. simple-list
, above), will be removed entirely from the generated CSS, replaced by the selectors you've added via @extend
(see example above).
There are some defining guidelines to obey (violations should log warnings):
- Definitions must occur at the root level (i.e. not inside statements, such as rule sets or
@media
blocks). - Definitions should only contain declarations and comments: no statements.
Extend a Placeholder (Add Selectors to It)
Use the at-rule @extend
within a rule set to add that rule set's selector(s) to a placeholder (which was defined via @define-placeholder
).
You can also use @simple-extend-addto
, if that better fits your mind and situation.
.list-i-want-to-be-simple {
@extend simple-list;
/* or @simple-extend-addto simple-list; */
font-size: 40em;
}
And there are some @extend
guidelines to obey (violations should log warnings):
@extend
must not occur at the root level: only inside rule sets.@extend
must not occur within@media
statements. (The generated code almost certainly would not match your intention.)- The placeholder must be defined before
@extend
can refer to it.
Plug it in to PostCSS
Plug it in just like any other PostCSS plugin. There are no frills and no options, so integration should be straightforward. For example (as a node script):
var fs = require('fs');
var postcss = require('postcss');
var simpleExtend = require('postcss-simple-extend');
var inputCss = fs.readFileSync('input.css', 'utf8');
var outputCss = postcss()
.use(simpleExtend())
// or .use(simpleExtend)
.process(inputCss)
.css;
console.log(outputCss);
Or take advantage of any of the myriad other ways to consume PostCSS, and follow the plugin instructions they provide.