A presentation at CSS Day 2016 + HTML Special in in Amsterdam, Netherlands by Niels Leenheer
your name here:
the idea
HTML is special. Unlike many other languages the browser won’t show an error message when you make a mistake. Sure, that makes it easy to write bad code, but it also allows HTML to be both backwards and future compatible. It allowed the HTML5 specification to extend the existing form field types. It allowed the RICG to create the <picture> element. And it forms the basis of Web Components because it makes custom elements possible. And most importantly, it allows the <noscript> tag, which by definition does absolutely nothing. This talk will explain the concepts behind graceful degradation, progressive enhancement and feature detection, and focus on how to solve practical problems with these concepts.
resilience
HTML is both backwards and future compatible
<NEXTID
N= "55"
</HEADER> <BODY> <H1> World Wide Web </H1> The WorldWideWeb (W3) is a wide-area <A NAME= 0 HREF= "WhatIs.html" >hypermedia </A> information retrieval initiative aiming to give universal access to a large universe of documents.
<P>Everything there is online about W3 is linked directly or indirectly to this document, including an <A
create polyfills for our favourite tags
@keyframes
blink
{
0 %
{
visibility :
visible ;
}
50 %
{
visibility :
hidden ;
}
}
blink
{
animation
:
blink
1s steps( 1 ) infinite; }
supported by all browsers <marquee>
DOM HTML </>
DOM HTML </> tokenizer & tree builder
tokenizer
analyse html character by character
< a href="#"> tag open state
< a href="#"> tag name state
< a href="#"> before attribute name state
< a
h ref="#"> attribute name state
< a
hr ef="#"> attribute name state
< a
hre f="#"> attribute name state
< a
href ="#"> attribute name state
< a
"#"> before attribute value state
< a
href =" #"> attribute value (double-quoted) state
< a
href ="
"> attribute value (double-quoted) state
< a
href ="
"
after attribute value quoted state
< a
href ="
"> data state
< a
href ="
"> tag name attribute name attribute value
{ type: 'tag open'
name: ' a', attributes: [
{
name: 'href'
, value: '#'
} ] } <a href="#">
Data state –
Character reference in data state –
RCDATA state –
Character reference in RCDATA state
–
RAWTEXT state –
Script data state –
PLAINTEXT state –
Tag open state –
End tag open state –
Tag name state –
RCDATA less-than sign state –
RCDATA end tag open state –
RCDATA end tag name state –
RAWTEXT less-than sign state –
RAWTEXT end tag open state –
RAWTEXT end tag name state –
Script data less-than sign state –
Script data end tag open state –
Script data end tag name state –
Script data escape start state –
Script data escape start dash state –
Script data escaped state –
Script data escaped dash state –
Script data escaped dash dash state –
Script data escaped less-than sign state –
Script data escaped end tag open state –
Script data escaped end tag name state –
Script data double escape start state –
Script data double escaped state –
Script data double escaped dash state –
Script data double escaped dash dash state –
Script data double escaped less-than sign state –
Script data double escape end state –
Before attribute name state –
Attribute name state –
After attribute name state –
Before attribute value state –
Attribute value (double-quoted) state –
Attribute value (single-quoted) state –
Attribute value (unquoted) state –
Character reference in attribute value state –
After attribute value (quoted) state –
Self-closing start tag state –
Bogus comment state –
Markup declaration open state –
Comment start state –
Comment start dash state –
Comment state –
Comment end dash state –
Comment end state –
Comment end bang state –
DOCTYPE state –
Before DOCTYPE name state –
DOCTYPE name state –
After DOCTYPE name state –
After DOCTYPE public keyword state –
Before DOCTYPE public identifier state –
DOCTYPE public identifier (double-quoted) state –
DOCTYPE public identifier (single-quoted) state –
After DOCTYPE public identifier state –
Between DOCTYPE public and system identifiers state –
After DOCTYPE system keyword state –
Before DOCTYPE system identifier state –
DOCTYPE system identifier (double-quoted) state –
DOCTYPE system identifier (single- quoted) state –
After DOCTYPE system identifier state –
Bogus DOCTYPE state –
CDATA section state
<a<a<a<a<a> this is a tag! </a<a<a<a<a>
<u ʍ op- ǝ pısdn>
ƃɐʇ
ɐ sı sı ɥʇ </u ʍ op- ǝ pısdn>
<c( ╯ ° □ ° ‚ ╯ — ┻━┻
this really is a tag too! </c( ╯ ° □ ° ‚ ╯ — ┻━┻
<a href="#"> and this one too! </a>
<a href="#"> and this one too! </a>
<a href="#"> and this one too! </a>
<a href="#"> and this one too! </a>
<a href="#"> and this one too! </a>
<a href="#"> and this one too! </a href="#">
find ~ -type f -name '*.html' -print0 | xargs -0 -L1 perl -C -p -i -e 's/<a h/<a\x { 2007 } h /g'
find ~ -type f -name '*.html' -print0 |
xargs -0 -L1 perl -C -p -i -e 's/<a /<a\x { 2007 } /g'
<i-
unicode</i-
? ?
<i- ❤
unicode</ i- ❤
<i- ❤
HTML </i- ❤
i- ❤ :before
{
content :
'I ❤ ' ; } I
❤
HTML
<is- "
X HTML </is- "
is- " :after
{
content :
' = " ' ; }
XHTML =
"
custom elements custom dom interface for your own element receive events when an element is created, attached or detached, and when attributes are changed
<completely- safe>
<this-is-
A document.createElement('image ').tagName B IMAGE Something else
document.createElement('image ').tagName A B IMAGE Something else
d = document.createElement('div'); d.innerHTML = '<image>'; d.firstChild .tagName A B IMAGE Something else
d = document.createElement('div'); d.innerHTML = '<image>'; d.firstChild .tagName A B IMAGE Something else
tree builder
{ type: 'tag open'
name: ' a', attributes: [
{
name: 'href'
, value: '#'
} ] } { type: 'tag close'
name: ' a' } { type: 'character'
value: '
' }
HTMLAnchorElement Text :
HTMLHtmlElement
HTMLBodyElement
HTMLHeadElement
creating missing elements
initial insertion mode <a href="#">
</a>before html insertion mode <a href="#">
</a>HTMLHtmlElement before head insertion mode <a href="#">
</a>HTMLHtmlElement HTMLHeadElement in head insertion mode <a href="#">
</a>HTMLHtmlElement HTMLHeadElement after head insertion mode <a href="#">
</a>HTMLHtmlElement HTMLBodyElement HTMLHeadElement in body insertion mode <a href="#">
</a>HTMLAnchorElement HTMLHtmlElement HTMLBodyElement HTMLHeadElement in body insertion mode <a href="#">
</a>HTMLAnchorElement HTMLHtmlElement HTMLBodyElement HTMLHeadElement in body insertion mode Text :
<a href="#"> </a>HTMLAnchorElement HTMLHtmlElement HTMLBodyElement HTMLHeadElement in body insertion mode Text :
<a href="#"> </a>HTMLAnchorElement HTMLHtmlElement HTMLBodyElement HTMLHeadElement Text :
<a href="#"> </a>fixing mistakes
<b> 1 <i> 2 </b> 3 </i>
<b> 1 <i> 2 </b> 3 </i>
<b> 1 <i> 2 </b> 3 </i> A C B 3
Bold Italic 3
Italic 3
Regular
<b> 1 <i> 2 </b> 3 </i> HTMLBodyElement
b HTMLBodyElement
<b> 1 <i> 2 </b> 3 </i> Text : 1 HTMLElement :
b HTMLBodyElement
<b> 1 <i> 2 </b> 3 </i> HTMLElement :
i HTMLElement :
b HTMLBodyElement Text : 1
<b> 1 <i> 2 </b> 3 </i> HTMLElement :
i HTMLElement :
b HTMLBodyElement Text : 1 Text : 2
<b> 1 <i> 2
</b> 3 </i> HTMLElement :i HTMLElement :
b HTMLBodyElement Text : 1 Text : 2
<b> 1 <i> 2
</b> 3 </i> HTMLElement :i HTMLElement :
b HTMLBodyElement Text : 1 Text : 2
<b> 1 <i> 2 </b> 3 </i> HTMLElement :
i HTMLElement :
b HTMLBodyElement Text : 1 Text : 2
<b> 1 <i> 2 </b> 3
</i> HTMLElement :b HTMLElement :
i HTMLElement :
i HTMLBodyElement Text : 1 Text : 3 Text : 2
<b> 1 <i> 2 </b> 3 </i> HTMLElement :
b HTMLElement :
i HTMLElement :
i HTMLBodyElement Text : 1 Text : 3 Text : 2
HTMLElement :
b HTMLElement :
i HTMLElement :
i <b> 1 <i> 2 </b> 3 </i> HTMLBodyElement Text : 1 Text : 3 Text : 2
<b> 1 <i> 2 </b> 3 </i> A C B 3
Bold Italic 3
Italic 3
Regular
<b> 1 <i> 2 </b> 3 </i> A C 3
Bold Italic 3
Italic 3
Regular B
aside
HTMLElement
HTMLElement <b> <u> <code> <var> <kbd> <samp> <sub> <rtc> <i> <mark> <ruby> <rb> <rt> <rp> <bdi> <bdo> <wbr>
validation
NAME= 37
HREF= "Helping.html"
How can I help </A> ?
<DD> If you would like to support the web.. <DT><ANAME= 48
HREF= ". . / R E A D M E . h t m l "
Getting code </A>
<DD> Getting the code by <ANAME= 49
HREF= "LineMode/Defaults/Distribution.html"
anonymous FTP </A> , etc. </A>
</DL> </BODY>noscript
all browsers support javascript
nobody disables javascript anymore
and if you do, stuff will break
deal with it
<noscript> 1 <noscript> 2 </noscript> 3 </noscript> HTMLBodyElement
noscript HTMLBodyElement
<noscript> 1 <noscript> 2 </noscript> 3 </noscript> HTMLElement :
noscript Text : 1 HTMLBodyElement
<noscript> 1 <noscript> 2
</noscript>3 </noscript> HTMLElement :
noscript Text : 1 <noscript> HTMLBodyElement
<noscript> 1 <noscript> 2 </noscript>
3 </noscript> HTMLElement :
noscript Text : 1 <noscript> 2 HTMLBodyElement
<noscript> 1 <noscript> 2 </noscript> 3 </noscript> HTMLElement :
noscript Text : 1 <noscript> 2 HTMLBodyElement
<noscript> 1 <noscript> 2 </noscript> 3
</noscript> Text : 3 HTMLElement :noscript Text : 1 <noscript> 2 HTMLBodyElement
<noscript> 1 <noscript> 2 </noscript> 3 </noscript> Text : 3 HTMLElement :
noscript Text : 1 <noscript> 2 HTMLBodyElement
no
wtf?
@html5test
https://html5te.st/quiz #HTMLQuiz
HTML is special. Unlike many other languages the browser won’t show an error message when you make a mistake. Sure, that makes it easy to write bad code, but it also allows HTML to be both backwards and future compatible. It allowed the HTML5 specification to extend the existing form field types. It allowed the RICG to create the element. And it forms the basis of Web Components because it makes custom elements possible. And most importantly, it allows the tag, which by definition does absolutely nothing. This talk will explain the concepts behind graceful degradation, progressive enhancement and feature detection, and focus on how to solve practical problems with these concepts.
Here’s what was said about this presentation on social media.
<Blink> all the thingz #cssday pic.twitter.com/LeuQetcdcJ
— Stefanie Laharnar (@lhtdesignde) June 16, 2016
Valid HTML elements with @rakaz #cssday pic.twitter.com/JNnsryI46d
— 🇺|🇳|🇦 👩🏻💻 (@Una) June 16, 2016
Go on! Optimize your coworkers code with this snippet by @html5test #CSSday pic.twitter.com/YCl3xhGitI
— Dennis Frank (@freshmango) June 16, 2016
this-is-👍 #cssday pic.twitter.com/LyUBC1nNNG
— Victor Bastiaansen (@vicpuntnl) June 16, 2016
Very nice explaination on how html parsing works! #cssday pic.twitter.com/jwS4LvXEnl
— Chris Laarman (@chrislaarman) June 16, 2016
“You don’t need a computer science degree to make a website” – @rakaz at #cssday
— Paul Robert Lloyd (@paulrobertlloyd) June 16, 2016
And @html5test prepared a #cssday quiz for you. Try it out at https://t.co/NM7QjXlxOf
— CSS Day conference (@cssdayconf) June 16, 2016
BREAKING: @html5test brings back the <blink> tag! #cssday
— Hans Grimm (@grimmweb) June 16, 2016
Looking forward to adding <blink> to all my projects now, thanks @html5test! #cssday
— Stephen Hay (@stephenhay) June 16, 2016
Niels Leenheer on point with his talk about <noscript> talk! 💕 Nice @html5test #cssday
— Anneke Sinnema (@asinnema) June 16, 2016
Woo! NLHTML5 veteran @html5test is now on stage at #cssconf talking about <noscript> pic.twitter.com/zDvyE3kgZZ
— NLHTML5 (@nlhtml5) June 16, 2016
Really strong talk on resilience of #html. “< noscript >” by @html5test. #webdev https://t.co/6O55ME3kyv
— Stefan @ndcoslo 🇳🇴 (@stefanjudis) August 5, 2016
And you thought you know everything about the <noscript> tag? Think again: https://t.co/7XMd5RhMgo #fronteers via @rakaz
— Smashing Magazine (@smashingmag) July 28, 2016