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
11
3.9k
∞ 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
Tweet
Share
More Decks by Mathias Bynens
See All by Mathias Bynens
V8 internals for JavaScript developers @ Fronteers 2018
mathiasbynens
3
480
V8 internals for JavaScript developers
mathiasbynens
2
780
What’s new in ES2018?
mathiasbynens
2
120
V8 internals for JavaScript developers
mathiasbynens
1
140
Preventing timing attacks on the web @ Fronteers Jam 2016
mathiasbynens
4
220
Front-End Performance: The Dark Side @ ColdFront Conference 2016
mathiasbynens
1
370
Hacking with Unicode in 2016
mathiasbynens
15
14k
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
970
Other Decks in Programming
See All in Programming
データの整合性を保つ非同期処理アーキテクチャパターン / Async Architecture Patterns
mokuo
47
17k
CDK開発におけるコーディング規約の運用
yamanashi_ren01
2
120
定理証明プラットフォーム lapisla.net
abap34
1
1.8k
お前もAI鬼にならないか?👹Bolt & Cursor & Supabase & Vercelで人間をやめるぞ、ジョジョー!👺
taishiyade
6
4k
苦しいTiDBへの移行を乗り越えて快適な運用を目指す
leveragestech
0
580
チームリードになって変わったこと
isaka1022
0
200
Rails アプリ地図考 Flush Cut
makicamel
1
120
CSS Linter による Baseline サポートの仕組み
ryo_manba
1
100
SwiftUIで単方向アーキテクチャを導入して得られた成果
takuyaosawa
0
270
SpringBoot3.4の構造化ログ #kanjava
irof
2
990
Kubernetes History Inspector(KHI)を触ってみた
bells17
0
230
2024年のkintone API振り返りと2025年 / kintone API look back in 2024
tasshi
0
220
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
55
9.2k
A better future with KSS
kneath
238
17k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2.1k
Designing for Performance
lara
604
68k
The Pragmatic Product Professional
lauravandoore
32
6.4k
Java REST API Framework Comparison - PWX 2021
mraible
28
8.4k
KATA
mclloyd
29
14k
How to Think Like a Performance Engineer
csswizardry
22
1.3k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Embracing the Ebb and Flow
colly
84
4.6k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
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