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, ...
...
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