Every HTML document is built from the same few pieces: elements, tags and attributes. Learn their rules once and you can read any HTML you meet.
Anatomy of an element
<p class="intro">Welcome to the shop.</p>
<p class="intro">is the opening tag. It contains the element namepand one attribute.Welcome to the shop.is the content.</p>is the closing tag. It repeats the name after a forward slash.- The whole thing, from opening tag to closing tag, is the element.
People often say "tag" when they mean "element". The difference matters when you debug: an element can be missing its closing tag, but it is still an element in the DOM.
Element names are not case-sensitive, but the convention is lowercase. Write <p>, not <P>.
Nesting
Elements can contain other elements. The inner one is a child; the outer one is its parent.
<p>Delivery is <strong>free</strong> on orders over £50.</p>
The rule: close elements in the reverse order you opened them. Think of it like brackets.
<!-- Wrong: tags overlap -->
<p>Delivery is <strong>free</p></strong>
<!-- Right: the inner element closes first -->
<p>Delivery is <strong>free</strong></p>
Browsers repair overlapping tags, but not always the way you expect, and the repaired DOM can break your CSS and JavaScript. Indent nested elements so the structure is visible:
<ul>
<li>Bread</li>
<li>Cakes
<ul>
<li>Birthday</li>
<li>Wedding</li>
</ul>
</li>
</ul>
What can go inside what
Not every element can contain every other. The specification defines a content model for each element. A few rules you will hit early:
- A
pcannot contain block-level structures such as anotherp, adiv, a list or a heading. The browser closes the paragraph early when it meets one. ulandolmay contain onlylielements (plusscriptandtemplate) as direct children.- An
aelement must not contain another link or a button. - A
buttonmust not contain other interactive elements.
<!-- Wrong: the browser ends the p before the div -->
<p>Opening times <div>9am to 5pm</div></p>
<!-- Right -->
<div>
<p>Opening times</p>
<p>9am to 5pm</p>
</div>
Void elements
Some elements cannot have content, so they have no closing tag. These are void elements. The common ones are:
| Element | Purpose |
|---|---|
br | Line break within text |
hr | Thematic break between sections of content |
img | Image |
input | Form control |
link | Link to an external resource such as a stylesheet |
meta | Metadata |
source | Media source for picture, audio or video |
track | Text track for media |
The others are area, base, col, embed and wbr.
<img src="cake.jpg" alt="A three-tier wedding cake with white icing">
<p>Call us on<br>020 7946 0000</p>
You may see void elements written with a trailing slash, such as <br />. In HTML the slash is allowed but ignored. It comes from XHTML. Pick one style and be consistent. This course leaves it out.
The trailing slash does nothing on non-void elements. <div /> is not an empty, closed div. The browser treats it as an opening tag, and everything after it ends up inside the div.
Attributes
Attributes add information to an element. They go in the opening tag as name="value" pairs, separated by spaces.
<a href="/contact" title="Opening hours and address">Contact us</a>
Rules for attributes:
- Wrap values in double quotes. Quotes are optional for simple values, but always using them avoids bugs with spaces and special characters.
- Each attribute may appear only once per element.
- Attribute names are not case-sensitive; write them in lowercase.
- Order does not matter.
Global attributes
Some attributes work on every element. You will use these constantly:
| Attribute | What it does |
|---|---|
id | A unique identifier for one element on the page |
class | One or more space-separated names for styling and scripting |
lang | The language of the element's content |
title | Extra advisory text, often shown as a tooltip |
hidden | Hides the element from everyone |
data-* | Custom data for your own scripts, such as data-product-id="42" |
<section id="reviews" class="panel panel--highlight" data-count="12">
<h2>Reviews</h2>
<p lang="fr">Délicieux.</p>
</section>
An id must be unique in the document and must not contain spaces. A class can be shared by many elements, and one element can have several classes.
Boolean attributes
Some attributes are on or off. Their presence means true, and their absence means false.
<input type="checkbox" checked>
<button disabled>Sold out</button>
Writing disabled="false" does not enable the button. Any value, even "false", counts as present. To turn a boolean attribute off, remove it.
Comments
Comments are notes that the browser ignores:
<!-- Navigation starts here -->
<nav>...</nav>
Comments are visible to anyone who views the source, so never put passwords, private notes or internal URLs in them.
Character references
A few characters have special meaning in HTML. To show them as text, use a character reference:
| To show | Write |
|---|---|
< | < |
> | > |
& | & |
" inside an attribute value | " |
With meta charset="utf-8" and a UTF-8 file, you can type everything else directly, including £, é and emoji.
Check your markup
The W3C validator at validator.w3.org reports nesting errors, missing attributes and unknown elements. Paste your HTML in or upload the file. Fix errors from the top down, because one early mistake often causes several reports further on.
Summary
- An element is an opening tag, content and a closing tag.
- Close nested elements in reverse order, and respect each element's content model.
- Void elements such as
img,br,inputandmetahave no closing tag. - Attributes go in the opening tag as quoted
name="value"pairs. Boolean attributes are on when present. - Use character references for
<and&in text, and validate your markup regularly.