Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
HTML style guide with coding standards and best practices.

HTML Style Guide

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

Table of Contents

  1. Files
    1. File Format
    2. Filename
  2. Document
    1. Doctype
    2. Language
    3. Character Encoding
    4. Viewport
    5. Head and Body
  3. Comments
    1. Single-line Comments
    2. Multi-line Comments
    3. Closing Tag Comments
    4. Sensitive Information
  4. Formatting
    1. Line Indentation
    2. Direct Child Elements
    3. Block, List and Table Elements
    4. Trailing Whitespace
    5. Elements and Attributes
  5. Elements and Attributes
    1. Self-closing Elements
    2. Optional Open/Close Tags
    3. Attribute Values
    4. Attribute Booleans
    5. Type and Language Attribute
    6. Type Attribute
    7. Protocol
  6. Best Practices
    1. Structures, Styles and Scripts
    2. Valid HTML
    3. Semantic HTML
    4. Form Field Labels
    5. Form Field Names
    6. Entity References

1. Files

This section describes the format and naming convention of HTML files.

File Format

  1. Character encoding MUST be set to UTF-8 without BOM
    • Sublime.app → FileSave with EncodingUTF-8
  2. Line endings MUST be set to Unix (LF)
    • Sublime.app → ViewLine EndingsUnix

Filename

  1. Letters MUST be all lowercase
    • e.g. sidebar.html, sidebar.php
  2. Words MUST be separated with a hyphen
    • e.g. social-media-widget.html, social-media-widget.php

Table of Contents

2. Document

This section showcases the main elements required in a complete HTML file.

  1. Doctype MUST be specified and SHOULD be HTML5
    • e.g. <!DOCTYPE html>
  2. Language MUST be defined in the html element
    • e.g. <html lang="en">
  3. Character encoding MUST be defined as early as possible
    • e.g. <meta charset="utf-8">
  4. Viewport MUST be included
    • e.g. <meta name="viewport" content="width=device-width, user-scalable=no">
  5. Head and body elements MUST be included
    • e.g. <head></head><body></body>

Table of Contents

Example

<!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

3. Comments

This section describes how comments should be formatted and used.

  1. Single-line comments MUST be on one line and text inside MUST be surrounded by spaces
    • e.g. <!-- This is a comment -->
  2. 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 -->
  3. Closing tag comments SHOULD include the class or ID symbol and name
    • e.g. </div><!-- #main-wrapper -->
  4. Sensitive information MUST NOT be placed in a comment
    • e.g. <!-- Sends email to user@domain.com -->

Table of Contents

1. Single-line Comments

Single-line comments MUST be on one line and text inside MUST be surrounded by spaces.

Incorrect

<!--
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.

Correct

<!-- This is a comment -->

Comments

2. Multi-line Comments

Multi-line comments MUST start and end on their own line and text MUST NOT be indented.

Incorrect

<!-- 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.

Correct

<!--
This is a comment
that spans multiple lines
-->

Comments

3. Closing Tag Comments

Closing tag comments SHOULD include the class or ID symbol and name.

Incorrect

<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 #.

Correct

<div id="main-wrapper">
	...
</div><!-- #main-wrapper -->

Comments

4. Sensitive Information

Sensitive information MUST NOT be placed in a comment.

Incorrect

<!-- Generated by some_php_function() -->

↳ Incorrect because comment reveals that markup comes from some_php_function().

Comments

4. Formatting

This section outline various, general formatting rules related to whitespace and text.

  1. Line indentation MUST be accomplished using tabs
    • i.e. <ul> <li>
  2. Direct child elements within html, body, style or script element MUST NOT be indented
    • i.e. <body> <h1></h1> </body>, <head> ... </head>
  3. Block, list and table elements MUST start on a new line and their children MUST be indented
    • i.e. <div> <h1>, <table> <th>
  4. Trailing whitespace MUST NOT be present
    • i.e. no <p></p> · ·
  5. Elements and attributes MUST be all lowercase
    • e.g. <a href="" title="">, <link rel="stylesheet" href="">

Table of Contents

1. Line Indentation

Line indentation MUST be accomplished using tabs.

Incorrect

<ul>
  <li>Item number one</li>
  <li>Item number two</li>
</ul>

↳ Incorrect because <li> is indented with spaces instead of tabs.

Correct

<ul>
	<li>Item number one</li>
	<li>Item number two</li>
</ul>

Formatting

2. Direct Child Elements

Direct child elements within html, body, style or script element MUST NOT be indented.

Incorrect

<!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.

Correct

<!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>

Formatting

3. Block, List and Table Elements

Block, list and table elements MUST start on a new line and their children MUST be indented.

Incorrect

<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.

Correct

<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>

Formatting

4. Trailing Whitespace

Trailing whitespace MUST NOT be present.

Incorrect

<p>This is a paragraph.</p>   

↳ Incorrect because there are spaces after </p>.

Correct

<p>This is a paragraph.</p>

Formatting

5. Elements and Attributes

Elements and attributes MUST be all lowercase.

Incorrect

<div ID="mainWrapper" class="DESKTOP">
	<P>This is a paragraph</P>
</div>

↳ Incorrect because ID, mainWrapper, DESKTOP and <P> are not lowercase.

Correct

<div id="main-wrapper" class="desktop">
	<p>This is a paragraph</p>
</div>

Formatting

5. Elements and Attributes

This section addresses how to utilize elements and attributes.

  1. Self-closing elements MUST NOT be closed
    • e.g. <br>, <link rel="stylesheet" href="">
  2. Optional open/close tags MUST be included
    • e.g. <ul><li></li></ul>
  3. Attribute values MUST be wrapped in double quotation marks
    • e.g. <a href="" title="">Link</a>
  4. Attribute booleans SHOULD NOT include a value
    • e.g. <input type="text" name="" autofocus>
  5. Type and language attribute MUST be omitted on script tags
    • e.g. <script src=""></script>
  6. Type attribute MUST be omitted on link and style tags
    • e.g. <style src=""></script>
  7. Protocol SHOULD be omitted
    • e.g. <link href="//style.css" rel="stylesheet">

Table of Contents

1. Self-closing Elements

Self-closing elements MUST NOT be closed.

Incorrect

<link href="theme.css" rel="stylesheet" />

<br />

↳ Incorrect because <link> and <br> have a / at the end.

Correct

<link href="theme.css" rel="stylesheet">

<br>

Elements and Attributes

2. Optional Open/Close Tags

Optional open/close tags MUST be included.

Incorrect

<!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.

Correct

<!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>

Elements and Attributes

3. Attribute Values

Attribute values MUST be wrapped in double quotation marks.

Incorrect

<form action=processor.php class='application'>
	...
</form>

↳ Incorrect because processor.php and application are not wrapped in double quotes.

Correct

<form action="processor.php" class="application">
	...
</form>

Elements and Attributes

4. Attribute Booleans

Attribute booleans SHOULD NOT include a value.

~ Acceptable

<input type="text" name="first_name" autofocus="autofocus">

↳ Acceptable, but autofocus value is not required for autofocus attribute.

Correct

<input type="text" name="first_name" autofocus>

Elements and Attributes

5. Type and Language Attribute

Type and language attribute MUST be omitted on script tags.

Incorrect

<script src="//script.js" type="text/javascript"></script>

↳ Incorrect because type attribute is included.

Correct

<script src="//script.js"></script>

Elements and Attributes

6. Type Attribute

Type attribute MUST be omitted on link and style tags.

Incorrect

<link rel="stylesheet" href="//style.css" type="text/css">

↳ Incorrect because type attribute is included.

Correct

<link rel="stylesheet" href="//style.css">

Elements and Attributes

7. Protocol

Protocol SHOULD be omitted.

~ Acceptable

<link rel="stylesheet" href="http://domain.com/style.css">

↳ Acceptable, but http://domain.com could be replaced with //.

Correct

<link rel="stylesheet" href="//style.css">

Elements and Attributes

6. Best Practices

  1. Structures, styles and scripts MUST be separated from each other
    • e.g. <a class="button" data-track="pageview">Read More</a>
  2. Valid HTML MUST be written
    • i.e. yes <ul><li></li></ul>, no <ul><p></p></ul>
  3. Semantic HTML MUST be written
    • i.e. yes <a href="">View Options</a>, no <div class="click">View Options</div>
  4. Form field labels MUST be used
    • e.g. <label for=""></label><input name="" type="text">
  5. Form field names MUST use underscores to separate words
    • e.g. <input type="text" name="first_name">
  6. Entity references MUST NOT be used
    • e.g. yes , no &mdash;

Table of Contents

