Pro Yearly is on sale from $80 to $50! »

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. PostCSS ͱ͸Կ͔ Yoshihide Jimbo @ Kaizen Platform, Inc. Grand-Frontend-Osaka 2015

    Summer 2015/08/22
  2. @jmblog Front-end engineer Remote worker Yoshihide Jimbo

  3. None
  4. Agenda 1. PostCSS ͱ͸ 2.PostCSS Ͱग़དྷΔ͜ͱ 3.PostCSS ͷύϑΥʔϚϯε 4.PostCSS ͷ࢖͍ಓ

    5.PostCSS ͷ͜Ε͔ΒΛ༧ଌ
  5. 1. PostCSS ͱ͸

  6. τϨϯυ

  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
  8. None
  9. None
  10. None
  11. https:/ /twitter.com/mdo/status/591364406816079873

  12. PostCSS ͱ͸

  13. CSS PostCSS new CSS PostCSS ͱ͸ PostCSS is a tool

    for transforming CSS with JS plugins.
  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 ͱ͸
  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 ͱ͸
  16. PostCSS ͱ͸ CSS Parser CSS Node Tree API Source Map

    Generator Node Tree Stringifier • PostCSS ຊମʹؚ·ΕΔͷ͸ɺ࣍ͷ 4 ͭͷػೳɻ CSS Λύʔεͯ͠ɺϊʔυπϦʔʢASTʣ ʹม׵ ϊʔυπϦʔΛૢ࡞͢Δ API Λఏڙ Source map Λੜ੒ ϊʔυπϦʔΛจࣈྻʹ࠶ม׵ • PostCSS ୯ମ͚ͩ͸ CSS ʹରͯ͠มߋ͸Ұ੾Ճ͑ͳ͍ɻ
  17. • CSS ʹର͢Δ༷ʑͳมߋ͸ɺϓϥάΠϯ͕ߦ͏ɻ • ϓϥάΠϯͷ࢓૊Έγϯϓϧɻ୯ͳΔ JS ͷ function Ͱɺ֤ϓϥάΠϯ͸ ϊʔ

    υπϦʔΛड͚औΓɺಛఆͷϊʔυΛಡΈ͜ΜͩΓɺෆཁͳϊʔυΛऔΓআ͍ͨ Γɺ৽͍͠ϊʔυΛ௥Ճ͢Δɻͦͯ͠ɺมߋΛՃ͑ͨϊʔυπϦʔΛ return ͠ ͯɺ࣍ͷϓϥάΠϯʹड͚౉͢ɻ • ֤ϓϥάΠϯ͸୯ػೳͷΈ࣋ͭΑ͏ΨΠυϥΠϯͰਪ঑͞Ε͍ͯΔɻैͬͯɺҰ ͭҰͭͷϓϥάΠϯ͸খ͍͞΋ͷ͕ଟ͍ɻ • ΍Γ͍ͨ͜ͱʹԠͯ͡ɺ༷ʑͳϓϥάΠϯΛ૊Έ߹Θͤͯར༻͢Δ͜ͱʹͳΔɻ ϓϥάΠϯͱ͸
  18. ஫ҙ • ʮPostCSSʯͱ͍͏ݴ༿͸ɺπʔϧຊମΛࢦ͍ͯ͠Δ৔߹ͱɺϓϥάΠϯΛؚ ΊͨΤίγεςϜશମΛࢦ͍ͯ͠Δ৔߹ͱɺಛఆͷϓϥάΠϯ͚ͩΛࢦ͍ͯ͠Δ ৔߹͕͋ΔɻίϯςΩετʹؾΛ͚ͭΑ͏ɻ • Postprocessor ʢϙετϓϩηοαʔʣͱ͍͏ݴ༿͕ͨ·ʹग़ͯ͘Δ͕ɺ PostCSS ͕ग़དྷΔ͜ͱ͸

    Postprocessing ʹݶఆ͞Εͳ͍ɻ࣮ଶͱ߹Θͣɺ PostCSS νʔϜ΋࢖͏ͷΛ΍ΊͨͷͰ๨ΕΑ͏ɻɹ (›°□°ʣ›ớ ᵲᴸᵲ
  19. 2. PostCSS Ͱग़དྷΔ͜ͱ

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

    ExtensionsɹɹSass ͷΑ͏ͳಠ֦ࣗு • FallbacksɹɹϑΥʔϧόοΫʢޙํޓ׵ʣ • Optimizationsɹɹ࠷దԽ • Analysisɹɹ෼ੳ • OthersɹɹͳͲͳͲ
  21. Future CSS Syntax W3CͰ࢓༷ࡦఆதͷ࣍ੈ୅ CSS ͷઌऔΓ

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

    color: var(--color); } div { color: red; } https:/ /github.com/postcss/postcss-custom-properties Lj IN OUT
  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
  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
  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
  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
  27. cssnext Future CSS Syntax ܥϓϥάΠϯ܈Λ 1 ͭʹ·ͱΊͯ࢖͍΍ͨ͘͢͠ϓϥάΠϯύοΫɻ CSS ൛ͷ Babel

    Έ͍ͨͳ΋ͷɻ
  28. cssnext Ͱ΋ŋŋŋ࢖͍͍ͨϓϥάΠϯ͸ cssnext ܦ༝Ͱ͸ͳ͘ݸผͰ࢖ͬͨ΄͏͕͍͍͔΋ʁ https:/ /github.com/postcss/postcss/issues/477

  29. Language Extensions Sass ͷΑ͏ͳಠ֦ࣗு

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

    green; } @else { background: blue; } } .foo { background: green; } https:/ /github.com/andyjansson/postcss-conditionals Lj IN OUT
  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
  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
  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
  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
  35. PreCSS Sass ʹࣅͨߏจΛॻ͚ΔΑ͏ʹ͢ΔͨΊͷϓϥάΠϯύοΫ

  36. Fallbacks ϑΥʔϧόοΫʢޙํޓ׵ʣ

  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
  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
  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
  40. Optimization ࠷దԽ

  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
  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
  43. cssnano minifyɺoptimize ܥͷϓϥάΠϯ܈Λ 1 ͭʹͨ͠ϓϥάΠϯύοΫ

  44. Others ͦͷଞ

  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
  46. stylelint Modern CSS linter

  47. Fun ͓༡ͼ

  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
  49. ؆୯ͳϓϥάΠϯͷίʔυྫ

  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) + ')"' }); } }); }; }); ؆୯ͳϓϥάΠϯͳΒ͜Ε͙Β͍ͷίʔυྔͰॻ͚ͯ͠·͏ɻ
  51. PostCSS.parts PostCSS ͷϓϥάΠϯΛݕࡧͰ͖ΔαΠτ

  52. github.com/postcss/postcss README ʹ΋ΧςΰϦʔ෼͚͞ΕͨϓϥάΠϯͷϦετ͕͋Δ

  53. 3. PostCSS ͷύϑΥʔϚϯε

  54. Preprocessors

  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 ഒۙ͘଎͍
  56. Vendor Prefixers

  57. Vendor Prefixers Compass 59ms 2564ms (43.2x slower) * Autoprefixer Compass

    ΑΓ΋ 43 ഒҎ্଎͍ PostCSS*
  58. ͜͜·Ͱͷ·ͱΊ

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

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

  61. Sass ΍ Less ͷ୅ΘΓͱͯ͠࢖͏

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

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

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

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

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

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

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

    ·ͣ͸ Sass Λ࢖͍ͳ͕Β Autoprefixer, cssnano Λಋೖͯ͠ΈΔɻಛʹ Autoprefixer ͸࢖ͬͯଛ͸ͳ͍ɻͱ͍͏͔ɺඞਢΞΠςϜɻ .pipe( sass() ) .pipe( postcss([ require('autoprefixer'), require('cssnano') ]) )
  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') ]) )
  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') ]) )
  71. ݱ࣮తͳ࢖͍ํ • ͨͩ͠ɺ͜ΕΒ͸͋͘·Ͱɺଉͷ௕͍ຊ൪ͷϓϩμΫτͰ࠾༻͢Δ৔߹ɻݸਓత ͳϓϩδΣΫτͰ͸ɺࡉ͔͍͜ͱ͸ؾʹͤͣʹɺศརͩͱࢥͬͨϓϥάΠϯ͸Ͳ ΜͲΜ࢖ͬͯɺΑ͔ͬͨ͜ͱ΋ѱ͔ͬͨ͜ͱ΋ίϛϡχςΟʹϑΟʔυόοΫ͠ ͍͖ͯ·͠ΐ͏ɻࣗ෼ͰϓϥάΠϯΛ࡞ͬͯެ։ͯ͠΋͍͍Ͱ͠ΐ͏ɻͦ͏΍ͬ ͯ Web ͷະདྷ͸࡞ΒΕ͍͖ͯ·͢ɻ

  72. 4. PostCSS ͷ͜Ε͔ΒΛ༧ଌ

  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
  74. • Sass ͸ Bootstrap 4 ͕ Less ͔ΒҠߦͨ͜͠ͱͰ Preprocessor ͷதͰ͸ൈ͖

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

  76. Work with us! ҰॹʹੈքΛ KAIZEN ͢ΔϝϯόʔΛٻΊ͍ͯ·͢ʂ

  77. Be a Growth Hacker! άϩʔεϋοΧʔͱͯ͠վળҊΛఏҊͯ͠ใुΛ֫ಘ͠·ͤΜ͔ʁ

  78. Thanks!