Skip to content Paweł Grzybek

CSS mixins with @apply rule

I am very excited about recent evolution of CSS. Flexbox was a buzzword some time ago, today it is a part of a spec that is well supported and widely adopted. Few months back I published an intro to CSS grid layout module that is another approaching feature that will dramatically change the way we build our projects. The enormous popularity of preprocessors like Sass or LESS undoubtedly influenced spec authors to bring variables to the language as a CSS Custom Properties. I recently published a post that explains everything that you need to know about this powerful feature. Another aspect of preprocessors that developers and designers love are mixins. Well the good news keeps coming my friend - CSS @apply Rule is just around the corner. Let’s embrace a native CSS mixins together.

This specification defines the @apply rule, which allows an author to store a set of properties in a named variable, then reference them in other style rules.

Before we begin with some code snippets and examples I need to inform you that at the time of writing this article the only implementation is in Google Chrome Canary with “Experimental Web Platform features” flag enabled.

Enable Experimental Web Platform Featured Flag in Google Chrome

Syntax

If you are familiar with the syntax of CSS Custom Properties you won’t struggle to memorize this one. Just wrap a set of properties with curly braces like that…

:root {
  --heading-style: {
    font-family: cursive;
    font-weight: 700;
  };
}

Use the mixin via new @apply at-rule.

h1 {
  @apply --heading-style;
}

See the Pen 2016.04.18 - 1 by Pawel Grzybek (@pawelgrzybek) on CodePen.

Local variables in CSS mixins

Sass allows us to pass a list of locally defined variables to a mixin. Unfortunately this isn’t possible with the @apply rule.

If you have some object oriented JavaScript experience, the first thing that you will try as a way around this is doing something like…

:root {
  --brand-color: red;
  --heading-style: {
    color: var(--brand-color);
    font-family: cursive;
    font-weight: 700;
  };
}
h1 {
  --brand-color: green;
  @apply --heading-style;
}

/*
brand-color value pulled from the root, not the local block
value is red, not green
it is CSS, not JavScript
*/

…but this is not JavaScript my friend. It takes the value of the variable from the place where the mixin is defined, not from the block that is “invoked” in. Hopefully we will get ability to pass a parameters to a mixin at some point in the future - fingers crossed.

Use native CSS mixins today

As I mentioned before, the browser support for this feature is practically zero right now. Chrome Platform Status informs us that the first implementation is planned for Google Chrome 51 (behind the flag) and Opera 38. Any details about other browsers haven’t been revealed at the time of writing this article.

As a web developers we want to use the benefits of future improvements right now! That’s what we do with Babel and ECMAScript 2015. This is the reason why I like PostCSS so much! If you have never used it yet, I highly encourage you to check my introduction to PostCSS for Sass users. Pascal Duez created a postcss-apply that transpiles @apply rule to syntax understandable by current browsers.

The feature detection for @apply isn’t that straight forward as with CSS Custom Properties. I’m sure this is just a matter of time to standardize the way to use it with @support rule. If you really need to detect a support for @apply rule, look at the script created by Serg Gospodarets. Serg also published list of great use cases for CSS Mixins on his blog.

I hope you found this overview useful. See you next time :-*

UPDATE!

Tab Atkins Jr officially anounced that the proposal for @apply has been abandoned from various reasons. Learn more details behind this decision here.

There’s plenty more space to experiment here, and while it does suck to lose a tool that you might have gotten excited about, @apply really is just quite a bad idea technically. Let’s solve these problems correctly.

Comments

  • p
    paolo

    What's the current status of @apply? Can we use it now? or is it totally junked "what could have been"?

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Unfortunately that the proposal has been abandoned :(

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
      • p
        paolo

        Oh man that's too bad, i'm very much excited to use css native mixins :(

        👆 you can use Markdown here

        Your comment is awaiting moderation. Thanks!
        • Pawel Grzybek
          Pawel Grzybek

          I am sure there was a great reason to drop it. Look at the bright side — there is a lot new cool things in CSS that is worth to be excited about :)

          👆 you can use Markdown here

          Your comment is awaiting moderation. Thanks!

Leave a comment

👆 you can use Markdown here

Your comment is awaiting moderation. Thanks!