Slide 1

Slide 1 text

CSS Preprocessors Presented by / Michael Trythall @mtrythall for slides & code samples http://git.io/729TEQ

Slide 2

Slide 2 text

Hello I'm Mike Head of UX at Front-end + Design for >15 years Using CSS preprocessors for ~2 years Lincoln Loop

Slide 3

Slide 3 text

Following Along Slides, examples, and more at http://git.io/729TEQ

Slide 4

Slide 4 text

Trying the Examples or http://sassmeister.com/ g e m i n s t a l l s a s s and s a s s f i l e

Slide 5

Slide 5 text

kthx let's go

Slide 6

Slide 6 text

What are CSS Preprocessors? Think CoffeeScript for CSS, sorta kinda

Slide 7

Slide 7 text

Why use a CSS preprocessor?

Slide 8

Slide 8 text

What's out there? and are the big dogs Sass LESS

Slide 9

Slide 9 text

What's the Difference?

Slide 10

Slide 10 text

Sass/SCSS Ruby-powered Has Used by designers and FE folks Very friendly syntax More features than other preprocessors Ecosystem better for building custom things Docs complete but not pretty Compass

Slide 11

Slide 11 text

LESS JavaScript-powered Has Used by lots of people, but mostly Bootstrap users Stranger syntax than Sass/SCSS Fewer, but enough, features Ecosystem better for building Bootstrappy things Docs complete (enough) and very pretty Bootstrap

Slide 12

Slide 12 text

Alright, what can they do?

Slide 13

Slide 13 text

Nesting h e a d e r { f o n t - s i z e : 5 e m ; . t i t l e { / / h e a d e r . t i t l e { f o n t - s i z e : 1 0 e m ; } f o n t - s i z e : 1 0 e m ; a { / / h e a d e r . t i t l e a { b a c k g r o u n d : g r e e n ; c o l o r : w h i t e ; } b a c k g r o u n d : g r e e n ; c o l o r : w h i t e ; } } } h e a d e r { f o n t - s i z e : 5 e m ; } h e a d e r . t i t l e { f o n t - s i z e : 1 0 e m ; } h e a d e r . t i t l e a { b a c k g r o u n d : g r e e n ; c o l o r : w h i t e ; }

Slide 14

Slide 14 text

Parent References a { c o l o r : b l u e ; & : h o v e r { / / a : h o v e r c o l o r : y e l l o w ; } } a { n a v & { / / n a v a c o l o r : g r e e n ; } } a { c o l o r : b l u e ; } a : h o v e r { c o l o r : y e l l o w ; } n a v a { c o l o r : g r e e n ; }

Slide 15

Slide 15 text

Imports Non-blocking, single file imports @ i m p o r t " b a s e " ; / * A u t h o r e d D e p e n d e n c i e s * / @ i m p o r t " m i x i n s " ; @ i m p o r t " p a r t i a l s " ; @ i m p o r t " u t i l i t y " ; / / g e n e r a l c l a s s e s u s e d b y e v e r y t h i n g / * P a t t e r n s * / @ i m p o r t " g l o b a l / e l e m e n t s " ; / / c o m m o n e l e m e n t s , h e a d e r , a n c h o r s , t a b l e , e t c @ i m p o r t " g l o b a l / f o r m s " ; @ i m p o r t " g l o b a l / c o m p o n e n t s " ; / / s p e c i a l d e s i g n c o m p o n e n t s , n o n - i n t e r a c t i v e w i d g e t s @ i m p o r t " g l o b a l / w i d g e t s " ; / / a n y c o m p o n e n t w i t h i n t e r a c t i v i t y o r I O / * S t r u c t u r e * / @ i m p o r t " g l o b a l / l a y o u t " ; @ i m p o r t " g l o b a l / h e a d e r " ; @ i m p o r t " g l o b a l / f o o t e r " ; @ i m p o r t " g l o b a l / s i d e - n a v " ;

Slide 16

Slide 16 text

