かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Gulp Stylusでautoprefixerを使うメモ

nibだけだと今は不要になってるベンダープレフィックスも出力してしまうのでautoprefixerを使って対象ブラウザをコントロールするメモ

node: v9.6.1
npm: v6.1.0

gulp@3.9.1
gulp-stylus@2.7.0
gulp-autoprefixer@2.3.1
nib@1.1.2

install

$ npm install --save-dev gulp-autoprefixer

stylusで使用するならautoprefixer-stylusというパッケージもあるみたいで、中身はautoprefixerを使っているので問題ないと思うのだけれど、最終アップデートが1年前だったのでgulp-autoprefixerを使うことにしました。

gulpfile.js

"use strict";
const gulp    = require('gulp'),
      plumber = require('gulp-plumber'),
      stylus  = require('gulp-stylus'),
      nib     = require('nib'),
      prefix  = require('gulp-autoprefixer');

const devDir = './dev',
      destDir = './webroot';

// task
gulp.task('stylus', function() {
  let files = devDir + '/stylus/main.styl',
      destPath = destDir + '/assets/css';

  return gulp.src( files )
    .pipe( plumber() )
    .pipe( stylus({
      import: ['nib'],
      use:    [nib()],
      compress: false,
      linenos:  false
    }) )
    .pipe( prefix({
      browsers: ['last 2 versions', '> 1% in JP', 'ie >= 10']
      cascade: false
    }) )
    .pipe( gulp.dest( destPath ) );
});

gulp-autoprefixer browsers オプションで対応ブラウザを指定する

autoprefixerbrowsers オプションで対応させるブラウザを配列で複数指定ができます。
上記の

browsers: ['last 2 versions', '> 1% in JP', 'ie >= 10']

は「最新の2バージョン、日本で1%以上のシェア、IE10以上に対応」という感じです。

対象ブラウザはbrowserl.istでチェックすることが出来ます。(, 区切りで複数条件もチェックできるっぽいです)
オプションの詳細はbrowserslist - Githubで確認ができるのですが、gulp-autoprefixerのバージョンのせいなのかちゃんと調べてはないのですが、last 2 major versionsnot ie <= 8といったオプションだとエラーになってコンパイルできませんでした。

コンパイル結果

Stylus

::selection
  background: #A5EFD2

main
  a
    transition: all .25s
    opacity: 1
    user-select: none
    &:hover
      opacity: .6
      transform: scale(.9, .9)

.flex
  display: flex

1. nibだけ (autoprefixer) 無しの時

::selection {
  background: #a5efd2;
}
main a {
  -webkit-transition: all 0.25s;
  -moz-transition: all 0.25s;
  -o-transition: all 0.25s;
  -ms-transition: all 0.25s;
  transition: all 0.25s;
  opacity: 1;
  -ms-filter: none;
  filter: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
main a:hover {
  opacity: 0.6;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
  filter: alpha(opacity=60);
  -webkit-transform: scale(0.9, 0.9);
  -moz-transform: scale(0.9, 0.9);
  -o-transform: scale(0.9, 0.9);
  -ms-transform: scale(0.9, 0.9);
  transform: scale(0.9, 0.9);
}
.flex {
  display: -webkit-box;
  display: -moz-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: box;
  display: flex;
}

2. autoprefixer使用時

::-moz-selection {
  background: #a5efd2;
}
::selection {
  background: #a5efd2;
}
main a {
  transition: all 0.25s;
  opacity: 1;
  -ms-filter: none;
  filter: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
main a:hover {
  opacity: 0.6;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
  filter: alpha(opacity=60);
  transform: scale(0.9, 0.9);
}
.flex {
  display: -ms-flexbox;
  display: box;
  display: flex;
}

新しく足りてないベンダープレフィックスが追加され、不要なベンダープレフィックスが削除されてスッキリしました!
状況としてはnibで色々ベンダープレフィックスが出力されて、その後でautoprefixerがゴニョゴニョしてるという感じです。display: flexに関してはnibdisplay: box;が出力されてしまい、 次のような

You should write display: flex by final spec instead of display: box

display: boxではなく、display: flexを使ってねというメッセージが出てdisplay: box;は削除されず残ったままになりました。

最近のブラウザだと結構ベンダープレフィックス不要になっていたのですね... 自動コンパイルで放置してたから気づいていませんでした...

gulp-autoprefixerにベンダープレフィックス付きのプロパティのインデントを整形するcascadeオプションがあるのですが、nibでベンダープレフィックスが出力されてしまっていると整形(cascade: true)は効かないようです。
実際に使用する場合はmin化とかしてしまうと思うので、まぁ気にするほどではないと思いますが。(オプション効かない気持ち悪さはあります)
 

autoprefixer-stylus の場合

折角なのでgulp-autoprefixerではなくautoprefixer-stylusも試してみました。

gulpfile.js

"use strict"
const prefix = require('autoprefixer-stylus');

// task
gulp.task('stylus', function() {
  let files = devDir + '/stylus/main.styl',
      destPath = destDir + '/assets/css';

  return gulp.src( files )
    .pipe( plumber() )
    .pipe( stylus({
      import: ['nib'],
      use: [nib(), prefix({
        browsers: ['last 2 versions', '> 1% in JP', 'ie >= 10'],
        cascade: true
      })],
      compress: false,
      linenos:  false
    }) )
    .pipe( gulp.dest( destPath ) );
});

autoprefixer-stylus の場合stylusのuse内に処理を書けばOK。
同様のstylusをコンパイルしてみます。

コンパイル結果

Stylus

::selection
  background: #A5EFD2

main
  a
    transition: all .25s
    opacity: 1
    user-select: none
    &:hover
      opacity: .6
      transform: scale(.9, .9)

.flex
  display: flex

::-moz-selection {
  background: #a5efd2;
}
::selection {
  background: #a5efd2;
}
main a {
  -webkit-transition: all 0.25s;
  transition: all 0.25s;
  opacity: 1;
  -ms-filter: none;
  -webkit-filter: none;
          filter: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
main a:hover {
  opacity: 0.6;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
  filter: alpha(opacity=60);
  -webkit-transform: scale(0.9, 0.9);
  transform: scale(0.9, 0.9);
}
.flex {
  display: -webkit-box;
  display: -ms-flexbox;
  display: box;
  display: flex;
}

cascadeオプションは効いています。
display: flexに関してはnibで出力されるdisplay: boxのせいで長めのメッセージが表示されて少しびっくりしますが問題なくコンパイルは動作します。
ただ、gulp-autoprefixerと同じブラウザの指定なのですが出力されるベンダープレフィックスに違いが... ξ(Ծ‸Ծ)ξ
(どっちが正しいんだ...
 
個人的にstylus以外にしたときにも使えそうなのでgulpで使用するならgulp-autoprefixerで良いかな〜という気がしました。
nibでdisplay: boxを出力しないオプションが有るのか知りたい...


[参考]

HTML5 & CSS3 デザインレシピ集

HTML5 & CSS3 デザインレシピ集