惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Vercel News
Vercel News
O
OpenAI News
Engineering at Meta
Engineering at Meta
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
云风的 BLOG
云风的 BLOG
罗磊的独立博客
S
SegmentFault 最新的问题
The Register - Security
The Register - Security
Hugging Face - Blog
Hugging Face - Blog
D
DataBreaches.Net
U
Unit 42
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
B
Blog
阮一峰的网络日志
阮一峰的网络日志
P
Proofpoint News Feed
雷峰网
雷峰网
V
Visual Studio Blog
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
N
Netflix TechBlog - Medium
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Y
Y Combinator Blog
博客园 - 【当耐特】
G
Google Developers Blog
L
LangChain Blog
Stack Overflow Blog
Stack Overflow Blog
I
InfoQ
Martin Fowler
Martin Fowler
F
Fortinet All Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Cloudflare Blog
AI
AI
Google Online Security Blog
Google Online Security Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - Franky
Blog — PlanetScale
Blog — PlanetScale
Webroot Blog
Webroot Blog
PCI Perspectives
PCI Perspectives
爱范儿
爱范儿
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org

Mathias Bynens

A horrifying globalThis polyfill in universal JavaScript JavaScript engine fundamentals: optimizing prototypes JavaScript engine fundamentals: Shapes and Inline Caches Asynchronous stack traces: why await beats Promise#then() ECMAScript regular expressions are getting better! Unicode property escapes in JavaScript regular expressions ES2015 const is not about immutability Valid JavaScript variable names in ES2015 Unicode-aware regular expressions in ES2015 Dear Google, please fix plain text emails in Gmail PBKDF2+HMAC hash collisions explained JavaScript has a Unicode problem Processing Content Security Policy violation reports Hiding JSON-formatted data in the DOM with CSP enabled Loading JSON-formatted data with Ajax and xhr.responseType='json' Reserved keywords in JavaScript How to support full Unicode in MySQL databases How to speedrun Dropbox’s Dropquest 2012 Unquoted font family names in CSS Unquoted property names / object keys in JavaScript Valid JavaScript variable names in ES5 CSS character escape sequences JavaScript’s internal character encoding: UCS-2 or UTF-16? JavaScript character escape sequences JavaScript foo.prototype.bar notation Ambiguous ampersands HTML element + attribute notation How I detect and use localStorage: a simple JavaScript pattern Unquoted attribute values in HTML and CSS/JS selectors The end-tag open (ETAGO) delimiter Using the oninput event handler with onkeyup/onkeydown as its fallback Everything you always wanted to know about touch icons In defense of CSS hacks — introducing “safe CSS hacks” AirPlay video support in iOS Safari — a bookmarklet Completing Dropbox’s Dropquest 2011 in 60 seconds Using CSS without HTML How to create simple Mac apps from shell scripts Using setTimeout to speed up window.onload Bulletproof JavaScript benchmarks Thoughts on Safari Reader’s generated HTML How to enable Safari Reader on your site? The XML serialization of HTML5, aka ‘XHTML5’ The id attribute got more classy in HTML5 The three levels of HTML5 usage The HTML5 document.head DOM tree accessor Bulletproof HTML5 <details> fallback using jQuery Displaying hidden elements like <head> using CSS Inline <script> and <style> vs. external .js and .css — what’s the size threshold? Using Showdown/PageDown with and without jQuery
The smallest possible valid (X)HTML documents
Mathias · 2011-12-15 · via Mathias Bynens

I thought it would be fun to document the smallest possible valid HTML documents for each version, so here goes :)

ISO/IEC 15445:2000, also known as “ISO HTML”: 113 bytes

<!DOCTYPE html PUBLIC"ISO/IEC 15445:2000//DTD HTML//EN"><html><head><title></title></head><body><p></body></html>

The DOCTYPE can also be written as <!DOCTYPE html PUBLIC "ISO/IEC 15445:2000//DTD HyperText Markup Language//EN">, but that obviously requires more characters.

Although it tricks the W3C Validator, the space following PUBLIC can be omitted as long as no system identifier is used.

Start and end tags for <html>, <head>, <body> are required, as well as a block-level element as body content. The end tag for the <p> element can be omitted, though.

HTML 2.0: 58 bytes

<!DOCTYPE html PUBLIC"-//IETF//DTD HTML 2.0//EN"><title//x

Other than the DOCTYPE, only the <title> element is required, as well as some body content (in this case, the text “x”). The start and end tags for <html>, <head> and <body> may be omitted. (Browsers automatically create these elements.)

You may have noticed the use of <title// instead of <title></title> here. This is a markup minimization feature of SGML named “SHORTTAG NETENABL IMMEDNET”. NET stands for Null End Tag. Basically, this allows shortening tags surrounding a text value. The first slash (/) in <title// stands for the NET-enabling “start-tag close” (NESTC), and the second slash stands for the NET. If you wanted to add some content to the <title> element, you could theoretically use <title/Foo/ instead of (<title>Foo</title>).

Note that the following version (54 bytes) seems to have the same effect, according to the W3C Validator:

