CSSNext

Use the Latest CSS syntax today

How do we get these future features?

  • CSS Next
  • PostCSS
  • Webpack

Webpack

What is Webpack?

Asset Bundler

Its takes a config, where you define your app's entry point and output point, and it builds your bundle.

How does it work?

It has a number of different `loaders` you can use to define how different types of files should be processed

PostCSS & CSSNext

cssnext is a PostCSS plugin that transforms future CSS syntax to browser compatible syntax.

cssNext Playground

http://cssnext.io/playground/

PostCSS has a lot of CSS transforming plugins and can run on all of the popular task runners and bundlers

Use the PostCSS-loader to load the PostCSS-CSSNext plugin

You get it for free in the JS stack

npm i -g ldsjs --registry http://icsnpm.ldschurch.org

Why should we want to use CSSNext?

Better investment of learning.

More likely to withstand the test of time.

What CSS features do we get with CSSNext?

CSS Vars

custom properties

Problem Space

You want the same property value on multiple elements. But you don't want to hard code the value everywhere.

Native Solution

.title {
    color: #123456;
}

.side__header {
    color: #123456;
}

.footer__header {
    color: #123456;
}

SCSS Solution

$main-color: #123456

.title {
    color: $main-color;
}

.side__header {
    color: $main-color;
}

.footer__header {
    color: $main-color;
}

CSS Next Solution

:root {
    --main-color: #123456;
}

.title {
    color: var(--main-color);
}

.side__header {
    color: var(--main-color);
}

.footer__header {
    color: var(--main-color);
}

Gotchas

All vars are global and on the :root.

Can't do scoped vars.

Can't use them in media queries

set & @apply

Problem Space

You have a set of properties that you want to reuse on multiple element. 

You don't want to repeat them.

Native Solution

.button {
    border: solid 1px #123456;
    color: white;
    padding: .5em;
}

.success {
    border-color: green;
}

.error {
    border-color: red;
}

<button class="button success" />

<button class="button error" />

SCSS Solution

.button {
    border: solid 1px #123456;
    color: white;
    padding: .5em;
}

.button__success {
    @extend .button;
    border-color: green;
}

.button__error {
    @extend .button;
    border-color: red;
}

CSS Next Solution

:root {
    --button: {
        border: solid 1px #123456;
        color: white;
        padding: .5em;
    }
}

.button__success {
    @apply --button;
    border-color: green;
}

.button__error {
    @apply --button;
    border-color: red;
}

Gotchas

Must define them in the :root.

custom media queries

Problem Space

You want to use the same widths for your media queries across your app.

You want to use a variable instead.

Native Solution

@media (max-width: 30em) {
    //some style
}

...

@media (max-width: 30em) {
    //some style for a different component
}

SCSS Solution

$small-screens: 30em;

@media (max-width: $small-screens) {
    //some style
}

...

@media (max-width: $small-screens) {
    //some style for a different component
}

CSS Next Solution

@custom-media  --small-screens (max-width: 30em);

@media (--small-screens) {
    //some style
}

...

@media (--small-screens) {
    //some style for a different component
}

Gotchas

Must include both the range and the value.

custom Selectors

Problem Space

Selectors as a variable

Native Solution

h1, h2, h3, h4, h5, h6 {
    //styles
}

...

h1, h2, h3, h4, h5, h6 {
    // more styles
}

SCSS Solution

$headers: h1, h2, h3, h4, h5, h6;

//sass interpolation
#{headers} {
    //styles
}

...

#{headers} {
    // more styles
}

CSS Next Solution

@custom-selector :--headers h1, h2, h3, h4, h5, h6;

:--headers {
    //styles
}

...

:--headers {
    // more styles
}

Compound Custom Selectors

@custom-selector :--button button, .button;
@custom-selector :--enter :hover, :focus;

:--button:--enter {

}

//output
button:hover,
.button:hover,
button:focus,
.button:focus {

}

Gotchas

nesting

Problem Space

Want to select sub elements of a component.

Don't want to type out the full BEM class of an element.

Native Solution

.header {
    //styles
}

.header__search {
    //styles
}

.header__search--error {
    //styles
}

Native Solution

.header {
    //styles
}

.header p {
    //styles
}

.header p a {
    //styles
}

SCSS Solution

.header {
    //styles
    &__search{
        //styles
        &--error{
            //styles
        }
    }
}

SCSS Solution

.header {
    //styles
    p {
        //styles
        a {
            //styles
        }
    }
}

CSS Next Solution

.header {
    //styles
    &__search{
        //styles
        &--error{
            //styles
        }
    }
}

CSS Next Solution

.header {
    //styles
    p {
        //styles
        a {
            //styles
        }
    }
}

Gotchas

//invalid
.foo{
    .bar &{
        //style
    }
}

//valid
.foo{
    @nest .bar &{
        //style
    }
}

// output
// .bar .foo

:not()

multiple arguments

Problem Space

When you want to filter something from your selection.

Currently you can't give :not() multiple arguments.

Native Solution

<nav>
    <ol>
        <li class="nav__item"></li>
        <li class="nav__item"></li>
        <li class="nav__item"></li>
        <li class="nav__item"></li>
    </ol>
</nav>

//style
.nav__item {
    margin-bottom: .5em;
}
.nav__item:last-child,
.nav__item--active {
    margin-bottom: 0;
}

SCSS Solution

<nav>
    <ol>
        <li class="nav__item"></li>
        <li class="nav__item"></li>
        <li class="nav__item"></li>
        <li class="nav__item"></li>
    </ol>
</nav>

//style
.nav__item {
    margin-bottom: .5em;
}
.nav__item:last-child,
.nav__item--active {
    margin-bottom: 0;
}

CSS Next Solution

<nav>
    <ol>
        <li class="nav__item"></li>
        <li class="nav__item"></li>
        <li class="nav__item"></li>
        <li class="nav__item"></li>
    </ol>
</nav>

//style
.nav__item:not(:last-child, nav__item--active) {
    margin-bottom: .5em;
}

Gotchas

CSSNext

By Matthew Poulson

CSSNext

  • 789