How to Use PostCSS as a Configurable Alternative to Sass

Web developers love the Sass CSS preprocessor. According to the Sass opinions in the State of CSS Survey, every developer knows what it is, 89% use it regularly, and 88% have high satisfaction.Many web bundlers include Sass processing, but you may also be using PostCSS without realizing it. PostCSS is primarily known for its Autoprefixer plugin, which automatically adds -webkit, -moz, and -ms vendor prefixes to CSS properties when required. Its plugin system means it can do so much more … such as compiling .scss files without having to use the Sass compiler.
This tutorial explains how to create a custom CSS preprocessor which compiles Sass syntax and supplements it with further features. It’s ideal for anyone with specific CSS requirements who knows a little Node.js.
Quick Start
An example PostCSS project can be cloned from GitHub. It requires Node.js, so run npm install to fetch all dependencies.
Compile the demonstration src/scss/main.scss source code to build/css/main.css using:

npm run css:dev

Auto-compile whenever files are changed using:

npm run css:watch

Then exit watching by pressing Ctrl | Cmd + C in the terminal.
Both options also create a source map at build/css/main.css.map, which references the original source files in the developer tools.
Production-level minified CSS without a source map can be compiled using:

npm run css:build

Refer to the README.md file for further information.
Should You Replace Sass with PostCSS?
There’s nothing wrong with the Sass compiler, but consider the following factors.
Module Dependencies
The latest Dart version of Sass can be installed globally using the Node.js npm package manager:

npm install -g sass

Compile Sass .scss code with:

sass [input.scss] [output.css]

Source maps are automatically generated (–no-source-map will switch them off) or –watch can be added to auto-compile source files when they change.

The latest version of Sass requires less than 5MB of installation space.
PostCSS should require fewer resources and a basic Sass-like compiler with auto-prefixing, and minification needs less than 1MB of space. In reality, your node_modules folder will expand to more than 60MB and increase rapidly as more plugins are added. This is mostly npm installing other dependencies. Even though PostCSS may not use them, it can’t be considered as a lightweight alternative.
However, if you’re already using PostCSS for Autoprefixer or other purposes, Sass may not be necessary.
Processing Speed
The slow, Ruby-based Sass compiler has long gone and the latest edition uses a compiled Dart runtime. It’s fast.

PostCSS is pure JavaScript and, while benchmarks will differ, it can be three times slower at compiling the same source code.
However, this speed difference will be less noticeable if you’re already running PostCSS after Sass. A two-stage process can be slower than using PostCSS alone, since much of its work involves tokenizing CSS properties.
Customization
The Sass language includes a large set of features including variables, nesting, partials, mixins, and more. There are downsides:

You cannot easily add new features.
Perhaps you’d like an option convert HSLA colors to RGB. It may be possible to write a custom function, but other requirements will be impossible — such as inlining an SVG as a background image.

You can’t easily restrict the feature set.
Perhaps you’d prefer your team not to use nesting or @extend. Linting rules will help, but they won’t stop Sass compiling valid .scss files.

PostCSS is considerably more configurable.
On its own, PostCSS does nothing. Processing functionality requires one or more of the many plugins available. Most perform a single task, so if you don’t want nesting, don’t add a nesting plugin. If necessary, you can write your own plugins in a standard JavaScript module that can harness the power of Node.js.

Install PostCSS
PostCSS can be used with webpack, Parcel, Gulp.js, and other build tools, but this tutorial shows how to run it from the command line.
If necessary, initialize a new Node.js project with npm init. Set up PostCSS by installing the following modules for basic .scss parsing with plugins for partials, variables, mixins, nesting, and auto-prefixing:

npm install –save-dev postcss postcss-cli postcss-scss postcss-advanced-variables postcss-nested autoprefixer

Like the example project, PostCSS and its plugins are installed locally. This is a practical option if your projects are likely to have differing compilation requirements.
Note: PostCSS can only be run from a JavaScript file, but the postcss-cli module provides a wrapper that can be called from the command line. The postcss-scss module allows PostCSS to read .scss files but doesn’t transform them.
Autoprefixer Configuration
Autoprefixer uses browserslist to determine which vendor prefixes are required according to your list of supported browsers. It’s easiest to define this list as a “browserslist” array in package.json. The following example adds vendor prefixes where any browser has at least 2% market share:

“browserslist”: [
” > 2%”
],

Your First Build
You’ll typically have a single root Sass .scss file which imports all required partial/component files. For example:

@import ‘_variables’;
@import ‘_reset’;
@import ‘components/_card’;

Compilation can be started by running npx postcss, followed by the input file, an –output file, and any required options. For example:

npx postcss ./src/scss/main.scss
–output ./build/css/main.css
–env development
–map
–verbose
–parser postcss-scss
–use postcss-advanced-variables postcss-nested autoprefixer

This command:
parses ./src/scss/main.scss
outputs to ./build/css/main.css
sets the NODE_ENV environment variable to development
outputs an external source map file
sets verbose output and error messages
sets the postcss-scss Sass parser, and
uses the plugins postcss-advanced-variables, postcss-nested, and autoprefixer to handle partials, variables, mixins, nesting, and auto-prefixing
Optionally, you could add –watch to auto-compile when .scss files are modified.
Create a PostCSS Configuration File
The command line quickly becomes unwieldy for longer lists of plugins. You can define it as an npm script, but a PostCSS configuration file is an easier option that offers additional possibilities.
PostCSS configuration files are JavaScript module files named postcss.config.js and typically stored in the project’s root directory (or whichever directory you run PostCSS from). The module must export a single function:

module.exports = cfg = > {

};

It’s passed a cfg object with properties set by the postcss command. For example:

{
cwd: ‘/home/name/postcss-demo’,
env: ‘development’,
options: {
map: undefined,
parser: undefined,
syntax: undefined,
stringifier: undefined
},
file: {
dirname: ‘/home/name/postcss-demo/src/scss’,
basename: ‘main.scss’,
extname: ‘.scss’
}
}

You can examine these properties and react accordingly — for example, determine whether you’re running in development mode and processing a .scss input file:

module.exports = cfg = > {

const
dev = cfg.env === ‘development’,
scss = cfg.file.extname === ‘.scss’;

};

The function must return an object with property names matching the postcss-cli command line options. The following configuration file replicates the long quick start command used above:

module.exports = cfg = > {

const
dev = cfg.env === ‘development’,
scss = cfg.file.extname === ‘.scss’;

return {

map: dev ? { inline: false } : false,
parser: scss ? ‘postcss-scss’ : false,
plugins: [
require(‘postcss-advanced-variables’)(),
require(‘postcss-nested’)(),
require(‘autoprefixer’)()
]

};

};

PostCSS can now be run using a shorter command:

npx postcss ./src/scss/main.scss
–output ./build/css/main.css
–env development
–verbose

Here are some things to note:
–verbose is optional: it’s not set in postcss.config.js.
Sass syntax parsing is only applied when the input is a .scss file. Otherwise, it defaults to standard CSS.
A source map is only output when –env is set to development.
–watch can still be added for auto-compilation.
If you’d prefer postcss.config.js to be in another directory, it can be referenced with the –config option — such as –config /mycfg/. In the example project, the configuration above is located in config/postcss.config.js. It’s referenced by running npm run css:basic, which calls:

npx postcss src/scss/main.scss
–output build/css/main.css
–env development
–verbose
–config ./config/

Adding Further Plugins
The following sections provide examples of PostCSS plugins which either parse additional .scss syntax or provide processing beyond the scope of the Sass compiler.
Use Design Tokens
Design Tokens are a technology-agnostic way to store variables such as corporation-wide fonts, colors, spacing, etc. You could store token name–value pairs in a JSON file:

{

“font-size”: “16px”,

“font-main”: “Roboto, Oxygen-Sans, Ubuntu, sans-serif”,
“lineheight”: 1.5,

“font-code”: “Menlo, Consolas, Monaco, monospace”,
“lineheight-code”: 1.2,

“color-back”: “#f5f5f5”,
“color-fore”: “#444”

}

Then reference them in any web, Windows, macOS, iOS, Linux, Android, or other application.
Design tokens are not directly supported by Sass, but a JavaScript object with a variables property holding name–value pairs can be passed to the existing postcss-advanced-variables PostCSS plugin:

module.exports = cfg = > {

const variables = require(‘./tokens.json’);

const
dev = cfg.env === ‘development’,
scss = cfg.file.extname === ‘.scss’;

return {

map: dev ? { inline: false } : false,
parser: scss ? ‘postcss-scss’ : false,
plugins: [
require(‘postcss-advanced-variables’)({ variables }),
require(‘postcss-nested’)(),
require(‘autoprefixer’)()
]

};

};

The plugin converts all values to global Sass $variables which can be used in any partial. A fallback value can be set to ensure a variable is available even when it’s missing from tokens.json. For example:

$color-back: #fff !default;

Token variables can then be referenced in any .scss file. For example:

body {
font-family: $font-main;
font-size: $font-size;
line-height: $lineheight;
color: $color-fore;
background-color: $color-back;
}

In the example project, a token.json file is defined, which is loaded and used when running npm run css:dev.
Add Sass Map Support
Sass Maps are key–value objects. The map-get function can look up values by name.
The following example defines media query breakpoints as a Sass map with a respond mixin to fetch a named value:

$breakpoint: (
‘small’: 36rem,
‘medium’: 50rem,
‘large’: 64rem
);

@mixin respond($bp) {
@media (min-width: map-get($breakpoint, $bp)) {
@content;
}
}

Default properties and media query modifications can then be defined in the same selector. For example:

main {
width: 100%;

@include respond(‘medium’) {
width: 40em;
}
}

Which compiles to CSS:

main {
width: 100%;
}

@media (min-width: 50rem) {

main {
width: 40em
}

}

The postcss-map-get plugin adds Sass map processing. Install it with:

npm install –save-dev postcss-map-get

And update the postcss.config.js configuration file:

module.exports = cfg = > {

const variables = require(‘./tokens.json’);

const
dev = cfg.env === ‘development’,
scss = cfg.file.extname === ‘.scss’;

return {

map: dev ? { inline: false } : false,
parser: scss ? ‘postcss-scss’ : false,
plugins: [
require(‘postcss-advanced-variables’)({ variables }),
require(‘postcss-map-get’)(),
require(‘postcss-nested’)(),
require(‘autoprefixer’)()
]

};

};

Add Media Query Optimization
Since we’ve added media queries, it would be useful to combine and sort them into mobile-first order. For example, the following CSS:

@media (min-width: 50rem) {

main {
width: 40em;
}

}

@media (min-width: 50rem) {

#menu {
width: 30em;
}

}

can be merged to become:

@media (min-width: 50rem) {

main {
width: 40em;
}

#menu {
width: 30em;
}

}

This isn’t possible in Sass, but can be achieved with the PostCSS postcss-sort-media-queries plugin. Install it with:

npm install –save-dev postcss-sort-media-queries

Then add it to postcss.config.js:

module.exports = cfg = > {

const variables = require(‘./tokens.json’);

const
dev = cfg.env === ‘development’,
scss = cfg.file.extname === ‘.scss’;

return {

map: dev ? { inline: false } : false,
parser: scss ? ‘postcss-scss’ : false,
plugins: [
require(‘postcss-advanced-variables’)({ variables }),
require(‘postcss-map-get’)(),
require(‘postcss-nested’)(),
require(‘postcss-sort-media-queries’)(),
require(‘autoprefixer’)()
]

};

};

Add Asset Processing
Asset management is not available in Sass, but postcss-assets makes it easy. The plugin resolves CSS image URLs, adds cache-busting, defines image dimensions, and inlines files using base64 notation. For example:

