第5章 現場で使える実践Sassテクニック

5-5 PostCSSでSassをさらに便利にする

PostCSS とは

npm install --save-dev gulp-postcss
var gulp = require('gulp');
var sass = require('gulp-sass');
var sassGlob = require('gulp-sass-glob');
var sourcemaps = require('gulp-sourcemaps');
var plumber = require('gulp-plumber');
var notify = require("gulp-notify");
var postcss = require('gulp-postcss'); //①「gulp-postcss」を読み込み
.pipe(postcss([autoprefixer()]))

ベンダープレフィックスを自動付与する

インストールと設定

npm install --save-dev autoprefixer
var gulp = require('gulp');
var sass = require('gulp-sass');
var sassGlob = require('gulp-sass-glob');
var sourcemaps = require('gulp-sourcemaps');
var plumber = require('gulp-plumber');
var notify = require("gulp-notify");
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer'); //①「autoprefixer」を読み込み

gulp.task('sass', function() {
  return gulp.src('./sass/**/*.scss')
    .pipe(plumber({errorHandler: notify.onError(
    "Error: <%= error.message %>")}))
    .pipe(sourcemaps.init())
    .pipe(sassGlob())
    .pipe(sass({outputStyle: 'expanded'}))
    .pipe(postcss([autoprefixer()])) //②「sass」の後に指定
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('./css'));
});
.box {
    display: flex;
    justify-content: space-between;
    background: linear-gradient(to bottom, white, black);
    transition: all .5s;
}
.box {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: justify;
     -ms-flex-pack: justify;
         justify-content: space-between;
  background: -webkit-gradient(linear, left top, left bottom, from(white), to(black));
  background: linear-gradient(to bottom, white, black);
  -webkit-transition: all .5s;
  transition: all .5s;
}

対象ブラウザを設定する

    .pipe(postcss([autoprefixer(autoprefixer({browsers: ['last 1 versions']})]))
.box {
  display: -webkit-box;
  display: flex;
  -webkit-box-pack: justify;
          justify-content: space-between;
  background: linear-gradient(to bottom, white, black);
  transition: all .5s;
}
    .pipe(postcss([autoprefixer(autoprefixer({browsers: ['last 1 versions, ie 10']})]))
    .pipe(postcss([autoprefixer(autoprefixer({browsers: ['> 2%']})]))

画像名だけで画像のパスやサイズを取得する

インストールと設定

npm install --save-dev postcss-assets
var gulp = require('gulp');
var sass = require('gulp-sass');
var sassGlob = require('gulp-sass-glob');
var sourcemaps = require('gulp-sourcemaps');
var plumber = require('gulp-plumber');
var notify = require("gulp-notify");
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer');
var assets = require('postcss-assets'); //①「postcss-assets」を読み込み

gulp.task('sass', function() {
  return gulp.src('./sass/**/*.scss')
    .pipe(plumber({errorHandler: notify.onError(
    "Error: <%= error.message %>")}))
    .pipe(sourcemaps.init())
    .pipe(sassGlob())
    .pipe(sass({outputStyle: 'expanded'}))
    .pipe(postcss([assets({ //②「sass」の後に指定
      loadPaths: ['images/'] //③「loadPaths」に画像ディレクトリを指定(本書ではimages)
    })]))
    .pipe(postcss([autoprefixer()]))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('./css'));
});

画像パスを取得する

.image {
    background-image: resolve('logo.png');
}
.image {
  background-image: url('/images/logo.png');
}
    .pipe(postcss([assets({
      loadPaths: ['images/', './icons', './banners'] //③「loadPaths」に画像ディレクトリを指定(本書ではimages)
    })]))

.image {
    background-image: resolve('logo.png');
    background-image: resolve('star.svg');
    background-image: resolve('campaign.jpg');
}
.image {
  background-image: url('/images/logo.png');
  background-image: url('/icons/star.svg');
  background-image: url('/banners/campaign.jpg');
}
    .pipe(postcss([assets({
      loadPaths: ['images/', './icons', './banners'],
      relative: true //「relative: true」を追加
    })]))
.image {
  background-image: url('../images/logo.png');
  background-image: url('../icons/star.svg');
  background-image: url('../banners/campaign.jpg');
}
    .pipe(postcss([assets({
      loadPaths: ['images/', './icons', './banners'],
      baseUrl: 'http://example.com/wp-content/themes/' //「baseUrl」を追加
    })]))
.image {
  background-image: url('http://example.com/wp-content/themes/images/logo.png');
  background-image: url('http://example.com/wp-content/themes/icons/star.svg');
  background-image: url('http://example.com/wp-content/themes/banners/campaign.jpg');
}

画像サイズを取得する

.image {
    width: width('logo.png'); //①横幅を取得
    height: height('logo.png'); //②縦幅を取得
    background-size: size('logo.png'); //③縦横を取得
}
.image {
  width: 284px;
  height: 200px;
  background-size: 284px 200px;
}
.imagex2 {
    width: width('logo.png', 2);
    height: height('logo.png', 2);
    background-size: size('logo.png', 2);
}
.imagex2 {
  width: 142px;
  height: 100px;
  background-size: 142px 100px;
}

画像をインライン化する

.image {
    background-image: inline('logo.png');
}
.image {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAWIhgX+1...(略)...njh/P/U7OX3MieEOt6hjCO9QDqh74fxSlH5cNdLBCAAAAAElFTkSuQmCC');
}

CSSプロパティの記述順を自動でソートする

npm install --save-dev css-declaration-sorter
var gulp = require('gulp');
var sass = require('gulp-sass');
var sassGlob = require('gulp-sass-glob');
var sourcemaps = require('gulp-sourcemaps');
var plumber = require('gulp-plumber');
var notify = require("gulp-notify");
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer');
var assets = require('postcss-assets');
var cssdeclsort = require('css-declaration-sorter'); //①「css-declaration-sorter」を読み込み

gulp.task('sass', function() {
  return gulp.src('./sass/**/*.scss')
    .pipe(plumber({errorHandler: notify.onError("Error: <%= error.message %>")}))
    .pipe(sourcemaps.init())
    .pipe(sassGlob())
    .pipe(sass({outputStyle: 'expanded'}))
    .pipe(postcss([cssdeclsort({order: 'smacss'})])) //②「sass」の後に指定
    .pipe(postcss([assets({
      loadPaths: ['./images']
    })]))
    .pipe(postcss([autoprefixer()]))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('./css'));
});
.test {
    color: #C55;
    display: flex;
    justify-content: space-between;
    border: 0;
    background: #eee;
    transition: all .5s;
    animation: none;
}
.test {
  display: flex;
  justify-content: space-between;
  border: 0;
  background: #eee;
  color: #C55;
  animation: none;
  transition: all .5s;
}

並び替えオーダーの種類

.pipe(postcss([cssdeclsort({customOrder: 'mycustom.json'})]))

バラバラになったメディアクエリをまとめてコード量を削減してスッキリさせる

npm install --save-dev css-mqpacker
var gulp = require('gulp');
var sass = require('gulp-sass');
var sassGlob = require('gulp-sass-glob');
var sourcemaps = require('gulp-sourcemaps');
var plumber = require('gulp-plumber');
var notify = require("gulp-notify");
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer');
var assets = require('postcss-assets');
var cssdeclsort = require('css-declaration-sorter');
var mqpacker = require('css-mqpacker'); //①「css-mqpacker」を読み込み

gulp.task('sass', function() {
  return gulp.src('./sass/**/*.scss')
    .pipe(plumber({errorHandler: notify.onError("Error:<%= error.message %>")}))
    .pipe(sourcemaps.init())
    .pipe(sassGlob())
    .pipe(sass({outputStyle: 'expanded'}))
    .pipe(postcss([mqpacker()])) //②「sass」の後に指定
    .pipe(postcss([cssdeclsort({order: 'smacss'})]))
    .pipe(postcss([assets({
      loadPaths: ['./images']
    })]))
    .pipe(postcss([autoprefixer()]))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('./css'));
})
.list {
    width: 380px;
    @media screen and (min-width: 768px) {
        width: 50%;
    }
    @media screen and (min-width: 480px) {
        width: 100%;
    }
}

.banner {
    width: 800px;
    @media screen and (min-width: 768px) {
        width: 500px;
    }
    @media screen and (min-width: 480px) {
        width: 100%;
    }
}
.list {
  width: 380px;
}

@media screen and (min-width: 768px) {
  .list {
    width: 50%;
  }
}

@media screen and (min-width: 480px) {
  .list {
    width: 100%;
  }
}

.banner {
  width: 800px;
}

@media screen and (min-width: 768px) {
  .banner {
    width: 500px;
  }
}

@media screen and (min-width: 480px) {
  .banner {
    width: 100%;
  }
}
.list {
  width: 380px;
}
.banner {
  width: 800px;
}

@media screen and (min-width: 768px) {
  .list {
    width: 50%;
  }
  .banner {
    width: 500px;
  }
}

@media screen and (min-width: 480px) {
  .list {
    width: 100%;
  }
  .banner {
    width: 100%;
  }
}