HTML & CSS
Article
By Thomas Greco

Get Started on the CSS of the Future with PostCSS-cssnext

By Thomas Greco

PostCSS-cssnext

cssnext Logo

A discussion of PostCSS-cssnext appeared earlier this year in “7 PostCSS Plugins to Ease You into PostCSS”, published by SitePoint. PostCSS-cssnext is a plug-in pack for writing next generation CSS. This article provides an insight into the project’s history and its benefits. Once we gain a deeper understanding of PostCSS-cssnext, we’ll then jump into a handful of examples for you to play with. By the end of the article, you’ll be well-versed in future CSS syntax with PostCSS-cssnext, and be able to decide whether it is something you wish to use in an upcoming (or existing) project!

The Need for Next Generation CSS

Regardless of the language, developers are always after the latest features. Whereas tools like Babel provide JavaScript developers with support for future ECMAScript features, PostCSS-cssnext provides web designers with future CSS features. Currently, this means offering support for CSS4-related features, such as CSS variables, nesting, and more! Now, before we go any further, I would like to point out the fact that future CSS features can be subject to change, and the CSS4 spec is no different in this regard. Nonetheless, PostCSS-cssnext alleviates the negative impact this may have on a project by informing users in advance of any changes that are about to occur.

postcss homepage screenshot - features

From cssnext to PostCSS-cssnext

Initially, “cssnext” was meant to perform such tasks as minifying code and displaying error messages. These capabilities were helpful, however they did not support future CSS features, which is the ultimate goal of the PostCSS-cssnext project. As a consequence, the cssnext team decided to abandon the idea of cssnext as a standalone tool on the grounds that the time spent supporting it could be better spent on supporting future CSS syntax and any of its subsequent changes. For additional CSS-related processes, developers can integrate PostCSS-cssnext with other technologies like cssnano for code minification and postcss-browser-reporter for error reporting.

Dissecting PostCSS-cssnext

If we delve into the PostCSS-cssnext repository on GitHub, we can see just how modular this plug-in is. Inside the src/features.js file, we’ll see that the code for each future CSS feature is enclosed within its own module named in accordance with the relevant CSS specification.

// https://npmjs.com/package/postcss-custom-properties
customProperties: (options) => require("postcss-custom-properties")(options),

// https://npmjs.com/package/postcss-apply
applyRule: (options) => require("postcss-apply")(options),

// https://npmjs.com/package/postcss-calc
calc: (options) => require("postcss-calc")(options),

Because it’s a plug-in pack, PostCSS-cssnext is bundled with PostCSS plug-ins. This means that we could install these features individually if we so choose, although using PostCSS-cssnext means we don’t have to! For example, if we only wanted to use CSS custom properties, we could install it via npm like this:

npm install postcss-custom-properties --save-dev

For a full list of all the CSS features PostCSS-cssnext supports, head over to the dedicated features page on the PostCSS-cssnext website.

We should also note that PostCSS-cssnext comes bundled with autoprefixer and pixrem. Don’t worry if you’re unfamiliar with these tools. They are post-processors for creating cross-browser compatible CSS, and we are going to find out how they work soon.

A Look into PostCSS-cssnext Examples

Now that we’ve taken a detailed look at PostCSS, let’s dive into some examples!

Using Custom Properties With var()

Custom properties are among the most popular CSS features. It’s important to note that all custom properties are limited to the :root selector.

:root {
  --fontSize: 2em;
}

Once defined, we can then use var() inside of our CSS. In addition to the root selector, we should direct our attention to the use of dashes, -- when naming custom properties. This ensures our code aligns with the w3c spec.

See the Pen postcss-cssnext custom properties by SitePoint (@SitePoint) on CodePen.

Using Custom Properties With @apply

With @apply, we can take custom properties with var() a step further and reference sets of data. These are helpful in situations when you want to re-use a group of styles without having to write them over and over again! In our example, we see how we can take advantage of this feature when creating a layout.

:root {
  --flex-row: {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-around;
  }
}
.flex-row {
  @apply --flex-row;
}

The above CSS rules inside the :root selector define a flex container. If we want to modify this layout, all we need to do is modify a single value inside of --flex-row and the change will take effect wherever --flex-row is used in conjunction with @apply.

Quick Note on Our Code

Although I haven’t directly mentioned the use of nesting, we saw it being used in the example above (the --flex-row property is nested inside of the :root selector). For those completely new to the concept of nesting, you can read more about it in the CSS Nesting Module Level 3 documentation. As its name suggests, nesting allows us to nest CSS rules within other CSS rules. Without taking it too far, it’s a really practical feature, so I suggest checking it out!

