postcss-insert
v1.0.0
Published
A postcss plugin that inserts one css classes properties into another, like Sass @extend...only better
Downloads
782
Maintainers
Readme
PostCSS Insert
A PostCSS plugin that inserts CSS properties from one class into another, like Sass' @extend only better!
Alright, if you've used Sass before you know about @extend
the concept is pretty simple: you take one classes properties and add them to another class in a simple way. In theory, @extend
is awesome, but it doesn't work the way you expect. See this to see how Sass handles extend.
Mixins with Sass work better, you create a bunch of properties in a mixin and you just @include
them wherever you want. But, you now have this extra thing...the mixin itself, it feels kinda dirty to me. This really should be a solved problem, but it's not for some reason.
What I wanted was a way to have the simplicity of @extend
with the behavior of a @mixin
.
Funny thing is I wasn't the only one thinking of it. Adam Wathen was thinking about this when he created Tailwinds. Adam created a PostCSS plugin called @apply
which did almost everything I wanted it to do...except it was part of a framework. Now, Tailwinds is great, I have no issue with it, but I wanted this without needing a framework. Also, I didn't like the name @apply
because that name was being used with custom properties in CSS. I think its been deprecated, but there's a chance it will be taken up again in the future. To me, @apply
is a great name, but it comes with some potential baggage that I'd have to deal with later on, also I feel like @insert
is more descriptive of what the plugin is doing.
Install
$ npm install postcss-insert`
CSS Usage
Alright, so how do we use this thing? Take a look below:
.bar {
color: green;
}
.foo {
@insert .bar;
}
Output
.bar {
color: green;
}
.foo {
color: green;
}
Obviously this is a pretty contrived example, but you can see what we're doing here. A better example may be extending a button class:
.btn {
padding: 5px 15px;
text-transform: uppercase;
font-size: 18px;
}
.btn-primary {
@insert .btn;
background-color: blue;
}
Output
.btn {
padding: 5px 15px;
text-transform: uppercase;
font-size: 18px;
}
.btn-primary {
padding: 5px 15px;
text-transform: uppercase;
font-size: 18px;
background-color: blue;
}
All props come over, even !important
...unless you disable it
By default, @insert
will not strip !important
, but there's an option stripImportant
that you can set to true
and it will...well strip the !important
:
.bar {
color: green;
font-size: 22px !important;
border: 1px solid red;
}
.foo {
@insert .bar;
}
Output:
.bar {
color: green;
font-size: 22px !important;
border: 1px solid red;
}
.foo {
color: green;
font-size: 22px !important;
border: 1px solid red;
}
With stripImportant: true
you'd get the following:
.bar {
color: green;
font-size: 22px !important;
border: 1px solid red;
}
.foo {
@insert .bar;
}
Output:
.bar {
color: green;
font-size: 22px !important;
border: 1px solid red;
}
.foo {
color: green;
font-size: 22px;
border: 1px solid red;
}
This works inside of media queries...unless you disable it
@media (min-width: 400px) {
.bar {
color: green;
font-size: 22px !important;
border: 1px solid red;
}
}
.foo {
@insert .bar;
}
Output:
@media (min-width: 400px) {
.bar {
color: green;
font-size: 22px !important;
border: 1px solid red;
}
}
.foo {
color: green;
font-size: 22px !important;
border: 1px solid red;
}
General Plugin Usage
postcss([ require('postcss-insert')
]);
Recommendation
I recommend that this plugin run last in your PostCSS stack. If you're doing any sort of transforms where a class doesn't exist @insert
would fail because it can't find the class. If you run this last (or second-to-last right before something like mqpacker) you'll ensure that all classes are there and ready to go. I may eventually add some sort of silent fail option if it can't find a class, but right now that is not the case. Happy coding!
See PostCSS docs for examples for your environment.