<!DOCTYPE html PUBLIC"-//IETF//DTD HTML//EN"><title//x

HTML 3.2: 63 bytes

<!DOCTYPE html PUBLIC"-//W3C//DTD HTML 3.2 Final//EN"><title//x

Note that the DOCTYPE for HTML 3.2 and older versions doesn’t really have an effect on your document; browsers still enter quirks mode.

HTML 4.0 Strict: 59 bytes

<!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.0//EN"><title//<p>

In HTML4, the body content must contain a block-level element — just text content won’t do. For that reason, an empty <p> element is used.

HTML 4.01 Transitional: 71 bytes

<!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN"><title//x

Note that we’re not using the full document type declaration; the system identifier (the URL part that theoretically allows user agents to download the document type definition and any needed entity sets) is optional, so it’s been omitted here.

HTML 4.01 Transitional requires body content, but accepts text content; a block-level element in the <body> isn’t needed.

HTML 4.01 Frameset: 84 bytes

<!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01 Frameset//EN"><title//<frameset/<frame>/

The full DOCTYPE is <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">, but the system identifier may be omitted.

As you can see, we’re using the same SGML trick as before (<frameset/<frame>/) — only this time we’re actually adding content to the wrapper element.

In HTML 4.01 Frameset, the <frameset> element must have a <frame> child element. XHTML 1.0 Frameset does not have this requirement.

HTML 4.01 Strict: 60 bytes

<!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01//EN"><title//<p>

HTML 4.01 + RDFa 1.0: 69 bytes

<!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01+RDFa 1.1//EN"><title//<p>

The full DOCTYPE is <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/html401-rdfa-1.dtd">, but the system identifier may be omitted.

HTML 4.01 + RDFa 1.1: 69 bytes

<!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01+RDFa 1.1//EN"><title//<p>

The full DOCTYPE is <!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/html401-rdfa11-1.dtd">, but the system identifier may be omitted.

XHTML Basic 1.0: 41 bytes

<html><head><title/></head><body/></html>

The DOCTYPE — in this case, <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd"> — is optional in all XHTML versions, assuming the document is served with the correct Content-Type: application/xhtml+xml header. (That’s a bold assumption.) Note that the xmlns attribute on the root <html> element isn’t required in this version of XHTML.

Body content is optional, too.

You may notice the use of <title/> here instead of <title></title>. This is the XHTML equivalent of <title// in HTML serializations. Remember when we talked about SGML, and how HTML defined both its NET and NETSC with a /? The only difference here is that XML defines NESTC with a /, and NET with an > (angled bracket).

XHTML Basic 1.1: 41 bytes

<html><head><title/></head><body/></html>

The DOCTYPE, <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"> is optional — again, assuming the file is served with the correct MIME type.

XHTML 1.0 Transitional: 78 bytes

<html xmlns="http://www.w3.org/1999/xhtml"><head><title/></head><body/></html>

The DOCTYPE, <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">, is optional.

XHTML 1.0 Frameset: 82 bytes

<html xmlns="http://www.w3.org/1999/xhtml"><head><title/></head><frameset/></html>

The DOCTYPE, <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">, is optional.

XHTML 1.0 Strict: 78 bytes

<html xmlns="http://www.w3.org/1999/xhtml"><head><title/></head><body/></html>

The DOCTYPE, <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">, is optional.

XHTML + RDFa 1.1: 78 bytes

<html xmlns="http://www.w3.org/1999/xhtml"><head><title/></head><body/></html>

The DOCTYPE, <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd">, is optional.

XHTML 1.1: 78 bytes

<html xmlns="http://www.w3.org/1999/xhtml"><head><title/></head><body/></html>

The DOCTYPE, <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">, is optional.

HTML5: 15 bytes

<!DOCTYPE html>

That’s right — there’s no <title> element! When a higher-level protocol provides title information, e.g. in the subject line of an email or when HTML is used as an email authoring format, the <title> element may be omitted.

In all other situations, this is the smallest possible HTML5 document (31 bytes):

<!DOCTYPE html><title>x</title>

Sadly, the SGML trick we used before (<title//) is not allowed in HTML5 anymore. Even if it was, we still couldn’t use it, because HTML5 requires a non-empty content value for the <title> element if it is used. The reasoning behind this is obvious: if you leave the <title> element empty, it means the document doesn’t need a title, in which case you should simply omit the <title> element entirely (as explained above).

Note that body content is not required.

XHTML5: 44 bytes

<html xmlns="http://www.w3.org/1999/xhtml"/>

XHTML5 doesn’t require a DOCTYPE. Just like in HTML5, there are cases where a <title> element is not needed. Body content is optional, too.

(Use validator.nu to confirm this; the W3C validator would fall back to XHTML 1.0 Transitional if you tried to validate this.)

Disclaimer

It’s very likely that I missed a possible “optimization”. Please leave a comment if you have any corrections or other feedback!

Update: I’ve set up a repository on GitHub to collect the smallest possible syntactically valid files. Pull requests welcome!