1. Structures, Styles and Scripts

Structures, styles and scripts MUST be separated from each other.

Incorrect

<div class="internships-module">
	...
</div>

↳ Incorrect because structure, style and functionality are not decoupled.

Correct

<div class="module internships" data-track="pageview event">
	...
</div>

Best Practices

2. Valid HTML

Valid HTML MUST be written.

Incorrect

<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>.

Correct

<ul>
	<li>Item one</li>
	<li>Item two</li>
	<li>
		<ul>
			<li>Sub-item one</li>
			<li>Sub-item two</li>
		</ul>
	</li>
</ul>

Best Practices

3. Semantic HTML

Semantic HTML MUST be written.

Incorrect

<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.

Correct

<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> 

Best Practices

4. Form Field Labels

Form field labels MUST be used.

Incorrect

<input type="radio" name="gender" id="male" value="male">
<input type="radio" name="gender" id="female" value="female">

↳ Incorrect because <label> is missing.

Correct

<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>

Best Practices

5. Form Field Names

Form field names MUST use underscores to separate words.

Incorrect

<input type="text" name="emailaddress">
<input type="text" name="email-address">

↳ Incorrect because emailaddress and email-address are not using underscores between words.

Correct

<input type="text" name="email_address">

Best Practices

6. Entity References

Entity references MUST NOT be used.

Incorrect

↳ Incorrect because &euro; entity reference is used.

Correct

Best Practices


Table of Contents

Inspired in part by style guides from: CKAN, Google, jQuery, and WordPress.

@mekkanix

This comment has been minimized.

Copy link

@mekkanix mekkanix commented Mar 5, 2018

Most of your conventions are good, but I really don't agree with the Direct Child Elements.
For me, it's not because <html>, <head> and <body>are sepcial tags that their content is exempted from being indented.
Indentation make things clearer and easier to read in almost every case. Do not omit them in these tags.

(And I'm pretty sure that a lot a front-end developers prefer indentation even in the these special tags).

@samjamead

This comment has been minimized.

Copy link

@samjamead samjamead commented Apr 26, 2018

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

@StevenWard94

This comment has been minimized.

Copy link

@StevenWard94 StevenWard94 commented Jul 14, 2018

Do you have a reason for why you suggest using tabs instead of spaces for indentation? If anything, I would assume that an HTML style guide might be neutral on the issue given HTML's fairly "whitespace-neutral" syntax but I find it odd that you would go with tabs as a standard. There's no doubt you have more experience with practical HTML than I do so I could easily be missing the point or just be outright ignorant of something but I was curious if you had an explanation.

@ykiu

This comment has been minimized.

Copy link

@ykiu ykiu commented Aug 6, 2018

@samjamead Omitting / of void elements is allowed in HTML5 (which is not the case with XHTML). See https://www.w3.org/TR/html5/syntax.html#start-tags
And the author of this style guide encourages using HTML5.

@naitsirch

This comment has been minimized.

Copy link

@naitsirch naitsirch commented Dec 4, 2018

How should many long attributes be wrapped?

<div class="aaaaaaaaaaaaaaa bbbbbbbbbbbbbbb ccccccccccccccccc" id="abcdefghijklmnopqrstuvwxyz" ng-show="checkIfThisElementShouldBeShownWhenSomethingIsTrueOrNot()">
    Foo
</div>

like this?

<div class="aaaaaaaaaaaaaaa bbbbbbbbbbbbbbb ccccccccccccccccc"
     id="abcdefghijklmnopqrstuvwxyz"
     ng-show="checkIfThisElementShouldBeShownWhenSomethingIsTrueOrNot()">
    Foo
</div>

or like this?

<div class="aaaaaaaaaaaaaaa bbbbbbbbbbbbbbb ccccccccccccccccc"
 id="abcdefghijklmnopqrstuvwxyz"
 ng-show="checkIfThisElementShouldBeShownWhenSomethingIsTrueOrNot()"
>
    Foo
</div>

or another way? What is best readable? I have no real clue ^^

@ben-turner

This comment has been minimized.

Copy link

@ben-turner ben-turner commented Jan 18, 2019

"Entity references must not be used"

Except you need to. For example, you must write &amp;euro; if you want to display the text &euro; otherwise you just end up with . Also for displaying html, you have to use &lt;tag att="val"&gt; otherwise it will just be parsed as an HTML tag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment