cssnextから学ぶ次世代CSS


![Kobito.VVEsP2.png](https://qiita-image-store.s3.amazonaws.com/0/35595/4d76a40a-7223-bafb-fb95-2d0b20e22788.png "Kobito.VVEsP2.png")


cssnextとは策定中のCSS仕様を先立って使えるようにするツールのことです。
ひとことで言うとCSS版Babelです。

CSSを変換する仕組みはPostCSSのプラグインとして有志によって作成されています。
cssnextはそのプラグインをまとめたプラグインパックと呼ばれるものです。
※古いブラウザに対応させるためのフォールバック機能を提供するプラグインも含んでいます。

**本記事は策定中のCSSの知識をつけることが目的です**:smile: 


## 参考リンクなど
cssnext（PostCSS）の背景や使い方は先日記事を書いたので是非見てみてください
[Step by Stepで始めるCSSモダン化（PostCSS）](http://qiita.com/howdy39/items/1029e3df24ac42c7bd49)

[playground](http://cssnext.io/playground/)でcssnextが実際にどのように変換するのかを試せます。

## 機能一覧
本記事で紹介する機能一覧を出すのに使ったcssnextのページです。
[postcss-cssnext features](http://cssnext.io/features/)


|機能|プラグイン|仕様|Can I use|
|---|---|---|---|
|automatic vendor prefixes|[autoprefixer](https://github.com/postcss/autoprefixer)|||
|custom properties & `var()`|[postcss-custom-properties](https://github.com/postcss/postcss-custom-properties)|http://www.w3.org/TR/css-variables/|[CSS Variables (Custom Properties)](http://caniuse.com/#feat=css-variables)|
|custom properties set & `@apply`|[postcss-apply](https://github.com/pascalduez/postcss-apply)|https://tabatkins.github.io/specs/css-apply-rule|
|reduced `calc()`|[reduce-css-calc](https://github.com/MoOx/reduce-css-calc)|https://github.com/MoOx/reduce-css-calc#readme|[calc() as CSS unit value](http://caniuse.com/#feat=calc)|
|custom media queries|[postcss-custom-media](https://github.com/postcss/postcss-custom-media)|http://dev.w3.org/csswg/mediaqueries/#custom-mq|
|media queries ranges|[postcss-media-minmax](https://github.com/postcss/postcss-media-minmax)|http://dev.w3.org/csswg/mediaqueries/#mq-ranges|
|custom selectors|[postcss-custom-selectors](https://github.com/postcss/postcss-custom-selectors)|http://dev.w3.org/csswg/css-extensions/#custom-selectors|
|nesting|[postcss-nesting](https://github.com/jonathantneal/postcss-nesting)|http://tabatkins.github.io/specs/css-nesting/|
|`color()` function|[postcss-color-function](https://github.com/postcss/postcss-color-function)|http://dev.w3.org/csswg/css-color/#modifying-colors|
|`hwb()` function|[postcss-color-hwb](https://github.com/postcss/postcss-color-hwb)|http://dev.w3.org/csswg/css-color/#the-hwb-notation|
|`gray()` function|[postcss-color-gray](https://github.com/postcss/postcss-color-gray)|http://dev.w3.org/csswg/css-color/#grays|
|`#rrggbbaa` colors|[postcss-color-hex-alpha](https://github.com/postcss/postcss-color-hex-alpha)|http://dev.w3.org/csswg/css-color/#hex-notation|
|`rgba` function (`rgb` fallback)|[postcss-color-rgba-fallback](https://github.com/postcss/postcss-color-rgba-fallback)|http://www.w3.org/TR/css3-color/|[CSS3 Colors](http://caniuse.com/#feat=css3-colors)|
|`rebeccapurple` color|[postcss-color-rebeccapurple](https://github.com/postcss/postcss-color-rebeccapurple)|http://dev.w3.org/csswg/css-color/#valdef-color-rebeccapurple|
|`font-variant` property|[postcss-font-variant](https://github.com/postcss/postcss-font-variant)|http://dev.w3.org/csswg/css-fonts/#propdef-font-variant|[CSS font-variant-alternates](http://caniuse.com/#feat=font-variant-alternates)|
|`filter` property|[pleeease-filters](https://github.com/iamvdo/pleeease-filters)|http://www.w3.org/TR/filter-effects/|[CSS Filter Effects](http://caniuse.com/#feat=css-filters)|
|`initial` value|[postcss-initial](https://github.com/maximkoretskiy/postcss-initial)|http://www.w3.org/TR/css3-values/#common-keywords|[CSS initial value](http://caniuse.com/#feat=css-initial-value)|
|`rem` unit (`px` fallback)|[node-pixrem](https://github.com/robwierzbowski/node-pixrem)|http://www.w3.org/TR/css3-values/#rem-unit|[rem (root em) units](http://caniuse.com/#feat=rem)|
|`:any-link` pseudo-class|[postcss-pseudo-class-any-link](https://github.com/jonathantneal/postcss-pseudo-class-any-link)|http://dev.w3.org/csswg/selectors/#any-link-pseudo|
|`:matches` pseudo-class|[postcss-selector-matches](https://github.com/postcss/postcss-selector-matches)|http://dev.w3.org/csswg/selectors-4/#matches|[matches() DOM method](http://caniuse.com/#feat=matchesselector)|
|`:not` pseudo-class|[postcss-selector-not](https://github.com/postcss/postcss-selector-NOT)|http://dev.w3.org/csswg/selectors-4/#negation|[selector list argument of :not()](http://caniuse.com/#feat=css-not-sel-list)|
|`::` pseudo syntax (`:` fallback)|[postcss-pseudoelements](https://github.com/axa-ch/postcss-pseudoelements)|http://www.w3.org/TR/css3-selectors/#pseudo-elements|[::selection CSS pseudo-element](http://caniuse.com/#feat=css-selection)|
|`overflow-wrap` property (`word-wrap` fallback)|[postcss-replace-overflow-wrap](https://github.com/MattDiMu/postcss-replace-overflow-wrap)|https://drafts.csswg.org/css-text-3/#propdef-word-wrap|[CSS3 Overflow-wrap](http://caniuse.com/#feat=wordwrap)|
|attribute case insensitive|[postcss-attribute-case-insensitive](https://github.com/Semigradsky/postcss-attribute-case-insensitive)|https://www.w3.org/TR/selectors4/#attribute-case|[Case-insensitive CSS attribute selectors](http://caniuse.com/#feat=css-case-insensitive)|

※2016/09/07時点の機能一覧です。今後増減があると思います。
※`Can I use`が空なのは見つけれなかった。

　　　　　　　　　　　　
## automatic vendor prefixes
ベンダープレフィックスを自動でつけてくれる機能です。

```css:before
div {
  display:flex;
}
```

```css:after
div {
  display:-webkit-box;
  display:-ms-flexbox;
  display:flex;
}
```


## custom properties & `var()`
CSSに変数を導入します。

`:root{}`で定義して、`var()`で使います。

```css:before
:root {
  --myColor: red;
}

div {
  background-color: var(--myColor)
}
```

```css:after
div {
  background-color: red
}
```


## custom properties set & `@apply`
プロパティごと定義を共通化するものです。

`:root{}`で定義して、`@apply`で使います。

```css:before
:root {
  --myBackGroundColor: {
    background-color: red
  }
}

div {
  @apply --myBackGroundColor
}
```

```css:after
div {
  background-color: red}
```


## reduced `calc()`
数値計算を行います。

`calc()`の中に式を書きます。
式に単位が付いていてもOKです。

reduced。。。？一般的な「減らす」の意味じゃないですよね。
> 「整理して簡単な形に変える、まとめる」というしっくり来る説明を[@nyoro_712](http://qiita.com/nyoro_712)さんから貰いました。ありがとうございます。

```css:before
div {
  width: calc(10px + 20);
  min-width: calc(10 * 2px);
  height: calc(100px / 2);
  min-height: calc(10 + 20)px;
}
```

```css:after
div {
  width: 30px;
  min-width: 20px;
  height: 50px;
  min-height: 30px;
}
```


## custom media queries
メディアクエリの定義に名前をつけることができます。

`@custom-media --変数名 〜`で定義して`@media (--変数名)`で使用します。

iPadとかデバイス名指定できるの嬉しいですね。

```css:before
@custom-media --iPad only screen (min-device-width: 768px) and (max-device-width: 1024px);

@media (--iPad) {
  /** css for ipad */
}

```

```css:after
@media only screen (min-device-width: 768px) and (max-device-width: 1024px) {
  /** css for ipad */
}
```


## media queries ranges
不等号を使ってメディアクエリを定義できます。

min, maxに変換してくれます。地味に嬉しい機能。

```css:before
@media (width >= 500px) and (width < 1201px) {
  /* your styles */
}
```

```css:after
@media (min-width: 500px) and (max-width: 1200px) {
  /* your styles */
}
```



## custom selectors
セレクタを定義することができます。

`@custom-selector :--変数名`で定義しておいて`:--変数名`で使用
つなげる事もできます。
大量のセレクタが作れますね。

```css:before
@custom-selector :--header h1, h2, h3, h4;
@custom-selector :--hover :hover;
@custom-selector :--hoge .hoge, .piyo, .fuga;

:--header:--hover:--hoge {
  /* styles */
}
```

```css:after
h1:hover.hoge,
h2:hover.hoge,
h3:hover.hoge,
h4:hover.hoge,
h1:hover.piyo,
h2:hover.piyo,
h3:hover.piyo,
h4:hover.piyo,
h1:hover.fuga,
h2:hover.fuga,
h3:hover.fuga,
h4:hover.fuga {
  /* styles */
}
```


## nesting
Sassでもおなじみのネスト記法が使えます。

```css:before
a {
  color:red;

  & span {
    color: white;
  }
}
```

```css:after
a {
  color:red
}
a span {
  color:white
}
```


## `color()` function
color()関数で色を指定できます。

```css:before
a {
  color: color(red blackness(50%));
}
a:hover {
  color: color(red blackness(50%) whiteness(25%));
}
```

```css:after
a {
  color: rgb(128, 0, 0);
}
a:hover {
  color: rgb(128, 64, 64);
}
```


## `hwb()` function
HWB形式で色指定が可能です。

```css:before
body {
  color: hwb(90, 0%, 0%, 0.5);
}
```

```css:after
body {
  color: rgba(128, 255, 0, 0.5);
}
```

HSLと似ているので比較

### HSL
HSLは色相・彩度・明度（Hue, Saturation, Lightness）
<img src="https://qiita-image-store.s3.amazonaws.com/0/35595/7ce9a91e-65e4-ed59-a995-3184cb515fb6.png" width="150px"></img>

### HWB
HWBは色相・白味・黒味（Hue, Whiteness, Blackness）
<img src="https://qiita-image-store.s3.amazonaws.com/0/35595/d34f721b-32ee-c0f7-a0d1-d35c73b0e99e.png" width="150px"></img>

HWBのが直感的にイメージしやすいと思います。


## `gray()` function
灰色をあらわすための関数が追加。
rgb(),rgba()に変換します。


```css:before
.foo {
  color: gray(85);
}

.bar {
  color: gray(10%, 50%);
}
```

```css:after
.foo {
  color: rgb(85, 85, 85);
}

.bar {
  color: rgba(26, 26, 26, 0.5);
}
```


## `#rrggbbaa` colors
透明度が追加され、#rrggbbaaの形式で定義できます。

`#rgba`でもOK。

```css:before
body {
  background: #9d9c;
  color: #001020ff;
}
```

```css:after
body {
  background: rgba(153, 221, 153, 0.8);
  color: rgba(0, 16, 32, 1);
}
```


## `rgba` function (`rgb` fallback)
rgba()に対応していないIE8のために#rgbに変換します。

これはplaygroundでは有効になっていないみたいです。
[rgbaに対応してないのはもうIE8のみ](http://caniuse.com/#feat=css3-colors)みたいなので外したのかも。


```css:before
body {
  background: rgba(153, 221, 153, 0.8);
  border: solid 1px rgba(100,102,103,.3);
}
```

```css:after
body {
  background: #99dd99;
  background: rgba(153, 221, 153, 0.8);
  border: solid 1px #646667;
  border: solid 1px rgba(100,102,103,.3);
}
```


## `rebeccapurple` color
レベッカパープルという紫色をあらわす指定が追加されます。
[rebeccapurpleがCSS 4 colorに提案された経緯](https://cpplover.blogspot.jp/2014/06/rebeccapurplecss-4-color.html)に経緯がまとまっているので見てみてください:cry: 


```css:before
body {
  color: rebeccapurple;
}
```

```css:after
body {
  color: rgb(102, 51, 153);
}
```



## `font-variant` property
`font-variant-xxx`を`font-feature-settings`の形に変換するらしい。
`font-variant`はなくなるってことなのかな。ちょっとだけ調べてみましたが良くわからなかった。。


```css:before
h2 {
  font-variant-caps: small-caps;
}

table {
  font-variant-numeric: lining-nums;
}
```

```css:after
h2 {
  -webkit-font-feature-settings: "c2sc";
          font-feature-settings: "c2sc";
  font-variant-caps: small-caps;
}

table {
  -webkit-font-feature-settings: "lnum";
          font-feature-settings: "lnum";
  font-variant-numeric: lining-nums;
}
```



## `filter` property
filterに対応していないFirefox35未満でfilterを使えるようにする機能です。

オプションで`oldIE:true`を指定すると古いIEでも使えそうな記述あり。

フィルタ自体は以下記事を参照
[CSSフィルタことはじめ](http://qiita.com/bluebird/items/a3f55206984fa8105e39)

```css:before
.blur {
    filter:sepia(100%);
}
```

```css:after
.blur {
    filter:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><filter id="filter"><feColorMatrix type="matrix" color-interpolation-filters="sRGB" values="0.393 0.769 0.189 0 0 0.349 0.686 0.168 0 0 0.272 0.534 0.131 0 0 0 0 0 1 0" /></filter></svg>#filter');
    -webkit-filter:sepia(100%);
            filter:sepia(100%);
}
```


## `initial` value
スタイルをリセットする事が可能。

この`all: initial`は目玉機能だそうな。
どうもCSSに詳しい人には嬉しい機能らしい。



```css:before
div {
  all: initial; /* use initial for ALL PROPERTIES in one shot */
}
```

```css:after
div {
  -webkit-animation: none 0s ease 0s 1 normal none running;
          animation: none 0s ease 0s 1 normal none running;
  -webkit-backface-visibility: visible;
          backface-visibility: visible;
  background: transparent none repeat 0 0 / auto auto padding-box border-box scroll;
  border: medium none currentColor;
  border-collapse: separate;
  -o-border-image: none;
     border-image: none;
  border-radius: 0;
  border-spacing: 0;
  bottom: auto;
  box-shadow: none;
  box-sizing: content-box;
  caption-side: top;
  clear: none;
  clip: auto;
  color: #000;
  -webkit-columns: auto;
     -moz-columns: auto;
          columns: auto;
  -webkit-column-count: auto;
     -moz-column-count: auto;
          column-count: auto;
  -webkit-column-fill: balance;
     -moz-column-fill: balance;
          column-fill: balance;
  -webkit-column-gap: normal;
     -moz-column-gap: normal;
          column-gap: normal;
  -webkit-column-rule: medium none currentColor;
     -moz-column-rule: medium none currentColor;
          column-rule: medium none currentColor;
  -webkit-column-span: 1;
     -moz-column-span: 1;
          column-span: 1;
  -webkit-column-width: auto;
     -moz-column-width: auto;
          column-width: auto;
  content: normal;
  counter-increment: none;
  counter-reset: none;
  cursor: auto;
  direction: ltr;
  display: inline;
  empty-cells: show;
  float: none;
  font-family: serif;
  font-size: medium;
  font-style: normal;
  font-variant: normal;
  font-weight: normal;
  font-stretch: normal;
  line-height: normal;
  height: auto;
  -webkit-hyphens: none;
      -ms-hyphens: none;
          hyphens: none;
  left: auto;
  letter-spacing: normal;
  list-style: disc outside none;
  margin: 0;
  max-height: none;
  max-width: none;
  min-height: 0;
  min-width: 0;
  opacity: 1;
  orphans: 2;
  outline: medium none invert;
  overflow: visible;
  overflow-x: visible;
  overflow-y: visible;
  padding: 0;
  page-break-after: auto;
  page-break-before: auto;
  page-break-inside: auto;
  -webkit-perspective: none;
          perspective: none;
  -webkit-perspective-origin: 50% 50%;
          perspective-origin: 50% 50%;
  position: static;
  right: auto;
  -moz-tab-size: 8;
    -o-tab-size: 8;
       tab-size: 8;
  table-layout: auto;
  text-align: left;
  -moz-text-align-last: auto;
       text-align-last: auto;
  text-decoration: none;
  text-indent: 0;
  text-shadow: none;
  text-transform: none;
  top: auto;
  -webkit-transform: none;
          transform: none;
  -webkit-transform-origin: 50% 50% 0;
          transform-origin: 50% 50% 0;
  -webkit-transform-style: flat;
          transform-style: flat;
  -webkit-transition: none 0s ease 0s;
  transition: none 0s ease 0s;
  unicode-bidi: normal;
  vertical-align: baseline;
  visibility: visible;
  white-space: normal;
  widows: 2;
  width: auto;
  word-spacing: normal;
  z-index: auto;
  all: initial; /* use initial for ALL PROPERTIES in one shot */
}
```


## `rem` unit (`px` fallback)
remに対応していないIE8のためにpxを追加してくれます。

rem自体は以下記事を参照
[remってなに？](http://qiita.com/elly/items/da92e63641760a69a3be)

```css:before
h1 {
  font-size: 1.5rem;
}
```

```css:after
h1 {
  font-size: 24px;
  font-size: 1.5rem;
}
```



## `:any-link` pseudo-class
`:link`, `:visited`を1つの定義で可能にします。


```css:before
nav :any-link {
  background-color: yellow;
}
```

```css:after
nav :link,nav :visited {
  background-color: yellow;
}
```

## `:matches` pseudo-class
セレクタをグルーピングできます。

```css:before
p:matches(:first-child, .special) {
  color: red;
}
```

```css:after
p:first-child, p.special {
  color: red;
}
```

## `:not` pseudo-class
matchesの`:not`版です。

```css:before
p:not(:first-child, .special) {
  color: red;
}
```

```css:after
p:not(:first-child):not(.special) {
  color: red;
}
```

## `::` pseudo syntax (`:` fallback)
IE8のために`::`を`:`に変換します。

IE8はもう死んだんだ。

```css:before
a::before {
}
```

```css:after
a:before {
}
```

## `overflow-wrap` property (`word-wrap` fallback)
`overflow-wrap`を`word-wrap`に変換します。

```css:before
body {
  overflow-wrap: break-word;
}
```

```css:after
body {
  word-wrap: break-word;
}
```

## attribute case insensitive
大文字小文字を無視する属性セレクタのオプション`i`が追加。

```css:before
[attr=abc i] {
  border-style: solid none;
}
```

```css:after
[attr=abc],[attr=Abc],[attr=aBc],[attr=ABc],[attr=abC],[attr=AbC],[attr=aBC],[attr=ABC] {
  border-style: solid none;
}
```

## あとがき
Sassだ、LESSだ、Stylusだ、Compassだ、cssnextだ、とCSS界隈もかなり混沌としている気がします:sweat: 
いつかCSSだけで済む日が来るといいですね:smile: