Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Compatibility via Modernizr

Compatibility via Modernizr

My talk at McrFRED (http://fredup.github.io/manchester/), June 2013.

C993d5b186c4f8316b35eff301177874?s=128

Stu Cox

June 27, 2013
Tweet

Transcript

  1. Compatibility via Modernizr Making web things fit their medium by

    / #McrFRED | 27th June 2013 | Manchester, UK Stu Cox @stucoxmedia
  2. 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.
  3. How we did it back in the day

  4. 1. Make a 2. Test it in Browser A 3.

    It works! Hurray! web thing
  5. 4. Test it in Browser B 5. Doesn't work :-(

  6. 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 }
  7. 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"
  8. "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/
  9. Browser A Browser B Three sources of compatibility problems: Features

    Plugins Bugs
  10. 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, ... ...
  11. Plugins Platforms/Runtimes: Flash, Silverlight, Java, ... Viewers: PDF, Office documents,

    ... ...
  12. Bugs Rendering: Box model, double margin, ... Other broken things:

    History API in Android 2.x, ... ...
  13. These can all be described under one term: CAPABILITIES

  14. 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.”
  15. Progressive Enhancement It was going to get mentioned sooner or

    later. Providing different experiences for different users, depending on their capabilities.
  16. 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.
  17. 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.
  18. What's an enhancement? Examples: Some styling Fonts Animations Audio /

    video content A background image A whole functional part – e.g. a chat feature
  19. 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
  20. Examples: If b o x - s i z i

    n g not supported, layout won't be as expected. TypeError: Object #<HTMLDocument> 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 ' ) ; . . .
  21. How can we ensure enhancements are atomic? 1. Avoid certain

    dependencies 2. Safety net 3. Feature detect
  22. Feature detection Testing if the browser offers certain capabilities

  23. 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 ) }
  24. 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 . . . '
  25. 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 }
  26. 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 }
  27. 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…
  28. It's a feature detection library. Detects for 174+ modern browser

    capabilities. http://modernizr.com
  29. 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 * / }
  30. Custom builds All killer, no filler

  31. 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 ; } ) ;
  32. 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 ' } ) ;
  33. 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
  34. Now I'm going to talk a bit about my involvement

    in Modernizr.
  35. Undetectables Unfortunately some things fall under our radar

  36. 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
  37. 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
  38. 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
  39. 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...
  40. 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/
  41. In fact, you can't detect many device features Not reliably,

    anyway Think about the assumptions you're making
  42. Now I'm going to talk a bit about some hand-wavey

    idealistic stuff.
  43. Managing compatibility Variation between platforms is the web: embrace it.

    Consider it from the start of your project.
  44. 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 } ) ;
  45. 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 } ) ;
  46. That's all I've got. / www.stucox.com @stucoxmedia