All rules and guidelines in this document apply to HTML files.
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Icon Legend:
·
Space, ⇥
Tab, ↵
Enter/Return
- Files
- Document
- Doctype
- Language
- Character Encoding
- Viewport
- Head and Body
- Comments
- Formatting
- Elements and Attributes
- Best Practices
This section describes the format and naming convention of HTML files.
- Character encoding MUST be set to UTF-8 without BOM
- Sublime.app →
File
›Save with Encoding
›UTF-8
- Sublime.app →
- Line endings MUST be set to Unix (LF)
- Sublime.app →
View
›Line Endings
›Unix
- Sublime.app →
- Letters MUST be all lowercase
- e.g.
sidebar.html
,sidebar.php
- e.g.
- Words MUST be separated with a hyphen
- e.g.
social-media-widget.html
,social-media-widget.php
- e.g.
This section showcases the main elements required in a complete HTML file.
- Doctype MUST be specified and SHOULD be HTML5
- e.g.
<!DOCTYPE html>
- e.g.
- Language MUST be defined in the
html
element- e.g.
<html lang="en">
- e.g.
- Character encoding MUST be defined as early as possible
- e.g.
<meta charset="utf-8">
- e.g.
- Viewport MUST be included
- e.g.
<meta name="viewport" content="width=device-width, user-scalable=no">
- e.g.
- Head and body elements MUST be included
- e.g.
<head></head><body></body>
- e.g.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Welcome</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
</head>
<body>
<h1>Welcome</h1>
<p>This is a skeleton document.</p>
</body>
</html>
▲ Document
This section describes how comments should be formatted and used.
- Single-line comments MUST be on one line and text inside MUST be surrounded by spaces
- e.g.
<!-- This is a comment -->
- e.g.
- Multi-line comments MUST start and end on their own line and text MUST NOT be indented
- i.e.
<!--
↵
Line number one
↵
Line number two
↵
-->
- i.e.
- Closing tag comments SHOULD include the class or ID symbol and name
- e.g.
</div><!-- #main-wrapper -->
- e.g.
- Sensitive information MUST NOT be placed in a comment
- e.g.
<!-- Sends email to [email protected] -->
- e.g.
Single-line comments MUST be on one line and text inside MUST be surrounded by spaces.
<!--
This is a comment
-->
↳ Incorrect because <!--
, This is a comment
and -->
should be one line.
<!--This is a comment-->
↳ Incorrect because there is no space before or after This is a comment
.
<!-- This is a comment -->
▲ Comments
Multi-line comments MUST start and end on their own line and text MUST NOT be indented.
<!-- This is a comment
that spans multiple lines
-->
↳ Incorrect because <!--
and This is a comment
are on one line.
<!--
This is a comment
that spans multiple lines
-->
↳ Incorrect because This is a comment
and that spans multiple lines
are indented.
<!--
This is a comment
that spans multiple lines
-->
▲ Comments
Closing tag comments SHOULD include the class or ID symbol and name.
<div id="main-wrapper">
...
</div><!-- main-wrapper -->
↳ Incorrect because #
prefix is missing.
<div id="main-wrapper">
...
</div><!-- .main-wrapper -->
↳ Incorrect because main-wrapper
is prefixed with .
instead of #
.
<div id="main-wrapper">
...
</div><!-- #main-wrapper -->
▲ Comments
Sensitive information MUST NOT be placed in a comment.
<!-- Generated by some_php_function() -->
↳ Incorrect because comment reveals that markup comes from some_php_function()
.
▲ Comments
This section outline various, general formatting rules related to whitespace and text.
- Line indentation MUST be accomplished using tabs
- i.e.
<ul>
↵
⇥
<li>
- i.e.
- Direct child elements within
html
,body
,style
orscript
element MUST NOT be indented- i.e.
<body>
↵
<h1></h1>
↵
</body>
,<head>
↵
⇥
...
</head>
- i.e.
- Block, list and table elements MUST start on a new line and their children MUST be indented
- i.e.
<div>
↵
⇥
<h1>
,<table>
↵
⇥
<th>
- i.e.
- Trailing whitespace MUST NOT be present
- i.e. no
<p></p>
·
·
↵
- i.e. no
- Elements and attributes MUST be all lowercase
- e.g.
<a href="" title="">
,<link rel="stylesheet" href="">
- e.g.
Line indentation MUST be accomplished using tabs.
<ul>
<li>Item number one</li>
<li>Item number two</li>
</ul>
↳ Incorrect because <li>
is indented with spaces instead of tabs.
<ul>
<li>Item number one</li>
<li>Item number two</li>
</ul>
Direct child elements within html
, body
, style
or script
element MUST NOT be indented.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Welcome</title>
<meta charset="utf-8">
<style>
#main-wrapper {
width: 960px;
}
</style>
<script>
function show_alert() {
}
</script>
</head>
<body>
<div id="main-wrapper">
<h1>Welcome</h1>
<p>This is a skeleton document.</p>
</div>
</body>
</html>
↳ Incorrect because <head>
, <body>
and <div>
are indented.
↳ Incorrect because contents within <style>
and <script>
are indented.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Welcome</title>
<meta charset="utf-8">
<style>
#main-wrapper {
width: 960px;
}
</style>
<script>
function show_alert() {
}
</script>
</head>
<body>
<div id="main-wrapper">
<h1>Welcome</h1>
<p>This is a skeleton document.</p>
</div>
</body>
</html>
Block, list and table elements MUST start on a new line and their children MUST be indented.
<div><p>This is a paragraph.</p></div>
<ul><li>Item one</li><li>Item two</li></ul>
<table><tr><th>Header</th></tr><tr><td>Content</td></tr></table>
↳ Incorrect because <div>
, <ul>
, <table>
and<tr>
are not on their own line.
↳ Incorrect because <p>
, <li>
, <tr>
and <td>
are not indented.
<div>
<p>This is a paragraph.</p>
</div>
<ul>
<li>Item one</li>
<li>Item two</li>
</ul>
<table>
<tr>
<th>Header</th>
</tr>
<tr>
<td>Content</td>
</tr>
</table>
Trailing whitespace MUST NOT be present.
<p>This is a paragraph.</p>
↳ Incorrect because there are spaces after </p>
.
<p>This is a paragraph.</p>
Elements and attributes MUST be all lowercase.
<div ID="mainWrapper" class="DESKTOP">
<P>This is a paragraph</P>
</div>
↳ Incorrect because ID
, mainWrapper
, DESKTOP
and <P>
are not lowercase.
<div id="main-wrapper" class="desktop">
<p>This is a paragraph</p>
</div>
This section addresses how to utilize elements and attributes.
- Self-closing elements MUST NOT be closed
- e.g.
<br>
,<link rel="stylesheet" href="">
- e.g.
- Optional open/close tags MUST be included
- e.g.
<ul><li></li></ul>
- e.g.
- Attribute values MUST be wrapped in double quotation marks
- e.g.
<a href="" title="">Link</a>
- e.g.
- Attribute booleans SHOULD NOT include a value
- e.g.
<input type="text" name="" autofocus>
- e.g.
- Type and language attribute MUST be omitted on
script
tags- e.g.
<script src=""></script>
- e.g.
- Type attribute MUST be omitted on
link
andstyle
tags- e.g.
<style src=""></script>
- e.g.
- Protocol SHOULD be omitted
- e.g.
<link href="//style.css" rel="stylesheet">
- e.g.
Self-closing elements MUST NOT be closed.
<link href="theme.css" rel="stylesheet" />
<br />
↳ Incorrect because <link>
and <br>
have a /
at the end.
<link href="theme.css" rel="stylesheet">
<br>
Optional open/close tags MUST be included.
<!DOCTYPE html>
<html lang="en">
<div id="main-wrapper">
<h1>Welcome</h1>
<p>This is a skeleton document.
</div>
</html>
↳ Incorrect because <head></head>
, <body></body>
and </p>
are missing.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Welcome</title>
</head>
<body>
<div id="main-wrapper">
<h1>Welcome</h1>
<p>This is a skeleton document.</p>
</div>
</body>
</html>
Attribute values MUST be wrapped in double quotation marks.
<form action=processor.php class='application'>
...
</form>
↳ Incorrect because processor.php
and application
are not wrapped in double quotes.
<form action="processor.php" class="application">
...
</form>
Attribute booleans SHOULD NOT include a value.
<input type="text" name="first_name" autofocus="autofocus">
↳ Acceptable, but autofocus
value is not required for autofocus
attribute.
<input type="text" name="first_name" autofocus>
Type and language attribute MUST be omitted on script
tags.
<script src="//script.js" type="text/javascript"></script>
↳ Incorrect because type
attribute is included.
<script src="//script.js"></script>
Type attribute MUST be omitted on link
and style
tags.
<link rel="stylesheet" href="//style.css" type="text/css">
↳ Incorrect because type
attribute is included.
<link rel="stylesheet" href="//style.css">
Protocol SHOULD be omitted.
<link rel="stylesheet" href="http://domain.com/style.css">
↳ Acceptable, but http://domain.com
could be replaced with //
.
<link rel="stylesheet" href="//style.css">
- Structures, styles and scripts MUST be separated from each other
- e.g.
<a class="button" data-track="pageview">Read More</a>
- e.g.
- Valid HTML MUST be written
- i.e. yes
<ul><li></li></ul>
, no<ul><p></p></ul>
- i.e. yes
- Semantic HTML MUST be written
- i.e. yes
<a href="">View Options</a>
, no<div class="click">View Options</div>
- i.e. yes
- Form field labels MUST be used
- e.g.
<label for=""></label><input name="" type="text">
- e.g.
- Form field names MUST use underscores to separate words
- e.g.
<input type="text" name="first_name">
- e.g.
- Entity references MUST NOT be used
- e.g. yes
—
, no—
- e.g. yes
Structures, styles and scripts MUST be separated from each other.
<div class="internships-module">
...
</div>
↳ Incorrect because structure, style and functionality are not decoupled.
<div class="module internships" data-track="pageview event">
...
</div>
Valid HTML MUST be written.
<ul>
<li>Item one</li>
<li>Item two</li>
<ul>
<li>Sub-item one</li>
<li>Sub-item two</li>
</ul>
</ul>
↳ Incorrect because <ul>
cannot be a child of a <ul>
.
<ul>
<li>Item one</li>
<li>Item two</li>
<li>
<ul>
<li>Sub-item one</li>
<li>Sub-item two</li>
</ul>
</li>
</ul>
Semantic HTML MUST be written.
<div class="button">Click Here</div>
↳ Incorrect because <a>
is the elementing for clicking, not <div>
.
<p><strong>Lorem ipsum:</strong> Dolor sit amet, consectetur
adipiscing elit. Sed tincidunt urna id dui aliquet facilisis. Maecenas nulla diam,
scelerisque et nisl congue, ornare fermentum turpis. Pellentesque eu lorem nulla.
Sed interdum sagittis eros non vulputate. Donec sed interdum ante. Phasellus non
molestie nulla.</p>
↳ Incorrect because Lorem ipsum
is to be bold, not strongly spoken by a screen reader.
<div class="textarea">Write your text here.</div>
↳ Incorrect because <div>
is not a natural element for user input.
<a href="#" class="button">Click Here</a>
<p><b>Lorem ipsum:</b> Dolor sit amet, consectetur adipiscing
elit. Sed tincidunt urna id dui aliquet facilisis. Maecenas nulla diam, scelerisque
et nisl congue, ornare fermentum turpis. Pellentesque eu lorem nulla. Sed interdum
sagittis eros non vulputate. Donec sed interdum ante. Phasellus non molestie
nulla.</p>
<textarea name="comment">Write your text here.</textarea>
Form field labels MUST be used.
<input type="radio" name="gender" id="male" value="male">
<input type="radio" name="gender" id="female" value="female">
↳ Incorrect because <label>
is missing.
<input type="radio" name="gender" id="male" value="male"> <label for="male">Male</label>
<input type="radio" name="gender" id="female" value="female"> <label for="female">Female</label>
Form field names MUST use underscores to separate words.
<input type="text" name="emailaddress">
<input type="text" name="email-address">
↳ Incorrect because emailaddress
and email-address
are not using underscores between words.
<input type="text" name="email_address">
Entity references MUST NOT be used.
€
↳ Incorrect because €
entity reference is used.
€
Inspired in part by style guides from: CKAN, Google, jQuery, and WordPress.
Why should self-closing elements not include a
/
at the end?Edit Excluding the self closing slash contravenes the standard: https://www.w3.org/TR/xhtml1/#C_2