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
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