Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
∞ things I didn’t know about HTML, CSS, and Jav...
Search
Mathias Bynens
March 01, 2014
Programming
3.9k
11
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
∞ things I didn’t know about HTML, CSS, and JavaScript @ Kod.io 2014
Slides for my talk on random web development fun facts at Kod.io 2014.
Mathias Bynens
March 01, 2014
More Decks by Mathias Bynens
See All by Mathias Bynens
V8 internals for JavaScript developers @ Fronteers 2018
mathiasbynens
3
540
V8 internals for JavaScript developers
mathiasbynens
2
1.1k
What’s new in ES2018?
mathiasbynens
2
170
V8 internals for JavaScript developers
mathiasbynens
1
210
Preventing timing attacks on the web @ Fronteers Jam 2016
mathiasbynens
4
290
Front-End Performance: The Dark Side @ ColdFront Conference 2016
mathiasbynens
1
540
Hacking with Unicode in 2016
mathiasbynens
15
15k
Front-End Performance: The Dark Side @ Fronteers Spring Conference 2016
mathiasbynens
16
57k
3.14 things I didn’t know about CSS @ CSSConf.asia 2015
mathiasbynens
4
1.2k
Other Decks in Programming
See All in Programming
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1.2k
AIエージェントで 変わるAndroid開発環境
takahirom
2
630
ランチタイムLT会3周年!ランチタイムLT会を3年間続けられたお話
y0hgi
1
140
1年で人数1.5倍、PR数5.5倍増。 品質とアウトカムはどうなったか、 何が効いたか
ike002jp
0
130
SLOをサービス品質の共通言語にするために 取り組んできたこと
wakana0222
0
500
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
520
フィードバックで育てるAI開発
kotaminato
1
110
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
3
850
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
150
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
1
180
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
190
act1-costs.pdf
sumedhbala
0
230
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Scaling GitHub
holman
464
140k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
Statistics for Hackers
jakevdp
799
230k
Tell your own story through comics
letsgokoyo
1
990
Java REST API Framework Comparison - PWX 2021
mraible
34
9.5k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
260
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
460
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.4k
WCS-LA-2024
lcolladotor
0
710
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
970
Transcript
@mathias · #kodio_2014 Ten things I didn’t know about HTML
@mathias
Ten things I didn’t know about HTML @mathias · #kodio_2014
∞ things I didn’t know about HTML, CSS & JavaScript
@mathias · #kodio_2014
Back to the ’90s kickin’ it old skool
None
Background colors <body bgcolor="pink"></body>
Background colors <body bgcolor="pink"></body>
Background colors <body bgcolor="#ffc0cb"></body>
Background colors <body bgcolor="ffc0cb"></body>
Background colors <body bgcolor="#f3f"></body> " #FF33FF
Background colors <body bgcolor="f3f"></body> " #0F030F
Background colors <body bgcolor="sick"></body> " #00C000
Background colors <body bgcolor="MrT"></body> " #000000
Background colors <body bgcolor="chucknorris"></body> " #C00000
Background colors <body bgcolor="crap"></body> " #C0A000
Background colors <body bgcolor="!"></body> " #000000
Background colors <body bgcolor="kodio"></body> " #00D000
Background colors http://mths.be/bgcolor
Background colors http://mths.be/bgcolor
“Valid HTML” conformance criteria
Document Type Definition
DTD <head> <p>Lorem ipsum.</p> </head>
DTD <kitchensink>
DTD fail <input type="date" placeholder="foo">
DTD fail <input type="date" placeholder="foo"> <table> <tr><td>foo</td></tr> <tr><td colspan="2">bar</td></tr> </table>
DTD fail <input type="date" placeholder="foo"> → can still be checked
by a computer <table> <tr><td>foo</td></tr> <tr><td colspan="2">bar</td></tr> </table>
Computer says no <img src="foo.png" alt=""> <time datetime="2013-10-03">LOL</time> <blockquote>not a
quote</blockquote>
Computer says no <img src="foo.png" alt=""> → can only be
checked by a human <time datetime="2013-10-03">LOL</time> <blockquote>not a quote</blockquote>
Take-away Don’t obsess about HTML validation. • not the whole
story • validators have bugs, too Functionality trumps validation anyway. <meta http-equiv="X-UA-Compatible" content="IE=edge">
Character references aka. “entities”
Character references <!-- valid and reliable: --> <p>foo & bar</p>
<!-- renders as “foo & bar” -->
;
github:twbs/bootstrap#3057
github:twbs/bootstrap#3057
;
; PRETENDS TO BE OPTIONAL BREAKS STUFF WHEN OMITTED
Character references <!-- valid and reliable: --> <p>foo & bar</p>
<!-- renders as “foo & bar” -->
Character references <!-- invalid, but reliable: --> <p>foo & bar</p>
<!-- renders as “foo & bar” -->
Character references <!-- invalid, and confusing: --> <p title="foo&bar"> foo&bar
</p> <!-- title renders as “foo&bar” --> <!-- text renders as “foo&bar” -->
Character references <!-- valid and reliable: --> <p>foo & bar</p>
<!-- renders as “foo & bar” --> http://mths.be/bdu
Character references <!-- valid and reliable: --> <p>foo > bar</p>
<!-- renders as “foo > bar” -->
Character references <!-- invalid, but reliable: --> <p>foo > bar</p>
<!-- renders as “foo > bar” -->
Character references <!-- invalid, and confusing: --> <p title="foo>bar"> foo>bar
</p> <!-- title renders as “foo>bar” --> <!-- text renders as “foo>bar” -->
Character references <!-- valid and reliable: --> <p>foo > bar</p>
<!-- renders as “foo > bar” -->
Character references <p>foo…bar</p> <!-- which symbol is this? --> <!--
how will it render? -->
Character references <p>foo…bar</p> <!-- which symbol is this? --> <!--
how will it render? -->
… is U+0085, right?
… is U+0085, right? ✘
Nope, not in HTML!
Nope, not in HTML!
…but it is in XHTML
Character references
Tags
Valid HTML <!DOCTYPE html> <html> <head> <title>Foo</title> </head> <body> …
</body> </html>
Valid HTML <!DOCTYPE html> <html> <head> <title>Foo</title> </head> <body> …
</body> </html>
Valid HTML <!DOCTYPE html> <html> <head> <title>Huh?</title> <body> …
Valid HTML <!DOCTYPE html> <html> <head> <title>Huh?</title> <body> …
Valid HTML <!DOCTYPE html> <title>lolwut</title> …
None
None
^ n FTFY
Using CSS without HTML
None
None
CSS without HTML $ curl -i http://mathiasbynens.be/demo/css-without-html HTTP/1.1 200 OK
Date: Wed, 03 Oct 2013 13:33:37 GMT Link: <css-without-html.css>;rel=stylesheet Content-Length: 0 Content-Type: text/html; charset=UTF-8 http://mths.be/bpe
CSS without HTML $ curl -i http://mathiasbynens.be/demo/css-without-html HTTP/1.1 200 OK
Date: Wed, 03 Oct 2013 13:33:37 GMT Link: <css-without-html.css>;rel=stylesheet Content-Length: 0 Content-Type: text/html; charset=UTF-8 http://mths.be/bpe
None
Font family names
CSS html { font-family: 'Comic Sans MS'; } “If there’s
whitespace in the font family name, it must be quoted.”
CSS html { font-family: Comic Sans MS; } “If there’s
whitespace in the font family name, it must be quoted.” http://mths.be/bft
CSS html { font-family: 456bereastreet; }
CSS html { font-family: 456bereastreet; }
CSS html { font-family: \34 56bereastreet; }
CSS html { font-family: \34 56bereastreet; }
CSS html { font-family: '456bereastreet'; }
CSS http://mths.be/bjm
Attribute values
Attribute values <a href="foo">…</a> <style> a[href="foo"] { background: hotpink; }
</style>
Attribute values <a href=foo>…</a> <style> a[href=foo] { background: hotpink; }
</style>
Attribute values <a href=foo|bar>…</a> <style> a[href=foo|bar] { background: hotpink; }
</style>
Attribute values <a href=foo|bar>…</a> <style> a[href=foo|bar] { background: hotpink; }
</style>
Attribute values <a href=foo|bar>…</a> <style> a[href="foo|bar"] { background: hotpink; }
</style> http://mths.be/bal
Attribute values http://mths.be/bjn
Handling user input
http://mths.be/bqv
http://mths.be/bqv
Characters in JS
JavaScript string length >> 'A'.length // U+0041 1 >> 'A'
== '\u0041' true >> 'B'.length // U+0042 1 >> 'B' == '\u0042' true
String length ≠ char count >> 'A'.length // U+1D400 2
>> 'A' == '\uD835\uDC00' true >> 'B'.length // U+1D401 2 >> 'B' == '\uD835\uDC01' true http://mths.be/bed
Surrogate pairs // for non-BMP code points (> 0xFFFF) function
getSurrogates(codePoint) { var high = Math.floor((codePoint - 0x10000) / 0x400) + 0xD800; var low = (codePoint - 0x10000) % 0x400 + 0xDC00; return [ high, low ]; } ! function getCodePoint(high, low) { var codePoint = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000; return codePoint; } ! >> getSurrogates('A'); // U+1D400 [ 0xD835, 0xDC00 ] >> getCodePoint(0xD835, 0xDC00); 0x1D400 http://mths.be/bed
JS string character count function countSymbols(string) { return punycode.ucs2.decode(string).length; }
! >> countSymbols('A') // U+0041 1 >> countSymbols('A') // U+1D400 1 http://mths.be/punycode
JS variable names
Which is invalid? var H ̹̙̦̮͉̩̗̗ ͧ̇̏̊̾ Eͨ͆͒̆ͮ̃ ͏̷̮̣̫̤̣Cͯ̂͐ ͏̨̛͔̦̟͈̻O
̜͎͍͙͚̬̝̣ ̽ͮ͐͗̀ͤ̍̀ ͢ M̴̡̲̭͍͇̼̟̯̦ ̉̒͠ Ḛ̛̙̞̪̗ ͥ ͤͩ̾͑̔͐ ͅ Ṯ̴̷̷̗̼͍ ̿̿̓̽͐ H ̙̙ ̔̄ ͜ ; var "_ಠಠ_"; var ϗ îਓƎ ℵೋീΔେ; var ʃː λ ˀπ ᐩᐨᐟᑉᐦᐸᐳ\u200C; var a; http://mths.be/ber
♥ JS var H ̹̙̦̮͉̩̗̗ ͧ̇̏̊̾ Eͨ͆͒̆ͮ̃ ͏̷̮̣̫̤̣Cͯ̂͐ ͏̨̛͔̦̟͈̻O ̜͎͍͙͚̬̝̣
̽ͮ͐͗̀ͤ̍̀ ͢ M̴̡̲̭͍͇̼̟̯̦ ̉̒͠ Ḛ̛̙̞̪̗ ͥ ͤͩ̾͑̔͐ ͅ Ṯ̴̷̷̗̼͍ ̿̿̓̽͐ H ̙̙ ̔̄ ͜ ; // valid var !_ಠಠ_!; // valid var ϗ îਓƎ ℵೋീΔେ; // valid var ʃː λ ˀπ ᐩᐨᐟᑉᐦᐸᐳ\u200C; // valid var a; // syntax error http://mths.be/ber
/^(?!(?:do|if|in|for|let|new|try|var|case|else| enum|eval|false|null|this|true|void|with|break| catch|class|const|super|throw|while|yield|delete| export|import|public|return|static|switch|typeof| default|extends|finally|package|private|continue| debugger|function|arguments|interface|protected| implements|instanceof)$)[$A-Z\_a-z\xaa\xb5\xba \xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0- \u02e4\u02ec\u02ee\u0370- \u0374\u0376\u0377\u037a-\u037d\u0386\u0388-
\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7- \u0481\u048a-\u0527\u0531-\u0556\u0559\u0561- \u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a
\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a- \u302f\u3099\u309a\ua620-\ua629\ua66f\ua674- \ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823- \ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0- \ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d \ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0- \ua9d9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50- \uaa59\uaa7b\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe \uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3- \uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-
\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f \uff10-\uff19\uff3f]*$/
JS variable names http://mths.be/bjo
Questions? @mathias