CSS PREPROCESSORS OF BOTH WORLDS
A presentation at From The Front and the Temple of DOM in September 2014 in Bologna, Metropolitan City of Bologna, Italy by Gunnar Bittersmann
 
                CSS PREPROCESSORS OF BOTH WORLDS
 
                CSS PREPROCESSORS
 
                OF BOTH WORLDS
 
                COFFEE GRINDERS OUT OF YOUR BEANS Peugeot Coffee grinder 98 € PICK Kalita Coffee grinder 76 € PICK Heyde Coffee grinder 54 € PICK
 
                 
                .product-list { … } .product-item { … } .product-image { … } .product-brand { … } .product-model { … } .product-description { … } .product-price { … } .btn { … } .btn-cta { … }
 
                COFFEE GRINDERS OUT OF YOUR BEANS In your basket: Peugeot Coffee grinder 98 € Kalita Coffee grinder 76 € total amount 174 € BUY
 
                 
                .product-list { … } .product-item { … } .product-image { … } .product-brand { … } .product-model { … } .product-description { … } .product-price { … } .btn { … } .btn-cta { … } .checkout-list { … } .checkout-item { … } .checkout-image { … } .checkout-brand { … } .checkout-model { … } .checkout-description { … } .checkout-price { … }
 
                 
                 
                #page-products .product-list { … } #page-products .product-list li { … } #page-products .product-list .product-image { … } #page-products .product-list .brand { … } #page-products .product-list .model { … } #page-products .product-list .description { … } #page-products .product-list .price { … } #page-products .product-list button { … } #page-checkout .product-list { … } #page-checkout .product-list li { … } #page-checkout .product-list .product-image { … } #page-checkout .product-list .brand { … } #page-checkout .product-list .model { … } #page-checkout .product-list .description { … } #page-checkout .product-list .price { … }
 
                #page-products { ⁝ .product-list { ⁝ li { … } .product-image { … } .brand { … } .model { … } .description { … } .price { … } button { … } } } nesting
 
                #page-checkout { ⁝ .product-list { ⁝ li { … } .product-image { … } .brand { … } .model { … } .description { … } .price { … } } } nesting
 
                @import “_page-products”; @import “_page-checkout”; ⁝ modularization
 
                @import “_colors”; @import “_type”; @import “_image-replacement”; @import “_page-layout”; @import “_page-products”; @import “_page-checkout”; ⁝ modularization
 
                Atomic design (Brad Frost)
 
                Atomic design (Brad Frost) ATOMS MOLECULES ORGANISMS TEMPLATES PAGES
 
                Look ma, no classes!
 
                 
                #page-products { ⁝ .product-list { ⁝ li { … } [property=”image”] { … } [property=”brand”] { … } [property=”model”] { … } [property=”description”] { … } [property=”price”] { … } button { … } } }
 
                 
                One more cup of coffee, please! <html lang=”en”> <h1>One more cup of coffee, please!</h1>
 
                ONE MORE CUP OF COFFEE, PLEASE! <html lang=”en”> <h1 class=”uppercase”>One more cup of coffee, please!</h1> .uppercase { text-transform: uppercase }
 
                one more cup of coffee, please! <html lang=”en”> <h1 class=”lowercase”>One more cup of coffee, please!</h1> .uppercase { text-transform: uppercase } .lowercase { text-transform: lowercase }
 
                UN’ ALTRA TAZZA DI CAFFÈ, PER FAVORE! <html lang=”it”> <h1 class=”uppercase”>Un’ altra tazza di caffè, per favore!</h1> .uppercase { text-transform: uppercase } .lowercase { text-transform: lowercase }
 
                un’ altra tazza di caffè, per favore! <html lang=”it”> <h1 class=”lowercase”>Un’ altra tazza di caffè, per favore!</h1> .uppercase { text-transform: uppercase } .lowercase { text-transform: lowercase }
 
                NOCH EIN TÄSSCHEN KAFFEE, BITTE! <html lang=”de”> <h1 class=”uppercase”>Noch ein Tässchen Kaffee, bitte!</h1> .uppercase { text-transform: uppercase } .lowercase { text-transform: lowercase }
 
                noch ein tässchen kaffee, bitte! <html lang=”de”> <h1 class=”lowercase”>Noch ein Tässchen Kaffee, bitte!</h1> .uppercase { text-transform: uppercase } .lowercase { text-transform: lowercase }
 
                Noch ein Tässchen Kaffee, bitte! <html lang=”de”> <h1 class=”lowercase”>Noch ein Tässchen Kaffee, bitte!</h1> .uppercase { text-transform: uppercase } .lowercase { text-transform: lowercase } .lowercase:lang(de) { text-transform: none } ✘
 
                PRESENTATIONAL MARKUP
 
                Noch ein Tässchen Kaffee, bitte! <html lang=”de”> <h1>Noch ein Tässchen Kaffee, bitte!</h1> h1 { text-transform: lowercase } h1:lang(de) { text-transform: none } ✔
 
                QA’VIN LATLH TU’LUM HINOBNES! <html lang=”tlh”> <h1>qa’vIn latlh tu’lum HInobneS!</h1> h1 { text-transform: uppercase }
 
                qa’vin latlh tu’lum hinobnes! <html lang=”tlh”> <h1>qa’vIn latlh tu’lum HInobneS!</h1> h1 { text-transform: lowercase }
 
                qa’vIn latlh tu’lum HInobneS! <html lang=”tlh”> <h1>qa’vIn latlh tu’lum HInobneS!</h1> h1 { text-transform: lowercase } :lang(tlh) { text-transform: none !important} ✔
 
                 
                 
                 
                 
                 
                 
                 
                Structure (HTML/DOM) Presentation (CSS) Behavior (JavaScript)
 
                Separation of concerns Structure (HTML/DOM) Presentation (CSS) Behavior (JavaScript)
 
                SEND ORDER CHANGE ADDRESS OOCSS CHANGE BASKET <button type=”submit” class=”btn btn-large btn-red”>send order</button> <button type=”button” class=”btn btn-small btn-black”>change address</button> <button type=”button” class=”btn btn-small btn-black”>change basket</button>
 
                SEND ORDER CHANGE ADDRESS CHANGE BASKET <button type=”submit” class=”btn btn-large btn-red”>send order</button> <button type=”button” class=”btn btn-small btn-black”>change address</button> <button type=”button” class=”btn btn-small btn-black”>change basket</button>
 
                Stylesheet .btn { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; } .btn-large { padding: 0.375em; font-size: 1.25rem; } OOCSS .btn-small { padding: 0.25em font-size: 1rem; } .btn-red { background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); } .btn-black { background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…); }
 
                Object Oriented CSS CSS “object”: a repeating visual pattern, which can be abstracted into an independent snippet of HTML, CSS, and possibly JavaScript. Goal: reusable code, maintainability, performance OOCSS Principles: 1. Separate structure and skin 2. Separate container and content Means: • class selectors • no element type selectors • no ID selectors • no descendant combinators • presentational classes in the mark-up
 
                Markup { class attribute btn class selector } <button> “CSS classes” { btn-large } OOCSS <button> { btn-small <button> } { btn-red } { btn-black } Stylesheet min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; padding: 0.375em; font-size: 1.25rem; padding: 0.25em font-size: 1rem; background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…);
 
                Markup { class attribute btn class selector } <button> “CSS classes” { btn-large } OOCSS <button> { btn-small <button> } { btn-red } { btn-black } Stylesheet min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; padding: 0.375em; font-size: 1.25rem; padding: 0.25em font-size: 1rem; background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…);
 
                PRESENTATIONAL MARKUP
 
                 
                 
                OOCSS
 
                “CSS CLASSES”
 
                 
                 
                Object Oriented CSS CSS “object”: a repeating visual pattern, which can be abstracted into an independent snippet of HTML, CSS, and possibly JavaScript. Goal: reusable code, maintainability, performance OOCSS Principles: 1. Separate structure and skin 2. Separate container and content Means: • class selectors • no element type selectors • no ID selectors • no descendant combinators • presentational classes in the mark-up
 
                 
                Pros • • • • reusable code units smaller CSS file selector specificity selector performance OOCSS Cons • presentational markup • bigger HTML files
 
                 
                Pros Cons • reusable code units • presentational markup • bigger HTML files • selector specificity • selector performance OOCSS
 
                 
                Pros Cons • reusable code units • presentational markup • bigger HTML files OOCSS • selector performance
 
                 
                Pros Cons • reusable code units • presentational markup • bigger HTML files OOCSS
 
                Markup { btn } <button> { btn-large } OOCSS <button> { btn-small <button> } { btn-red } { btn-black } Stylesheet min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; padding: 0.375em; font-size: 1.25rem; padding: 0.25em font-size: 1rem; background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…);
 
                Markup btn Stylesheet { } <button> { btn-large } <button> { btn-small } <button> { btn-red } { btn-black } min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; padding: 0.375em; font-size: 1.25rem; padding: 0.25em font-size: 1rem; background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…);
 
                Markup btn Stylesheet { } <button> { btn-large } <button> { btn-small } <button> { btn-red } { btn-black } min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; padding: 0.375em; font-size: 1.25rem; padding: 0.25em font-size: 1rem; background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…);
 
                mixins [type=”submit”] { } @include btn; @include btn-large; @include btn-red; [type=”button”] { } @include btn; @include btn-small; @include btn-black; @mixin btn { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; } @mixin btn-large { padding: 0.375em; font-size: 1.25rem; } @mixin btn-small { padding: 0.25em font-size: 1rem; } @mixin btn-red { background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); } @mixin btn-black { background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…); }
 
                mixins [type=”submit”] { } @include btn; @include btn-large; @include btn-red; [type=”button”] { } @include btn; @include btn-small; @include btn-black; <button type=”submit”>send order</button> <button type=”button”>change address</button> <button type=”button”>change basket</button> @mixin btn { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; } @mixin btn-large { padding: 0.375em; font-size: 1.25rem; } @mixin btn-small { padding: 0.25em font-size: 1rem; } @mixin btn-red { background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); } @mixin btn-black { background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…); }
 
                [type=”submit”] { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; [type=”submit”] { } @include btn; @include btn-large; @include btn-red; [type=”button”] { } @include btn; @include btn-small; @include btn-black; padding: 0.375em; font-size: 1.25rem; } background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); [type=”button”] { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; padding: 0.25em; font-size: 1rem; } background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…);
 
                extends [type=”submit”] { @extend .btn; @extend .btn-large; @extend .btn-red; } [type=”button”] { @extend .btn; @extend .btn-small; @extend .btn-black; } .btn { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; } .btn-large { padding: 0.375em; font-size: 1.25rem; } .btn-small { padding: 0.25em font-size: 1rem; } .btn-red { background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); } .btn-black { background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…); }
 
                extends [type=”submit”] { @extend .btn; @extend .btn-large; @extend .btn-red; } [type=”button”] { @extend .btn; @extend .btn-small; @extend .btn-black; } .btn, [type=”submit”], [type=”button”] { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; } .btn-large, [type=”submit”] { padding: 0.375em; font-size: 1.25rem; } .btn-small, [type=”button”] { padding: 0.25em font-size: 1rem; } .btn-red, [type=”submit”] { background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); } .btn-black, [type=”button”] { background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…); }
 
                extends [type=”submit”] { @extend .btn; @extend .btn-large; @extend .btn-red; } [type=”button”] { @extend .btn; @extend .btn-small; @extend .btn-black; } <button type=”submit”>send order</button> <button type=”button”>change address</button> <button type=”button”>change basket</button> .btn, [type=”submit”], [type=”button”] { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; } .btn-large, [type=”submit”] { padding: 0.375em; font-size: 1.25rem; } .btn-small, [type=”button”] { padding: 0.25em font-size: 1rem; } .btn-red, [type=”submit”] { background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); } .btn-black, [type=”button”] { background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…); }
 
                placeholders [type=”submit”] { @extend %btn; @extend %btn-large; @extend %btn-red; } [type=”button”] { @extend %btn; @extend %btn-small; @extend %btn-black; } %btn { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; } %btn-large { padding: 0.375em; font-size: 1.25rem; } %btn-small { padding: 0.25em font-size: 1rem; } %btn-red { background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); } %btn-black { background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…); }
 
                placeholders [type=”submit”] { @extend %btn; @extend %btn-large; @extend %btn-red; } [type=”button”] { @extend %btn; @extend %btn-small; @extend %btn-black; } [type=”submit”], [type=”button”] { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; } [type=”submit”] { padding: 0.375em; font-size: 1.25rem; } [type=”button”] { padding: 0.25em font-size: 1rem; } [type=”submit”] { background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); } [type=”button”] { background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…); }
 
                placeholders [type=”submit”] { @extend %btn; @extend %btn-large; @extend %btn-red; } [type=”button”] { @extend %btn; @extend %btn-small; @extend %btn-black; } [type=”submit”], [type=”button”] { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; } [type=”submit”] { padding: 0.375em; font-size: 1.25rem; } [type=”button”] { padding: 0.25em font-size: 1rem; } [type=”submit”] { background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); } [type=”button”] { background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…); }
 
                Markup Sass { %btn } <button> { %btn-large } <button> { %btn-small } <button> { %btn-red } { %btn-black } min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; CSS padding: 0.375em; font-size: 1.25rem; padding: 0.25em font-size: 1rem; background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…);
 
                %btn { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; } #page-checkout [type=”submit”] { @extend %btn; @extend %btn-large; @extend %btn-red; } #page-checkout [type=”button”] { @extend %btn; @extend %btn-small; @extend %btn-black; } #page-other [type=”submit”] { @extend %btn; @extend %btn-small; @extend %btn-red; } %btn-large { padding: 0.375em; font-size: 1.25rem; } %btn-small { padding: 0.25em font-size: 1rem; } %btn-red { background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); } %btn-black { background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…); }
 
                SEND ORDER CHANGE ADDRESS CHANGE BASKET <button type=”submit” id=”ctrl-send-order”>send order</button> <button type=”button” id=”ctrl-change-address”>change address</button> <button type=”button” id=”ctrl-change-basket”>change basket</button>
 
                #ctrl-send-order { @extend %btn; @extend %btn-large; @extend %btn-red; } #ctrl-change-address, #ctrl-change-basket { @extend %btn; @extend %btn-small; @extend %btn-black; } %btn { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; } %btn-large { padding: 0.375em; font-size: 1.25rem; } %btn-small { padding: 0.25em font-size: 1rem; } %btn-red { background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); } %btn-black { background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…); }
 
                mixins and extends @mixin btn { min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; } %btn { @include btn; } @mixin %btn-large { padding: 0.375em; font-size: 1.25rem; } %btn-large { @include btn-large; } ⁝
 
                 
                 
                OOSass nesting modularization mixins extends placeholders
 
                 
                PRESENTATIONAL MARKUP
 
                Separation of concerns Structure (HTML/DOM) Presentation (CSS) Behavior (JavaScript)
 
                Markup btn Stylesheet { } <button> { btn-large } <button> { btn-small } <button> { btn-red } { btn-black } min-width: 8rem; font-family: “League Gothic”; text-align: center; border-radius: 0.375em; padding: 0.375em; font-size: 1.25rem; padding: 0.25em font-size: 1rem; background-color: hsl(2, 42%, 39%); background-image: linear-gradient(…); background-color: hsl(0, 0%, 20%); background-image: linear-gradient(…);
 
                 
                WHICH SIDE ARE YOU ON?
 
                