Variables (SASS/Scss) $ f o n t - s i z e : 1 6 p x ; $ t e x t - c o l o r : b l u e ; a { c o l o r : $ t e x t - c o l o r ; / / b l u e } p { $ t e x t - c o l o r : g r e e n ; $ b a c k g r o u n d - c o l o r : b l a c k ; a { b a c k g r o u n d - c o l o r : $ b a c k g r o u n d - c o l o r ; c o l o r : $ t e x t - c o l o r ; / / g r e e n } } h 1 { f o n t - s i z e : $ f o n t - s i z e * 4 ; / / 6 4 p x c o l o r : $ t e x t - c o l o r ; / / g r e e n ! }

Slide 17

Slide 17 text

Variables (SASS/Scss compiled) a { c o l o r : b l u e ; } p a { b a c k g r o u n d - c o l o r : b l a c k ; c o l o r : g r e e n ; } h 1 { f o n t - s i z e : 6 4 p x ; c o l o r : g r e e n ; }

Slide 18

Slide 18 text

Variables (LESS) @ f o n t - s i z e : 1 6 p x ; @ t e x t - c o l o r : b l u e ; a { c o l o r : @ t e x t - c o l o r ; / / b l u e } p { @ t e x t - c o l o r : g r e e n ; @ b a c k g r o u n d - c o l o r : b l a c k ; a { b a c k g r o u n d - c o l o r : @ b a c k g r o u n d - c o l o r ; c o l o r : @ t e x t - c o l o r ; / / g r e e n } } h 1 { f o n t - s i z e : @ f o n t - s i z e * 4 ; / / 6 4 p x c o l o r : @ t e x t - c o l o r ; / / b l u e ! }

Slide 19

Slide 19 text

