Slide 1

Slide 1 text

PostCSS Beyond preprocessors

Slide 2

Slide 2 text

About fleury.io

Slide 3

Slide 3 text

github.com/leroy-merlin-br

Slide 4

Slide 4 text

Background

Slide 5

Slide 5 text

/* COLORS orange: #FF530D red: #E82C0C */ .sticky-header { background-color: #FF530D; /* ORANGE */ height: 84px; } .content { border-bottom: 1px solid #E82C0C; /* RED */ /* header height */ margin-top: 84px; }

Slide 6

Slide 6 text

github.com/sass/sass

Slide 7

Slide 7 text

CSS with superpowers

Slide 8

Slide 8 text

$font-stack: Helvetica, sans-serif $primary-color: #333 body font: 100% $font-stack color: $primary-color body { font: 100% Helvetica, sans-serif; color: #333; }

Slide 9

Slide 9 text

github.com/less/less.js

Slide 10

Slide 10 text

github.com/stylus/stylus

Slide 11

Slide 11 text

Current scenario

Slide 12

Slide 12 text

github.com/postcss/postcss

Slide 13

Slide 13 text

What is it?

Slide 14

Slide 14 text

“PostCSS is a tool for transforming CSS”

Slide 15

Slide 15 text

.box { box-sizing: border-box; } .box { box-sizing: border-box; }

Slide 16

Slide 16 text

“PostCSS is a tool for transforming CSS with JavaScript plugins”

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

github.com/postcss/autoprefixer .box { box-sizing: border-box; } .box { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; -o-box-sizing: border-box; box-sizing: border-box; } postcss-autoprefixer

Slide 19

Slide 19 text

Under the hood

Slide 20

Slide 20 text

.css Parser Plugins Stringifier .css

Slide 21

Slide 21 text

Anatomy of a plugin live coding

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Getting started

Slide 24

Slide 24 text

postcss: { options: { processors: [ require('autoprefixer')() ] }, dist: { src: 'build' } } github.com/nDmitry/grunt-postcss

Slide 25

Slide 25 text

gulp.task('postcss', function () { var postcss = require('gulp-postcss'); return gulp.src('src/**/*.css') .pipe(postcss([ require('autoprefixer')(), ])) .pipe(gulp.dest('build')); }); github.com/postcss/gulp-postcss

Slide 26

Slide 26 text

module: { loaders: [{ test: /\.css$/, loader: "style-loader!css-loader!postcss-loader" }] }, postcss: function () { return [require('autoprefixer')]; } github.com/postcss/postcss-loader

Slide 27

Slide 27 text

Performance github.com/postcss/benchmark - live coding

Slide 28

Slide 28 text

Ok, what about the features I already have?

Slide 29

Slide 29 text

postcss-simple-vars .menu { width: calc(4 * 200px); } .menu_link { background: #056ef0; width: 200px; } $blue: #056ef0; $column: 200px; $type: 'link'; .menu { width: calc(4 * $column); } .menu_$(type) { background: $blue; width: $column; } github.com/postcss/postcss-simple-vars

Slide 30

Slide 30 text

@for $i from 1 to 3 { .b-$i { width: $(i)px; } } .b-1 { width: 1px } .b-2 { width: 2px } .b-3 { width: 3px } postcss-for github.com/antyakushev/postcss-for

Slide 31

Slide 31 text

.foo { @if 3 < 5 { background: green; } @else { background: blue; } } .foo { background: green; } postcss-conditionals github.com/andyjansson/postcss-conditionals

Slide 32

Slide 32 text

@each $icon in foo, bar, baz { .icon-$(icon) { background: url('$(icon).png'); } } .icon-foo { background: url('foo.png'); } .icon-bar { background: url('bar.png'); } .icon-baz { background: url('baz.png'); } postcss-each github.com/outpunk/postcss-each

Slide 33

Slide 33 text

body { background: color(red a(90%)) } body { background: rgba(255, 0, 0, 0.9) } postcss-color-function (W3C specs) github.com/postcss/postcss-color-function

Slide 34

Slide 34 text

@define-mixin icon $social, $color { .icon-$(social) { color: $color; @mixin-content; } } @mixin icon twitter { background: url(twt.png); } .icon-twitter { color: blue; background: url(twt.png); } postcss-mixin github.com/postcss/postcss-mixin

Slide 35

Slide 35 text

@define-extend list { list-style-type: none; margin: 0; padding: 0; } .default-list { @extend list } .default-list { list-style-type: none; margin: 0; padding: 0; } postcss-extend github.com/travco/postcss-extend

Slide 36

Slide 36 text

.phone { &_title { width: 500px; @media (max-width: 500px) { width: auto; } body.is_dark & { color: white; } } } .phone_title { width: 500px; } @media (max-width: 500px) { .phone_title { width: auto; } } body.is_dark .phone_title { color: white; } postcss-nested github.com/postcss/postcss-nested

Slide 37

Slide 37 text

.test { margin-left: 20px; margin-right: @margin-left; color: red; background: @color url('test.png'); } .test { margin-left: 20px; margin-right: 20px; color: red; background: red url('test.png'); } postcss-property-lookup github.com/simonsmith/postcss-property-lookup

Slide 38

Slide 38 text

But why stopping there?

Slide 39

Slide 39 text

@alias { fs: font-size; fw: font-weight; bg: background; } .foo { fs: 16px; fw: 400; transition: bg 200ms ease; } .foo { font-size: 16px; font-weight: 400; transition: background 200ms ease; } postcss-alias github.com/seaneking/postcss-alias

Slide 40

Slide 40 text

postcss-custom-selectors (W3C specs) github.com/postcss/postcss-custom-selectors @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; }

Slide 41

Slide 41 text

postcss-define-property github.com/daleeidd/postcss-define-property size: $height $width { height: $height; width: $width; } .rectangle { size: 50px 100px; } .rectangle { height: 50px; width: 100px; }

Slide 42

Slide 42 text

postcss-match github.com/rtsao/postcss-match $animal: bear; .zoo { @match $animal { snake => { color: green; }, buffalo | bear => { background: brown; }, lion => { font-weight: bold; } } } .zoo { background: brown; }

Slide 43

Slide 43 text

cssgrace github.com/cssdream/cssgrace .bar { display: inline-block; opacity: .5; } .bar { display: inline-block; *display: inline; *zoom: 1; opacity: .5; filter: alpha(opacity=50); }

Slide 44

Slide 44 text

postcss-js github.com/postcss/postcss-js let prefixer = postcssJs.sync([ autoprefixer ]); let style = prefixer({ border-radius: '10px' }); { -webkit-border-radius: 10px; -moz-border-radius: 10px; -ms-border-radius: 10px; border-radius: 10px; }

Slide 45

Slide 45 text

doiuse (caniuse api) github.com/anandthakker/doiuse .box { transform: scaleX(2) user-select: none; } box.css: line 2, col 3: CSS3 Transforms not supported by: IE (8) box.css: line 3, col 3: CSS user-select: none not supported by: IE (8,9)

Slide 46

Slide 46 text

css-modules atcss postcss-colorblind rtlcss postcss-constants postcss-cssstats csstyle immutable-css postcss.parts

Slide 47

Slide 47 text

What about my libraries?

Slide 48

Slide 48 text

postcss-short github.com/jonathantneal/postcss-short .icon { size: 48px; } .banner { position: fixed 0 0 *; } .icon { width: 48px; height: 48px; } .banner { position: fixed; top: 0; right: 0; left: 0; }

Slide 49

Slide 49 text

postcss-short-border postcss-short-color postcss-short-font-size postcss-short-position postcss-short-size postcss-short-spacing postcss-short-text github.com/jonathantneal/postcss-short

Slide 50

Slide 50 text

cssnext :root { --mainColor: #ffbbaaff; } @custom-media --mobile (width <= 640px); @custom-selector --heading h1, h2, h3, h4, h5, h6; .post-article :--heading { color: color( var(--mainColor) blackness(+20%) ); } @media (--mobile) { .post-article :--heading { margin-top: 0; } } github.com/cssnext/cssnext

Slide 51

Slide 51 text

postcss-color-function postcss-extend postcss-custom-properties postcss-custom-selectors postcss-custom-media github.com/cssnext/cssnext

Slide 52

Slide 52 text

Points for attention

Slide 53

Slide 53 text

Questions?

Slide 54

Slide 54 text

Thanks ( ^◡^)