#mybackground {
background-image: resolve(‘back.png’);
width: width(‘back.png’);
height: height(‘back.png’);
background-size: size(‘back.png’);
}

compiles to:

#mybackground {
background-image: url(‘/images/back.png’);
width: 600px;
height: 400px;
background-size: 600px 400px;
}

Install the plugin with:

npm install –save-dev postcss-assets

Then add it to postcss.config.js. In this case, the plugin is instructed to locate images in the src/images/ directory:

module.exports = cfg = > {

const variables = require(‘./tokens.json’);

const
dev = cfg.env === ‘development’,
scss = cfg.file.extname === ‘.scss’;

return {

map: dev ? { inline: false } : false,
parser: scss ? ‘postcss-scss’ : false,
plugins: [
require(‘postcss-advanced-variables’)({ variables }),
require(‘postcss-map-get’)(),
require(‘postcss-nested’)(),
require(‘postcss-sort-media-queries’)(),
require(‘postcss-assets’)({
loadPaths: [‘src/images/’]
}),
require(‘autoprefixer’)()
]

};

};

Add Minification
cssnano sets the standard for CSS minification. Minification can take more processing time than other plugins, so it can be applied in production only.
Install cssnano with:

npm install –save-dev cssnano

Then add it to postcss.config.js. In this case, minification only occurs when NODE_ENV is set to anything other than development:

module.exports = cfg = > {

const variables = require(‘./tokens.json’);

const
dev = cfg.env === ‘development’,
scss = cfg.file.extname === ‘.scss’;

return {

map: dev ? { inline: false } : false,
parser: scss ? ‘postcss-scss’ : false,
plugins: [
require(‘postcss-advanced-variables’)({ variables }),
require(‘postcss-map-get’)(),
require(‘postcss-nested’)(),
require(‘postcss-sort-media-queries’)(),
require(‘postcss-assets’)({
loadPaths: [‘src/images/’]
}),
require(‘autoprefixer’)(),
dev ? null : require(‘cssnano’)()
]

};

};

Setting –env to prodution triggers minification (and removes the source map):

npx postcss ./src/scss/main.scss
–output ./build/css/main.css
–env prodution
–verbose

In the example project, production CSS can be compiled by running npm run css:build.
Progress to PostCSS?
PostCSS is a powerful and configurable tool that can compile .scss files and enhance (or restrict) the standard Sass language. If you’re already using PostCSS for Autoprefixer, you may be able to remove the Sass compiler entirely while retaining the syntax you love.
Further links:

100+ Beautiful, Premium PowerPoint Presentation (PPT) Templates 2021

PowerPoint presentations, love them or hate them, are an essential part of today’s corporate world. Whether for business use or design purposes, the look-and-feel of your PowerPoint presentation can make a tremendous difference in how impressively your pitch comes across. To help out with making your next PowerPoint presentation particularly impressive, we have searched the…

State Of GDPR In 2021: Key Updates And What They Mean

The EU’s directives have impacted virtually every digital professional as products and services are designed with GDPR in mind, regardless of whether you’re a web design company in Wisconsin or a marketer in Malta. The far-reaching implications of GDPR don’t just impact how data should be processed, how products should be built and how data…

Looking for a special kind of popup for a website I'm working on.

Hey guys,
I’m a new, self-taught dev who just recently starting my first professional job. I’m looking into setting up a sort of special feature for a work project. This project is for a WordPress site, but I felt that it was more about web development than WP, which is why I’m posting here.
Basically, I need to be able to click a button underneath a blog post tile (on the main page), after which a popup will display with the title, image and content of the blog post inside.
The sort of loose example I was given was this site (when you press Learn More):
How advanced is something like this to implement? Is there any way for me to pull the WordPress code that this site used (it is a WordPress site also)
A requirement is that the popup itself needs to be AODA compliant (basically being accessible).
Can anyone give me some guidance with this task?