Writing CSS of the future: PostCSS
Front-end design with CSS has transitioned through various interesting stages. CSS3 arrived and it brought a lot of interesting features giving us abilities to use pure CSS to get results that are known to only be achievable with the presence of JavaScript. To grace the awesomeness of working with CSS, preprocessors were created and they include Sass and the others.
Sass introduced logic to CSS and that made it a lot easier to work with. While some may think preprocessors like Sass have only made things complex, the reality is that lack of logic and programmable structure makes the good ol' CSS difficult to work with and with the all that Sass introduced to CSS, it simplified how we use and think of our CSS.
Some of the operations introduced into CSS by writing Sass include the use of variables, mixins, partials (imported modules), control structures, extending rules, nested rules, placeholder selectors, math operations and more.
Sass has won our hearts over the years and it has made people from other preprocessors switch onto it. It has moved from a nested format to Sass3 format (SCSS) with fallback for CSS but there's been something even better lately; POSTCSS.
PostCSS brings a lot to the table. As you may have deduced from the name, unlike Sass it is not a pre-processor but a post-processor. Its most significant feature is that it allows you use plugins like CSSNEXT which gives you the freedom to use CSS4 amazing syntax without having to bother about browser compatibility.
PostCSS creates an AST that makes it easy for other programs/plugins to manipulate and produce a final CSS file with browser compatible format. So all the good stuff that follows will be a list of plugins and their capabilities because PostCSS itself doesn't do more than just provide the data structure for use by the plugins.
CSSnext
CSSnext is what really inspired the title of this article. It enables the use of CSS4 syntax that's still a draft as of the current date. CSS4 introduces so much that you've wished for in CSS. A lot of the things pre-processors like Sass come with like variables, nesting, color manipulations and more.
Variables
Variables can be defined and used this way:
:root{
--black: #000;
--white: #fff;
--color-one: #63BDC6;
--color-two: #5D7BC1;
--color-three: #9753AA;
--rootFont: 62.5%;
--fontSize: 2rem;
--fontOne: "tenby-four";
--fontTwo: "fira-sans-2";
}
Custom Selectors
/* Defining selector */
@custom-selector :--general html, button, input, select, textarea;
/* Usage */
:--general{
color: #222;
}
/* CSS Output */
html, button, input, select, textarea{
color: #222;
}
Custom Media Queries
@custom-media --small-viewport (max-width: 30em);
@custom-media --tablet-portrait (min-width: 768px);
@custom-media --tablet-landscape (min-width: 1024px);
@custom-media --tablet-wide (min-width: 1075px);
@custom-media --iphone-portrait (min-width: 320px);
@custom-media --iphone-landscape (min-width: 568px);
@custom-media --android-landscape (min-width: 480px);
@custom-media --laptop (min-width: 1170px);
/* Usage */
@media(--iphone-landscape){ ... }
@media only screen and (--tablet-portrait){ ... }
To see more features, go to the features page and try it in the playground.
CSSnano
CSSnano optimizes your CSS better than any other modifiers out there. It takes your file from bloated to floated (pun intended). You'd be amazed to see the optimizations it does to your code.
PreCSS
PreCSS allow the use of Sass compatible code. You'll find it handy if you want your transitioning from Sass to be almost like no change. It can be installed as a single plugin or installed in bits. Some plugins that can be selected from it include postcss-import
, postcss-mixins
, postcss-simple-vars
, postcss-nested
.
postcss-import
Allows importing other CSS modules and unlike Sass, you don't need a _ prefix
/* app.css */
@import 'variables';
@import 'mixins';
/* Imports variables.css and mixins.css */
postcss-mixins
This isn't exactly like it is in Sass but it's still pretty decent
/* Define Mixin */
@define-mixin ellipsis-line $width{
width: $width;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
/* Usage */
.foo{
@mixin ellipsis-line 100%;
}
postcss-simple-vars
I love a mix of Sass-like vars and the CSS4 vars in my variables.css
$color-hopbush: #c69;
$color-bouquet: #b37399;
$color-venus: #998099;
$color-patina: #699;
$color-nebula: #d2e1dd;
$color-wine: #B21F1F;
$color-dawn-pink: #f2ece4;
$color-wafer: #e1d7d2;
$color-rebeccapurple: #663399;
Also, I still have projects in Sass and this makes it easy for me to copy some of my default variables from each of them.
postcss-nested
Nesting in Sass is one of its features I find most interesting. I totally rely on it to write code using the BEM convention.
.media{ /* Block */
&--inactive{ /* Modifier */
...
}
&__avatar{ /* Element */
...
}
}
.pod{
&:hover{ ... }
&::before{ ... }
}
.child{
...
.parent & {
...
}
}
/* CSS Output */
.media{}
.media--inactive{}
.media__avatar{}
.pod{}
.pod:hover{}
.pod::before{}
.child{}
.parent .child{}
For better use of the BEM convention you can also use postcss-bem-linter.
Autoprefixer
You've probably been using autoprefixer since forever. I've been using autoprefixer since my use with compass which has been quite a long time from now and just like prefix-free it saves us from the browser prefix nightmare. I've recently added to our team's styleguide which should be public soon that there should be no use of browser prefixes within the code as this should be the work of autoprefixer.
There's a lot more postcss plugins I couldn't mention but the listed ones should get you started. Just take that leap and you'd enjoy the ride with postCSS. If you find something that doesn't work for you as you want then you can build your own plugin.