Slide 1

Slide 1 text

Compatibility via Modernizr Making web things fit their medium by / #McrFRED | 27th June 2013 | Manchester, UK Stu Cox @stucoxmedia

Slide 2

Slide 2 text

In this case: Your web thing ←→ Your user's browser/device com•pat•i•bil•i•ty |kәmˌpatɪˈbɪlɪti| (abbr.: compat.) noun (pl. -i•ties) a state in which two things are able to exist or occur together without problems or conflict.

Slide 3

Slide 3 text

How we did it back in the day

Slide 4

Slide 4 text

1. Make a 2. Test it in Browser A 3. It works! Hurray! web thing

Slide 5

Slide 5 text

4. Test it in Browser B 5. Doesn't work :-(

Slide 6

Slide 6 text

So we hack it. CSS hacks: User-Agent sniffs: These are essentially heuristics. . b t n { * m a r g i n - l e f t : - 1 3 p x ; } i f ( n a v i g a t o r . u s e r A g e n t . m a t c h ( / M S I E [ 6 7 ] \ . / ) ) { / / F i x f o r o l d I E }

Slide 7

Slide 7 text

Heuristics imply assumptions. "All browsers which parse CSS hack A also have layout bug B" "All browsers which match user-agent C support feature D" "I know about every browser my users might use" "If my assumptions are true now, they'll also be true in the future"

Slide 8

Slide 8 text

"I know about every browser my users might use" 85 browser versions with > 0.1% market share 7,000 different devices login to Facebook every day [1] Users have different needs (think accessibility) [1] techcrunch.com/2012/08/03/vp-mike-schroepfer-7000-different-mobile-devices-access-facebook-every-day/

Slide 9

Slide 9 text

Browser A Browser B Three sources of compatibility problems: Features Plugins Bugs

Slide 10

Slide 10 text

Features CSS: @ f o n t - f a c e , transitions, animations, flexbox, ... HTML: < a u d i o > , < v i d e o > , input types, drag & drop, ... JavaScript: History API, IndexedDB, WebSockets, ... ...

Slide 11

Slide 11 text

Plugins Platforms/Runtimes: Flash, Silverlight, Java, ... Viewers: PDF, Office documents, ... ...

Slide 12

Slide 12 text

Bugs Rendering: Box model, double margin, ... Other broken things: History API in Android 2.x, ... ...

Slide 13

Slide 13 text

These can all be described under one term: CAPABILITIES

Slide 14

Slide 14 text

Features are capabilities "Browser X has the ability to render SVG" Plugins add capabilities "A browser with the Flash plugin has the ability to render Flash media" Bugs are incapabilities "Browser Y has the ability NOT to fuck up the box model" “The differences between 2 users' browsers can be described (entirely) by the differences between their capability sets.”

Slide 15

Slide 15 text

Progressive Enhancement It was going to get mentioned sooner or later. Providing different experiences for different users, depending on their capabilities.

Slide 16

Slide 16 text

Think of your web thing as a collection of features. Core: the essential bits every user needs Enhancements: non-essential additions The core is smaller than you think.

Slide 17

Slide 17 text

Each feature depends on capabilities of the browser. Core capabilities → "system requirements" for your web thing Fewer core capabilities = accessible to more users. Enhancement capabilities → tiers of experience If a user has the required capabilities, they get the enhancement; otherwise they don't.

Slide 18

Slide 18 text

What's an enhancement? Examples: Some styling Fonts Animations Audio / video content A background image A whole functional part – e.g. a chat feature

Slide 19

Slide 19 text

Atomic Enhancements Either applied fully, or not at all No side effects when required capabilities aren't present Degrades gracefully If enhancements aren't atomic, bad things happen. Broken layouts Javascript errors Unusable interfaces

Slide 20

Slide 20 text

Examples: If b o x - s i z i n g not supported, layout won't be as expected. TypeError: Object # has no method 'querySelectorAll' . m o d u l e { b o x - s i z i n g : b o r d e r - b o x ; p a d d i n g : 1 e m ; w i d t h : 2 0 e m ; } / / M y m o d u l e v a r m o d u l e s = d o c u m e n t . q u e r y S e l e c t o r A l l ( ' . m o d u l e ' ) ; . . .

Slide 21

Slide 21 text

How can we ensure enhancements are atomic? 1. Avoid certain dependencies 2. Safety net 3. Feature detect

Slide 22

Slide 22 text

Feature detection Testing if the browser offers certain capabilities

Slide 23

Slide 23 text

Basic pattern i f ( s u p p o r t s F e a t u r e ) { / / U s e f e a t u r e ! / / E n s u r e a l l c o d e d e p e n d i n g o n t h i s f e a t u r e i s / / c o n t a i n e d h e r e . . . n o s i d e e f f e c t s ! } e l s e { / / S o m e f a l l b a c k ( o p t i o n a l ) }

Slide 24

Slide 24 text

Techniques 1. Does it exist? 2. Does it stick? 3. Does it work? ' g e o l o c a t i o n ' i n n a v i g a t o r v a r e l = c r e a t e E l e m e n t ( ' d i v ' ) ; e l . s t y l e . c s s T e x t = ' f i l t e r : b l u r ( 2 p x ) ' ; ! ! e l . s t y l e . l e n g t h / / t r u e i f C S S f i l t e r s s u p p o r t e d v a r i m a g e = n e w I m a g e ( ) ; i m a g e . o n l o a d = f u n c t i o n ( ) { i m a g e . w i d t h = = 1 / / t r u e i f W e b P s u p p o r t e d } i m a g e . s r c = ' d a t a : i m a g e / w e b p ; b a s e 6 4 , U k l G R i w A A A B X R U J Q V l A 4 I . . . '

Slide 25

Slide 25 text

Media Queries Yep, they're a kind of feature detection too. In CSS: In JS: @ m e d i a ( m i n - w i d t h : 8 0 0 p x ) { / / H a s a l a r g e v i e w p o r t } @ m e d i a n o t ( m i n - w i d t h : 8 0 0 p x ) { / / D o e s n ' t h a v e a l a r g e v i e w p o r t } i f ( w i n d o w . m a t c h M e d i a ( ' ( m i n - w i d t h : 8 0 0 p x ) ' ) . m a t c h e s ) { / / H a s a l a r g e v i e w p o r t } e l s e { / / D o e s n ' t h a v e a l a r g e v i e w p o r t }

Slide 26

Slide 26 text

Native Detection Via @ s u p p o r t s In CSS: In JS: @ s u p p o r t s ( d i s p l a y : f l e x ) { / / S u p p o r t s f l e x b o x } @ s u p p o r t s n o t ( d i s p l a y : f l e x ) { / / D o e s n ' t s u p p o r t f l e x b o x } i f ( w i n d o w . C S S . s u p p o r t s ( ' d i s p l a y ' , ' f l e x ' ) { / / S u p p o r t s f l e x b o x } e l s e { / / D o e s n ' t s u p p o r t f l e x b o x }

Slide 27

Slide 27 text

Fallbacks No fallback: "feature gating" Efficient, easy to maintain. Replace functionality: "polyfilling" Can be network and processor intensive, rarely an exact match Alternative functionality: "sandwich filling" Usually unnecessary…

Slide 28

Slide 28 text

It's a feature detection library. Detects for 174+ modern browser capabilities. http://modernizr.com

Slide 29

Slide 29 text

Basic patterns It makes feature detection a breeze i f ( M o d e r n i z r . g e o l o c a t i o n ) { / / U s e f e a t u r e ! / / E n s u r e a l l c o d e d e p e n d i n g o n t h i s f e a t u r e i s / / c o n t a i n e d h e r e . . . n o s i d e e f f e c t s ! } e l s e { / / S o m e f a l l b a c k ( o p t i o n a l ) } . g e o l o c a t i o n . m o d u l e { / * S t y l e s i f g e o l o c a t i o n s u p p o r t e d * / } . n o - g e o l o c a t i o n . m o d u l e { / * S t y l e s i f g e o l o c a t i o n n o t s u p p o r t e d * / }

Slide 30

Slide 30 text

Custom builds All killer, no filler

Slide 31

Slide 31 text

Roll your own Via M o d e r n i z r . a d d T e s t ( ) M o d e r n i z r . a d d T e s t ( ' y o d a ' , f u n c t i o n ( ) { v a r y o d a = d o c u m e n t . c r e a t e E l e m e n t ( ' y o d a ' ) ; r e t u r n ' t h e f o r c e ' i n y o d a ; } ) ;

Slide 32

Slide 32 text

Conditional Loading Via M o d e r n i z r . l o a d ( ) Avoid heavy loading for browsers which can't use it Rarely need n o p e – big polyfills are a bad idea! M o d e r n i z r . l o a d ( { t e s t : M o d e r n i z r . g e o l o c a t i o n , y e p : ' g e o . j s ' , n o p e : ' g e o - p o l y f i l l . j s ' } ) ;

Slide 33

Slide 33 text

Modernizr v3.0 New AMD-based internal architecture Builds are waaaaay smaller 20+ more detects since 2.6.2 Better handling of async tests Uses @ s u p p o r t s under the hood Faster release cycle Better documentation Easier integration with Coming soon, we promise! See: grunt-modernizr Alex Sexton's Modernizr 3 Workflow

Slide 34

Slide 34 text

Now I'm going to talk a bit about my involvement in Modernizr.

Slide 35

Slide 35 text

Undetectables Unfortunately some things fall under our radar

Slide 36

Slide 36 text

A good feature detect... Gives accurate positives Gives accurate negatives Is lightweight (fast & small) Doesn't make assumptions or use heuristics Realistically, most detects make some assumptions – we try to minimise these

Slide 37

Slide 37 text

Rule 1: It must interact with the document Because that's all we can access from JS. Styling Can't access the pixels on the screen Best-guess based on the (re)actions of the DOM Form UIs Appear on top of the document – invisible to us

Slide 38

Slide 38 text

Rule 2: It shouldn't take any user interaction Events Can't tell if events (e.g. D O M C o n t e n t L o a d e d ) will be fired at the correct time c o n t e n t e d i t a b l e We can often give accurate negatives, but not positives

Slide 39

Slide 39 text

Rule 3: Think about older browsers/devices Using new APIs e.g. w i n d o w . p e r f o r m a n c e – tells us nothing about older devices Touchscreens Don't get me started...

Slide 40

Slide 40 text

You can't detect a touchscreen Not reliably, anyway All techniques either use heuristics or rely on new APIs. http://stucox.com/blog/you-cant-detect-a-touchscreen/

Slide 41

Slide 41 text

In fact, you can't detect many device features Not reliably, anyway Think about the assumptions you're making

Slide 42

Slide 42 text

Now I'm going to talk a bit about some hand-wavey idealistic stuff.

Slide 43

Slide 43 text

Managing compatibility Variation between platforms is the web: embrace it. Consider it from the start of your project.

Slide 44

Slide 44 text

Idea: modular capability dependencies RequireJS-like syntax for defining browser dependencies b r o w s e r R e q u i r e ( [ ' s v g ' , ' c a n v a s ' ] , f u n c t i o n ( ) { / / O n l y r u n s i f c a p a b i l i t i e s a v a i l a b l e } ) ;

Slide 45

Slide 45 text

Even better: a RequireJS plugin r e q u i r e ( [ ' j q u e r y ' , ' M ! s v g ' , ' M ! c a n v a s ' ] , f u n c t i o n ( $ ) { / / O n l y r u n s i f s o f t w a r e A N D c a p a b i l i t y d e p e n d e n c i e s / / s a t i s f i e d } ) ;

Slide 46

Slide 46 text

That's all I've got. / www.stucox.com @stucoxmedia