Another cool thing that we might not have realized is that all of our code is cross-browser compatible! As we learned before, cssnext comes with autoprefixer, which automatically adds all the vendor prefixes to the compiled CSS code.

Calculating Expressions

We’ve already taken a look at the var() function. Now, let’s learn how we can use custom properties with var in conjunction with the calc function. In our example, we will use calc() to calculate font-sizes for our headings.

:root {
  --fontSize: 1rem;
}
h1 {
  font-size: calc(var(--fontSize) * 3);
}
h2 {
  font-size: calc(var(--fontSize) * 2.75);
}
h3 {
  font-size: calc(var(--fontSize) * 2.25);
}
h4 {
  font-size: calc(var(--fontSize) * 2);
}

Here, we see our --fontSize variable being passed into calc() to multiply its value. In addition to multiplication, calc() can also be used to perform division, subtraction, and addition.

See the Pen calc function by SitePoint (@SitePoint) on CodePen.

The Hidden Powers of Pixrem

A moment ago, we mentioned the effect autoprefixer had on our code. In addition to adding vendor prefixes, the PostCSS-cssnext plug-in pack will also generate fallback pixel values for rem units with the help of pixrem. It does this for browsers where rem is not supported, and if we analyze our compiled CSS in the above demo, we’ll see that our headings have now both a px and rem value, further ensuring cross-browser compatibility.

h1 {
  font-size: 48px;
  font-size: 3rem;
}
h2 {
  font-size: 44px;
  font-size: 2.75rem;
}
h3 {
  font-size: 36px;
  font-size: 2.25rem;
}
h4 {
  font-size: 32px;
  font-size: 2rem;
}

Custom Media Queries

Mobile web usage is huge, which means that responsive design is more crucial than ever. If you were not already aware, there are a number of planned changes to simplify the process of building media queries.

@custom-media --small-viewport (max-width: 600px);
 @media (--small-viewport) {
   /* styles for small viewport */
  .danger {
    flex-direction: column;
    background-color: rebeccapurple; 
  }
 }

In our first media query, we see @custom-media being used to create a custom media query. Once this is done, we can then pass the name of our media query into the @media() rule to establish our breakpoint. Now, we can see our items change from row to column and the background color change from orange to Rebecca purple as our viewport gets smaller (from 600px and below).

See the Pen postcss-cssnext custom media queries by SitePoint (@SitePoint) on CodePen.

Media Query Ranges

While writing media queries, PostCSS-cssnext allows us to be more concise with our code by letting us define media query ranges. This means that we can replace max, min, and equal values with the >,< and = operators. Although minor, these symbols allow for faster development and make code easier to read.

@custom-media --medium-viewport (width >= 600px) and (width <= 1280px);

@media (--medium-viewport) {
  .danger {
    display: flex;
    justify-content: space-around;
    padding: 1rem;
    background: teal;
  }
}

In the snippet above is the code for the --medium-viewport media query. If we resize the viewport to be smaller than 600px, then the media query for small screens from the previous example will take effect, i.e., flex-direction will be set to column and the background color will be Rebecca purple. When the page is displayed on screens wider than or equal to 600px all the way up to screens 1280px wide, the flex-direction property will revert to its default row value and the background color will be teal. Once the viewport width exceeds 1280px, the background color will revert back to orange.

See the Pen postcss-cssnext media query ranges by SitePoint (@SitePoint) on CodePen.

Conclusion

We just covered a lot of ground and gained a lot of knowledge about PostCSS-cssnext. So, what do you think? Do you find PostCSS-cssnext helpful? Hopefully, you’ve come away from this article with insight about the tool and its ability to bring future CSS features into today’s world. For those interested in playing around with PostCSS-cssnext, I’ve created this starter-kit with Gulp.

  • Matteo Gilardoni

    One part I am a bit concern about cssnext or other processor of this type is they remove custom property from the stylesheet when they process the css. I think there is a big difference from sass/less variables from custom properties.

    This is problematic if you are using custom property to evaluate at run-time value from javascript. Basically you are precluding every browser to use this feature even if they support it.

    Right now IE and Microsoft Edge are the only one not supporting it and Edge I think is going to release this feature on next update 15 or 16 version.

Recommended
Sponsors
Get the latest in Front-end, once a week, for free.