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.
npm install postcss-simple-extend --save
Version 1.0.0+ is compatible with PostCSS v5+.
Lower versions are compatible with PostCSS 4.1+.
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;
}
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.)
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.
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 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.