Skip to main content
Home / Articles /

Using a PostCSS function to automate your responsive workflow

A little while back, you might have bumped into this CSS-Tricks article where I described how a mixin can be used to automate responsive font sizes using RFS. In its latest version, v9, RFS is capable of rescaling any value for value for any CSS property with px or rem units, like margin, padding, border-radius or even box-shadow.

Today, we’ll focus on its PostCSS implementation. First thing to do, is install RFS with npm:

npm install rfs

Next step is to add RFS to the PostCSS plugins list. If you’re using a postcss.config.js file, you can add it to the list of other PostCSS plugins (e.g. Autoprefixer):

module.exports = {
  plugins: [
    require('rfs'),
    require('autoprefixer'),
  ]
}

Once configured, you’ll be able to use the rfs() function wherever you want in your custom CSS. For example, if you want your font sizes to be responsive:

.title {
  font-size: rfs(4rem);
}

...or use it with whatever property you want:

.card {
  background-color: #fff;
  border-radius: rfs(4rem);
  box-shadow: rfs(0 0 2rem rgba(0, 0, 0, .25));
  margin: rfs(2rem);
  max-width: 540px;
  padding: rfs(3rem);
}

The code above will output the following CSS:

.card {
  background-color: #fff;
  border-radius: calc(1.525rem + 3.3vw);
  box-shadow: 0 0 calc(1.325rem + 0.9vw) rgba(0, 0, 0, .25);
  margin: calc(1.325rem + 0.9vw);
  max-width: 540px;
  padding: calc(1.425rem + 2.1vw);
}

@media (min-width: 1200px) {
  .card {
    border-radius: 4rem;
    box-shadow: 0 0 2rem rgba(0, 0, 0, .25);
    margin: 2rem;
    padding: 3rem;
  }
}

Demo

Here's a Pen that shows how things work. You can resize the demo to see the fluid rescaling in action.

See the Pen
RFS card- PostCSS
by Martijn Cuppens (@MartijnCuppens)
on CodePen.

A deeper look at how RFS parses the CSS

The plugin will look for any occurance of the rfs() function in the declaration values and replace the function with a fluid value using the calc() function. After each rule, RFS will generate a media query with some additional CSS that prevents the values from becoming too large.

RFS only converts px and rem values in a declaration; all other values (e.g. em values, numbers or colors) will be ignored. The function can also be used multiple times in a declaration, like this:

box-shadow: 0 rfs(2rem) rfs(1.5rem) rgba(0, 0, 255, .6)

RFS and custom properties

:root {
  --title-font-size: rfs(2.125rem);
  --card-padding: rfs(3rem);
  --card-margin: rfs(2rem);
  --card-border-radius: rfs(4rem);
  --card-box-shadow: rfs(0 0 2rem rgba(0, 0, 0, .25));
}

These variables can be used in your CSS later on.

.card {
  max-width: 540px;
  padding: var(--card-padding);
  margin: var(--card-margin);
  background-color: #fff;
  box-shadow: var(--card-box-shadow);
  border-radius: var(--card-border-radius);
}

Hopefully you find these updates useful in your work. Leave a comment if you have any questions or feedback!

icon-link icon-logo-star icon-search icon-star