Variables (LESS, compiled) a { c o l o r : # 0 0 0 0 f f ; } p a { b a c k g r o u n d - c o l o r : # 0 0 0 0 0 0 ; c o l o r : # 0 0 8 0 0 0 ; } h 1 { f o n t - s i z e : 6 4 p x ; c o l o r : # 0 0 0 0 f f ; }

Slide 20

Slide 20 text

Math! p { $ w i d t h : 3 0 e m ; f o n t : 3 0 p x / 2 p x ; / / N o r m a l C S S , n o d i v i s i o n w i d t h : $ w i d t h / 2 ; / / U s i n g a v a r i a b l e c a u s e s d i v i s i o n h e i g h t : ( 5 0 0 p x / 2 ) ; / / U s e s p a r e n t h e s e s , d o e s d i v i s i o n m a r g i n - l e f t : 1 0 p x + 1 0 p x / 5 p x ; / / U s e s + , d o e s d i v i s i o n } p { f o n t : 3 0 p x / 2 p x ; w i d t h : 1 5 e m ; h e i g h t : 2 5 0 p x ; m a r g i n - l e f t : 1 2 p x ; }

Slide 21

Slide 21 text

Built-ins p { c o l o r : l i g h t e n ( g r e e n , 5 % ) ; b a c k g r o u n d - c o l o r : d a r k e n ( y e l l o w , 1 0 % ) ; f o n t - s i z e : c e i l ( 1 2 . 7 8 ) ; l i n e - h e i g h t : f l o o r ( 1 2 . 7 8 ) ; } p { c o l o r : # 0 0 9 a 0 0 ; b a c k g r o u n d - c o l o r : # c c c c 0 0 ; f o n t - s i z e : 1 3 ; l i n e - h e i g h t : 1 2 ; } Plus dozens more

Slide 22

Slide 22 text

Mixins @ m i x i n p a d d i n g ( $ p a r a m : 1 e m ) { / / $ p a r a m h a s a d e f a u l t v a l u e o f 1 e m p a d d i n g : $ p a r a m ; } @ m i x i n b o r d e r ( $ d i r e c t i o n : b o t t o m , $ w e i g h t : 1 p x , $ s t y l e : s o l i d , $ c o l o r : b l a c k ) { b o r d e r - # { $ d i r e c t i o n } : $ w e i g h t $ s t y l e $ c o l o r ; / / S t r i n g i n t e r p o l a t i o n } . b o x 1 { @ i n c l u d e p a d d i n g ; / / p a d d i n g : 1 e m ; b a c k g r o u n d : b l u e ; } . b o x 2 { @ i n c l u d e p a d d i n g ( 5 e m ) ; / / p a d d i n g : 5 e m ; @ i n c l u d e b o r d e r ( l e f t , 1 0 p x , d o t t e d , r e d ) ; / / b o r d e r - l e f t : 1 0 p x d o t t e d r e d ; b a c k g r o u n d : g r e e n ; }

Slide 23

Slide 23 text

Mixin (compiled) . b o x 2 { p a d d i n g : 1 e m ; b a c k g r o u n d : b l u e ; } . b o x 1 { p a d d i n g : 5 e m ; b o r d e r - l e f t : 1 0 p x d o t t e d r e d ; b a c k g r o u n d : g r e e n ; }

Slide 24

Slide 24 text

Functions Not in LESS @ f u n c t i o n a d d - s i z e s ( $ s i z e 1 , $ s i z e 2 ) { @ r e t u r n $ s i z e 1 + $ s i z e 2 } p { f o n t - s i z e : a d d - s i z e s ( 3 e m , 1 0 e m ) ; } p { f o n t - s i z e : 1 3 e m ; }

Slide 25

Slide 25 text

Extends % b i g - t e x t { / / S i l e n t / P l a c e h o l d e r s e l e c t o r ! S A S S / S c s s o n l y f o n t - s i z e : 2 0 e m ; f o n t - w e i g h t : b o l d ; } % d a s h e d - u n d e r l i n e { b o r d e r - b o t t o m : 3 p x d a s h e d ; } . e r r o r { @ e x t e n d % d a s h e d - u n d e r l i n e ; c o l o r : r e d ; } . s e r v e r - e r r o r { @ e x t e n d % b i g - t e x t ; @ e x t e n d . e r r o r ; f o n t - s i z e : 3 0 e m ; }

Slide 26

Slide 26 text

Extends (compiled) . s e r v e r - e r r o r { f o n t - s i z e : 2 0 e m ; f o n t - w e i g h t : b o l d ; } . e r r o r , . s e r v e r - e r r o r { b o r d e r - b o t t o m : 3 p x d a s h e d ; } . e r r o r , . s e r v e r - e r r o r { c o l o r : r e d ; } . s e r v e r - e r r o r { f o n t - s i z e : 3 0 e m ; }

Slide 27

Slide 27 text

Conditions $ s i z e : m e d i u m ; p { @ i f $ s i z e = = x s m a l l { f o n t - s i z e : 8 p x ; } @ e l s e i f $ s i z e = = s m a l l { f o n t - s i z e : 1 0 p x ; } @ e l s e i f $ s i z e = = l a r g e { f o n t - s i z e : 2 4 p x ; } @ e l s e i f $ s i z e = = x l a r g e { f o n t - s i z e : 3 2 p x ; } @ e l s e { f o n t - s i z e : 1 6 p x ; } } p { f o n t - s i z e : 1 6 p x ; }

Slide 28

Slide 28 text

For Loops @ f o r $ i f r o m 1 t h r o u g h 5 { l i . i t e m - # { $ i } { w i d t h : 1 . 5 e m * $ i ; } } l i . i t e m - 1 { w i d t h : 1 . 5 e m ; } l i . i t e m - 2 { w i d t h : 3 e m ; } l i . i t e m - 3 { w i d t h : 4 . 5 e m ; } l i . i t e m - 4 { w i d t h : 6 e m ; } l i . i t e m - 5 { w i d t h : 7 . 5 e m ; }

Slide 29

Slide 29 text

Each Loops @ e a c h $ e m p l o y e e i n P e t e , M i k e , M a r t i n , Y a n n { l i . e m p l o y e e - # { $ e m p l o y e e } { b a c k g r o u n d - i m a g e : u r l ( ' / i m a g e s / p h o t o s / # { $ e m p l o y e e } . j p g ' ) ; } } l i . e m p l o y e e - P e t e { b a c k g r o u n d - i m a g e : u r l ( " / i m a g e s / p h o t o s / P e t e . j p g " ) ; } l i . e m p l o y e e - M i k e { b a c k g r o u n d - i m a g e : u r l ( " / i m a g e s / p h o t o s / M i k e . j p g " ) ; } l i . e m p l o y e e - M a r t i n { b a c k g r o u n d - i m a g e : u r l ( " / i m a g e s / p h o t o s / M a r t i n . j p g " ) ; } l i . e m p l o y e e - Y a n n { b a c k g r o u n d - i m a g e : u r l ( " / i m a g e s / p h o t o s / Y a n n . j p g " ) ; }

Slide 30

Slide 30 text

While Loops $ i : 6 ; @ w h i l e $ i > 0 { . i t e m - # { $ i } { w i d t h : 2 e m * $ i ; } $ i : $ i - 2 ; } . i t e m - 6 { w i d t h : 1 2 e m ; } . i t e m - 4 { w i d t h : 8 e m ; } . i t e m - 2 { w i d t h : 4 e m ; } Shamefully copied from sass-lang.com because I can't think of a realistic use case

Slide 31

Slide 31 text

What about using this stuff in the real world?

Slide 32

Slide 32 text

Best Practices & Pitfalls

Slide 33

Slide 33 text

Killer App of CSS Preprocessors: Configuration Color palette, typography, etc should be configurable.

Slide 34

Slide 34 text

Config Example: Typography $ s a n s - s e r i f : ' O p e n S a n s ' , s a n s - s e r i f ; $ s a n s - s e r i f - c o n d : ' O p e n S a n s C o n d e n s e d ' , s a n s - s e r i f ; $ s e r i f : ' L o r a ' , s e r i f ; $ h e a d e r - f o n t : ' R o b o t o C o n d e n s e d ' , s a n s - s e r i f ; $ b a s e - f o n t - f a m i l y : $ s a n s - s e r i f ; $ b a s e - f o n t - s i z e : 1 6 p x ; $ b a s e - l i n e - h e i g h t : 2 4 p x ; / / T h e f o n t s i z e s f o r h 1 - h 6 . $ h 1 - f o n t - s i z e : 2 . 5 * $ b a s e - f o n t - s i z e ; $ h 2 - f o n t - s i z e : 1 . 5 * $ b a s e - f o n t - s i z e ; $ h 3 - f o n t - s i z e : 1 . 1 7 * $ b a s e - f o n t - s i z e ; $ h 4 - f o n t - s i z e : 1 * $ b a s e - f o n t - s i z e ; $ h 5 - f o n t - s i z e : 0 . 8 3 * $ b a s e - f o n t - s i z e ; $ h 6 - f o n t - s i z e : 0 . 6 7 * $ b a s e - f o n t - s i z e ;

Slide 35

Slide 35 text

Config Example: Color Palette $ w h i t e : # f f f ; $ d a r k e s t - g r a y : # 3 3 3 ; $ d a r k - g r a y : # 4 4 4 ; $ l i g h t - g r a y : # F 2 F 2 F 2 ; $ g r a y : # 6 6 6 ; $ b l a c k : # 1 D 1 D 1 D ; $ b l u e : # 0 0 A E F F ; / / U s e t h a t p a l e t t e ! $ b a c k g r o u n d : $ w h i t e ; $ t e x t - c o l o r : $ b l a c k ; $ h e a d e r - c o l o r : $ d a r k - g r a y ; $ l i n k - c o l o r : $ b l u e ; $ l i n k - c o l o r - h o v e r : d a r k e n ( $ b l u e , 3 % ) ; / / e t c , e t c

Slide 36

Slide 36 text

Use Imports Should look like a table of contents for your styles @ i m p o r t " b a s e " ; / / W h e r e c o n f i g u r a t i o n l i v e s @ i m p o r t " m i x i n s " ; / / G l o b a l m i x i n s @ i m p o r t " p a r t i a l s " ; / / D o e s n ' t g e t c o m p i l e d t o C S S @ i m p o r t " g l o b a l / l a y o u t " ; @ i m p o r t " g l o b a l / h e a d e r / s e a r c h " ; @ i m p o r t " g l o b a l / h e a d e r / n a v i g a t i o n " ; @ i m p o r t " g l o b a l / f o o t e r " ; @ i m p o r t " g l o b a l / s i d e - n a v " ; @ i m p o r t " v i e w s / a r t i c l e s / i n t e r a c t i v e " ; @ i m p o r t " v i e w s / a r t i c l e s / f e a t u r e s " ; @ i m p o r t " v i e w s / a r t i c l e s / p h o t o s " ;

Slide 37

Slide 37 text

Smart Folder Structure

Slide 38

Slide 38 text

Careful with variable flipping Careful with em based layouts and derivative color palettes $ b a s e - c o l o r : b l u e ; / / I f $ b a s e - c o l o r c h a n g e s , t h i s c o u l d b e v e r y a l a r m i n g $ l i n k - c o l o r : d a r k e n ( $ b a s e - c o l o r , 5 % ) ; $ b a s e - f o n t - s i z e : 1 6 p x ; / / I f $ b a s e - f o n t - s i z e c h a n g e s , c o u l d b e * h u g e * , o r t i n y ! $ h 1 - f o n t - s i z e : $ b a s e - f o n t - s i z e * 2 . 5 ;

Slide 39

Slide 39 text

Avoid Deep Nests Don't mimic HTML structure, use minimal selectors . s l i d e s h o w { d i v { h e a d e r { h 3 . t i t l e { a { c o l o r : b l u e ; } } } } }

Slide 40

Slide 40 text

Avoid Deep Nests (compiled) Looks benign, creates specificity nightmares . s l i d e s h o w d i v h e a d e r h 3 . t i t l e a { c o l o r : b l u e ; }

Slide 41

Slide 41 text

Limit and Flatten Classes Use extends and mixins to keep things DRY . a r t i c l e { f o n t - s i z e : 2 0 p x ; c o l o r : b l a c k ; } . f e a t u r e d { f o n t - s i z e : 3 0 p x ; } . f e a t u r e d - s p o n s o r e d { @ e x t e n d . f e a t u r e d ; c o l o r : y e l l o w ; } < s e c t i o n c l a s s = " a r t i c l e f e a t u r e d " > < h 3 > A r t i c l e T i t l e < / h 3 > < / s e c t i o n > < s e c t i o n c l a s s = " a r t i c l e d f e a t u r e d - s p o n s o r e d " > < h 2 > T h i s a r t i c l e i s a * f e a t u r e d * s p o n s o r e d a r t i c l e < / h 2 > < / s e c t i o n >

Slide 42

Slide 42 text

Watch for Bloat % c l e a r f i x { & : b e f o r e , & : a f t e r { c o n t e n t : " " ; d i s p l a y : t a b l e ; } & : a f t e r { c l e a r : b o t h ; } } . a r t i c l e { @ e x t e n d % c l e a r f i x ; p a d d i n g : 1 0 p x ; h 3 { @ e x t e n d % c l e a r f i x ; c o l o r : g r e e n ; . t i t l e { f l o a t : l e f t ; } } } . f e a t u r e d - a r t i c l e { @ e x t e n d . a r t i c l e ; }

Slide 43

Slide 43 text

Watch for Bloat (compiled) Consider nesting strategy, extends, and mixins as you go . a r t i c l e : b e f o r e , . f e a t u r e d - a r t i c l e : b e f o r e , . a r t i c l e h 3 : b e f o r e , . f e a t u r e d - a r t i c l e h 3 : b e f o r e , . a r t i c l e : a f t e r c o n t e n t : " " ; d i s p l a y : t a b l e ; } . a r t i c l e : a f t e r , . f e a t u r e d - a r t i c l e : a f t e r , . a r t i c l e h 3 : a f t e r , . f e a t u r e d - a r t i c l e h 3 : a f t e r { c l e a r : b o t h ; } . a r t i c l e , . f e a t u r e d - a r t i c l e { p a d d i n g : 1 0 p x ; } . a r t i c l e h 3 , . f e a t u r e d - a r t i c l e h 3 { c o l o r : g r e e n ; } . a r t i c l e h 3 . t i t l e , . f e a t u r e d - a r t i c l e h 3 . t i t l e { f l o a t : l e f t ; }

Slide 44

Slide 44 text

On Deployment & Workflow

Slide 45

Slide 45 text

Wrap Up!

Slide 46

Slide 46 text

Questions? Thank you! / Michael Trythall @mtrythall Watch for more examples http://git.io/729TEQ