PostCSS とは何か

PostCSS とは何か

関西フロントエンドUG 主催「Grand-Frontend-Osaka 2015 Summer」での発表資料です。

http://kfug.github.io/events/2015/grandfrontendosaka/

790f55ccde7a62df8f25747586657090?s=128

Yoshihide Jimbo

August 22, 2015
Tweet

Transcript

  1. 3.
  2. 7.

    770,000 downloads in the last month with npm grunt-cli: 890,000

    downloads Less: 1,050,000 downloads gulp: 1,861,631 downloads
  3. 8.
  4. 9.
  5. 10.
  6. 13.

    CSS PostCSS new CSS PostCSS ͱ͸ PostCSS is a tool

    for transforming CSS with JS plugins.
  7. 14.

    CSS new CSS Parser Stringifier var gulp = require('gulp'); var

    postcss = require('gulp-postcss'); gulp.task('css', function() { gulp.src('./src/**/*.css') .pipe(postcss([])) .pipe(gulp.dest('./dest')) }); PostCSS ͱ͸
  8. 15.

    Lj Plugin Parser Stringifier var gulp = require('gulp'); var postcss

    = require('gulp-postcss'); gulp.task('css', function() { var plugins = [ require('postcss-plugin1'), require("postcss-plugin2") ]; gulp.src('./src/**/*.css') .pipe(postcss(plugins)) .pipe(gulp.dest('./dest')) }); CSS new CSS Lj Plugin PostCSS ͱ͸
  9. 16.

    PostCSS ͱ͸ CSS Parser CSS Node Tree API Source Map

    Generator Node Tree Stringifier • PostCSS ຊମʹؚ·ΕΔͷ͸ɺ࣍ͷ 4 ͭͷػೳɻ CSS Λύʔεͯ͠ɺϊʔυπϦʔʢASTʣ ʹม׵ ϊʔυπϦʔΛૢ࡞͢Δ API Λఏڙ Source map Λੜ੒ ϊʔυπϦʔΛจࣈྻʹ࠶ม׵ • PostCSS ୯ମ͚ͩ͸ CSS ʹରͯ͠มߋ͸Ұ੾Ճ͑ͳ͍ɻ
  10. 17.

    • CSS ʹର͢Δ༷ʑͳมߋ͸ɺϓϥάΠϯ͕ߦ͏ɻ • ϓϥάΠϯͷ࢓૊Έγϯϓϧɻ୯ͳΔ JS ͷ function Ͱɺ֤ϓϥάΠϯ͸ ϊʔ

    υπϦʔΛड͚औΓɺಛఆͷϊʔυΛಡΈ͜ΜͩΓɺෆཁͳϊʔυΛऔΓআ͍ͨ Γɺ৽͍͠ϊʔυΛ௥Ճ͢Δɻͦͯ͠ɺมߋΛՃ͑ͨϊʔυπϦʔΛ return ͠ ͯɺ࣍ͷϓϥάΠϯʹड͚౉͢ɻ • ֤ϓϥάΠϯ͸୯ػೳͷΈ࣋ͭΑ͏ΨΠυϥΠϯͰਪ঑͞Ε͍ͯΔɻैͬͯɺҰ ͭҰͭͷϓϥάΠϯ͸খ͍͞΋ͷ͕ଟ͍ɻ • ΍Γ͍ͨ͜ͱʹԠͯ͡ɺ༷ʑͳϓϥάΠϯΛ૊Έ߹Θͤͯར༻͢Δ͜ͱʹͳΔɻ ϓϥάΠϯͱ͸
  11. 20.

    PostCSS Ͱग़དྷΔ͜ͱ • Future CSS SyntaxɹɹW3CͰ࢓༷ࡦఆதͷ࣍ੈ୅ CSS ͷઌऔΓ • Language

    ExtensionsɹɹSass ͷΑ͏ͳಠ֦ࣗு • FallbacksɹɹϑΥʔϧόοΫʢޙํޓ׵ʣ • Optimizationsɹɹ࠷దԽ • Analysisɹɹ෼ੳ • OthersɹɹͳͲͳͲ
  12. 22.

    ม਺ (CSS Variables) :root { --color: red; } div {

    color: var(--color); } div { color: red; } https:/ /github.com/postcss/postcss-custom-properties Lj IN OUT
  13. 23.

    ΧελϜηϨΫλʔ @custom-selector :--heading h1, h2, h3, h4, h5, h6; article

    :--heading + p { margin-top: 0; } article h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { margin-top: 0; } https:/ /github.com/postcss/postcss-custom-selectors Lj IN OUT
  14. 24.

    Color ؔ਺ body { background: color(red a(90%)) } body {

    background: rgba(255, 0, 0, 0.9) } https:/ /github.com/postcss/postcss-color-function Lj IN OUT
  15. 25.

    ϑΟϧλʔ .blur { filter: blur(4px); } .blur { filter: url('data:image/svg+xml;utf8,<svg

    xmlns="http:// www.w3.org/2000/svg"><filter id="filter"><feGaussianBlur stdDeviation="4" /></filter></svg>#filter'); filter: blur(4px); } https:/ /github.com/iamvdo/pleeease-filters Lj IN OUT
  16. 26.

    :matches ٖࣅΫϥε p:matches(:first-child, .special) { color: red; } p:first-child, p.special

    { color: red; } https:/ /github.com/postcss/postcss-selector-matches Lj IN OUT
  17. 30.

    @if จ .foo { @if 3 < 5 { background:

    green; } @else { background: blue; } } .foo { background: green; } https:/ /github.com/andyjansson/postcss-conditionals Lj IN OUT
  18. 31.

    Sass ͬΆ͍ม਺ $blue: #056ef0; $column: 120px; .menu_link { background: $blue;

    width: $column; } .menu_link { background: #056ef0; width: 200px; } https:/ /github.com/postcss/postcss-simple-vars Lj IN OUT
  19. 32.

    @for จ @for $i from 1 to 3 { .b-$i

    { width: $(i)px; } } .b-1 { width: 1px } .b-2 { width: 2px } .b-3 { width: 3px } https:/ /github.com/antyakushev/postcss-for Lj IN OUT
  20. 33.

    @mixin @define-mixin icon $network, $color: blue { .icon.is-$(network) { color:

    $color; @mixin-content; } } @mixin icon twitter { background: url(twt.png); } .icon.is-twitter { color: blue; background: url(twt.png); } https:/ /github.com/postcss/postcss-mixins Lj IN OUT
  21. 34.

    ωετ .phone { &_title { width: 500px; body.is_dark & {

    color: white; } } } .phone_title { width: 500px; } body.is_dark .phone_title { color: white; } https:/ /github.com/postcss/postcss-nested Lj IN OUT
  22. 37.

    Autoprefixer a { display: flex; } a { display: -webkit-box;

    display: -webkit-flex; display: -ms-flexbox; display: flex } https:/ /github.com/postcss/autoprefixer Lj IN OUT
  23. 38.

    opacity for IE8 .foo { opacity: .5; } .foo {

    opacity: .5; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; } https:/ /github.com/iamvdo/postcss-opacity Lj IN OUT
  24. 39.

    rgba() for IE8 body { background: rgba(153, 221, 153, 0.8);

    } body { background: #99DD99; background: rgba(153, 221, 153, 0.8); } https:/ /github.com/postcss/postcss-color-rgba-fallback Lj IN OUT
  25. 41.

    Reduce calc() h1 { font-size: calc(16px * 2); height: calc(100px

    - 2em); } h1 { font-size: 32px; height: calc(100px - 2em) } https:/ /github.com/postcss/postcss-calc Lj IN OUT
  26. 42.

    Reduce @charset rule .foo { color: red; } @charset "Shift_JIS";

    ... @charset "Shift_JIS"; ... @charset "Shift_JIS"; .foo { color: red; } ... https:/ /github.com/hail2u/postcss-single-charset Lj IN OUT
  27. 45.

    ࣗಈ੔ܗ .class, #id { color : blue; border :solid #ddd

    1px} .class, #id { color: blue; border: 1px solid #ddd; } https:/ /github.com/morishitter/cssfmt Lj IN OUT
  28. 48.

    British English ͰίʔυΛॻ͚ΔΑ͏ʹ body { background-colour: grey !please; transparency: 0.3;

    text-align: centre; text-transform: capitalise; } body { background-color: gray !important; opacity: 0.7; text-align: center; text-transform: capitalize; } https:/ /github.com/HashanP/postcss-spiffing Lj IN OUT
  29. 50.

    ྫʣOpacity fallbacks for IE8 var postcss = require('postcss'); module.exports =

    postcss.plugin('postcss-opacity', function () { return function (css) { css.eachDecl(function(decl) { if (decl.prop === 'opacity') { decl.parent.insertAfter(decl, { prop: '-ms-filter', value: '"progid:DXImageTransform.Microsoft.Alpha(Opacity=' + (parseFloat(decl.value) * 100) + ')"' }); } }); }; }); ؆୯ͳϓϥάΠϯͳΒ͜Ε͙Β͍ͷίʔυྔͰॻ͚ͯ͠·͏ɻ
  30. 55.

    Preprocessors PostCSS* LibSass Less Stylus Ruby Sass 36ms 136ms (3.8x

    slower) 160ms (4.4x slower) 167ms (4.6x slower) 1084ms (30.1x slower) * postcss-nested + postcss-simple-vars + postcss-calc + postcss-mixins C++ Ͱॻ͔Εͨ LibSass ΑΓ΋ 4 ഒۙ͘଎͍
  31. 59.

    ͜͜·Ͱͷ·ͱΊ • PostCSS ͸ CSS ʹ͍Ζ͍ΖͳมߋΛՃ͑ΔͨΊͷπʔϧɻ • ༷ʑͳϓϥάΠϯ͕ଘࡏ͍ͯ͠Δɻ • ࣍ੈ୅

    CSS ΛઌऔΓͯ͠ॻ͚ΔΑ͏ʹ΋ͳΔ͠ɺSass ͱಉ͡Α͏ͳίʔυΛॻ ͘͜ͱ΋Ͱ͖Δ͠ɺ࠷దԽ΍෼ੳɺࣗಈ੔ܗͳΜ͔΋Ͱ͖Δɻ • طଘͷπʔϧͱൺ΂ͯ΋ύϑΥʔϚϯεʹ༏Ε͍ͯΔɻ
  32. 62.

    • ύϑΥʔϚϯεʹ༏Ε͍ͯΔɻ • Sass Ͱ͸೉͍͠ಠࣗػೳ֦ு΋Մೳɻ • Sass ͱͷޓ׵ੑ͸ͳ͍ͷͰɺطଘͷ SCSS ϑΝΠϧ͕ͦͷ··࢖͑ΔΘ͚Ͱ

    ͸ͳ͍ɻ • ֦ு͗͢͠ΔͱɺΦϨΦϨ Preprocesser ʹͳͬͯ͠·͍ɺϝϯςφϯείε τ΋͔͔Δ͠ɺ৽نϝϯόʔͷֶशίετ΋͔͔Δɻ Sass ΍ Less ͷ୅ΘΓͱͯ͠࢖͏ ϝϦοτ σϝϦοτ PreCSS ͳͲΛར༻͢Δ
  33. 64.

    • Ҡߦίετ͕͔͔Δɻ͚ͲɺͦΖͦΖͦͷίετΛ෷ͬͯ΋͍͍ࠒ߹͍͡Όͳ ͍͔ͱݸਓతʹ͸ࢥ͍·͢ɻ Compass ͷ୅ΘΓͱͯ͠࢖͏ ϝϦοτ σϝϦοτ • ύϑΥʔϚϯεʹ༏Ε͍ͯΔɻ40ഒҎ্ʂ •

    mixin Ͱ͸ͳ͘ૉͷ CSS Ͱίʔυ͕ॻ͚Δɻ • Compass ͸2015೥1݄Ҏ߱ɺ΄ͱΜͲ։ൃ͕ࢭ·ͬͯΔ༷ࢠɻͦΖͦΖΦϫίϯʁ Autoprefixer ΍ Fallback ܥϓϥάΠϯΛར༻͢Δ
  34. 66.

    • Preprocessor ʹґଘͤͣ ૉͷ CSS ͱͯ͠ɺม਺ͳͲͷศརػೳ͕࢖͑Δɻ • ES2015(ES6) ͱҧͬͯɺ࢓༷ࡦఆ͸΄ͱΜͲ͕ Editor's

    Draft ͷஈ֊ɻ • ·ͩ·ͩ࢓༷͕มߋ͞ΕΔՄೳੑ͸͋Δɻ • ࢓༷͕มߋ͞ΕΔͱɺͦͷରԠ͕ඞཁʹͳͬͯ͘Δɻ͔͠΋ɺར༻͍ͯ͠Δϓϥ άΠϯ͕৽͍͠࢓༷ʹ͍ͭରԠ͢Δͷ͔ɺ͋Δ͍͸ݹ͍࢓༷΋ಉ࣌ʹαϙʔτ͠ ͯ͘ΕΔ͔Ͳ͏͔͸ɺ࡞ऀ࣍ୈɻ • ΋͏গ͠࢓༷͕҆ఆ͔ͯ͠Βಋೖͯ͠΋͍͍Μ͡Όͳ͍͔ͱݸਓతʹ͸ࢥ͏ɻ ࣍ੈ୅ CSS ΛઌऔΓ͢Δ ϝϦοτ σϝϦοτ nextcss ͳͲΛར༻͢Δ
  35. 68.

    ݱ࣮తͳ࢖͍ํ • PostCSS ͸ Grunt, Gulp, webpack ͳͲओཁͳϏϧυπʔϧʹରԠ͍ͯ͠Δͷ ͰɺطଘͷϏϧυϑϩʔʹಋೖ͠΍͍͢ɻ •

    ·ͣ͸ Sass Λ࢖͍ͳ͕Β Autoprefixer, cssnano Λಋೖͯ͠ΈΔɻಛʹ Autoprefixer ͸࢖ͬͯଛ͸ͳ͍ɻͱ͍͏͔ɺඞਢΞΠςϜɻ .pipe( sass() ) .pipe( postcss([ require('autoprefixer'), require('cssnano') ]) )
  36. 69.

    ݱ࣮తͳ࢖͍ํ • ঃʑʹɺଞͷϓϥάΠϯ΋ࢼͯ͠ΈΔɻFallback ܥ ΍ Optimization ܥɺ CSSfmt ͳͲ͸ɺݩͷ Sass

    ϑΝΠϧΛॻ͖׵͑ΔҠߦίετ͕͔͔Βͳ͍ͷ Ͱɺಋೖ͠΍͍͢ɻ .pipe( sass() ) .pipe( postcss([ require('autoprefixer'), require('postcss-will-change'), require('postcss-selector-not'), require('postcss-selector-matches'), require('cssnano') ]) )
  37. 70.

    ݱ࣮తͳ࢖͍ํ • খ͞Ίͷ৽͍͠ϓϩδΣΫτͰ͸ɺ࣮ݧతʹ Sass Λ࢖Θͣ PostCSS ͚ͩͰॻ ͍ͯΈΔͷ΋Ұͭͷબ୒ࢶɻͦͷ৔߹ɺSass ͱಉ౳ͷػೳΛ͢΂ͯ࢖͓͏ͱͤ ͣɺඞཁ࠷௿ݶͷ΋ͷ͚ͩ࠾༻ͨ͠΄͏͕Α͍ɻ

    .pipe( postcss([ require('postcss-simple-vars'), require('autoprefixer'), require('postcss-will-change'), require('postcss-selector-not'), require('postcss-selector-matches'), require('cssnano') ]) )
  38. 73.

    • 2015೥ 8݄ 19೔ʹެ։ɻ • SCSS Parser ͕ਖ਼ࣜʹϦϦʔε͞Εͨɻ • ͜ΕʹΑΓɺCSS

    ϑΝΠϧ͚ͩͰͳ͘ɺSCSS ϑΝΠϧ΋ PostCSS Ͱॲཧ͢Δ ࣄ͕Ͱ͖ΔΑ͏ʹɻʢͨͩ͠ɺPostCSS Ͱ SCSS Λ CSS ʹίϯύΠϧͰ͖Δ Α͏ʹͳͬͨΘ͚Ͱ͸ͳ͍ɻʣ • ͜Ε·Ͱ͸ʮSass → CSS → PostCSS → new CSSʯ͔͠Ͱ͖ͳ͔͕ͬͨɺ
 ͜Ε͔Β͸ʮSass → PostCSS → new Sass → CSS → PostCSS → new CSSʯΈ͍ͨͳϑϩʔ΋Մೳʹɻ • SCSS Λ௚઀ Autoprefixer ʹ͔͚ͨΓɺcssfmt Ͱࣗಈ੔ܗͨ͠Γɺstylelint ͰίʔυνΣοΫͨ͠Γɻ όʔδϣϯ5.0
  39. 74.

    • Sass ͸ Bootstrap 4 ͕ Less ͔ΒҠߦͨ͜͠ͱͰ Preprocessor ͷதͰ͸ൈ͖

    Μग़ͨײ͕͋Δɻ΋͏͠͹Β͘ Sass ͸ϝδϟʔͳଘࡏͰ͋Γଓ͚ͦ͏ɻ • PostCSS ͸ SCSS ϑΝΠϧΛ Parse Ͱ͖ΔΑ͏ʹͳͬͨ͜ͱͰɺSass ͱ͏· ͘ڞଘ͠ͳ͕ΒਐԽ͍ͯ͘͠ؾ഑ɻ • ͨͩ͠ɺPostCSS ͸ Preprocessor ͱͯ͠΋࢖͑Δ͠ɺଞͷ࢖͍ํ΋Ͱ͖Δͷ ͰɺՄೳੑ͸ Sass ͱൺ΂ͯඇৗʹେ͖͍ɻ • ͞Βʹɺγϯϓϧͳ࢓૊ΈͰɺ͏·͘ΤίγεςϜΛ࡞Γ্͍͛ͯΔͷͰɺਐԽ ͷεϐʔυ͕΋ͷ͘͢͝ૣ͍ɻ • ͱ͍͏Θ͚Ͱɺؾ͚ͮ͹ Sass Λۦஞͯ͠͠·ͬͯΔɺͱ͍͏͜ͱ΋͋Δ͔΋ Ͷɻ PostCSS vs Sass?
  40. 78.