HTML basics · 3 / 8
lesson 3

Tags and attributes

Two primitives, a handful of rules, and you can read any HTML ever written.

~ 9 min read·lesson 3 of 8
0 / 8

Every HTML page you will ever read or write is built out of two ideas: tags and attributes. Once you can name those two things and the small rules around them, every weird-looking piece of markup you bump into stops being weird.

This lesson zooms in on those two primitives and the handful of edge cases — like tags that close themselves, and attributes that do not need a value — that catch most beginners out.

Tags wrap content

A tag is the angle-bracket label you put around a piece of content. Most tags come as a pair: an opening tag that starts the wrap, and a closing tag that ends it. The closing tag looks like the opening one with a slash in front of the name.

basic.html
<p>This whole sentence is a paragraph.</p>

<p> opens the wrap, </p> closes it, and the text in between is the paragraph's content. The opening tag plus the closing tag plus everything between them is called an element. So <p>This is a paragraph.</p> is a "p element". You will hear "tag" and "element" used loosely, but technically a tag is just the angle-bracket label and an element is the whole wrapped thing.

Elements can hold other elements. Wrap a <strong> (which means "this text is important") inside a <p>, and the strong element lives inside the paragraph element.

nested.html
<p>Tickets cost <strong>$5</strong> at the door.</p>

The rule is simple: whatever you open last, you close first. Imagine the tags as boxes. You can put a small box inside a big one, but you cannot have the small box and the big box overlap halfway. Crossed tags like <p><strong>...</p></strong> are wrong — the parser will untangle them, but the result will not match what you wrote.

check your understanding
Which of these is correctly nested HTML?

Tags that do not wrap anything

Most tags wrap content, but a few tags exist where there is nothing to wrap. An image, for instance, is just a thing on the page — there is no text inside it to enclose. Same with a line break, or one of the meta tags from the last lesson.

These are called void elements ("void" as in empty). They have an opening tag and that is it — no closing tag, because there would be nothing for the closing tag to close.

void.html
<img src="cat.jpg" alt="A grey cat napping on a sofa.">
<br>
<meta charset="utf-8">
<input type="text">

<img> puts an image on the page. <br> is a hard line break. <meta> sets a piece of page-level information. <input> is a form field. None of them wrap any content, so none of them need a closing tag.

You may sometimes see void elements written with a slash before the closing bracket, like <br />. That style comes from a stricter dialect of HTML called XHTML. In modern HTML the slash is optional and ignored — <br> and <br /> mean the same thing. Pick whichever your editor inserts and move on.

Watch out

Do not invent your own self-closing tags. <p /> looks plausible, but <p> is not a void element — the parser will treat your "self-close" as just an opening tag and then look for the matching </p> later. Stick to the void list (img, br, hr, input, meta, link, and a few others).

check your understanding
Which line is correct HTML?

Attributes add details

A tag on its own says "this is a link" or "this is an image", but it does not say which link or which image. That extra detail is carried by attributes — little name-value pairs you write inside the opening tag.

attributes.html
<a href="/about" title="About this site">About</a>
<img src="cat.jpg" alt="A grey cat" width="320">
<input type="email" placeholder="you@example.com" required>

Each attribute has two parts: a name (href, src, type) and usually a value in quotes ("/about", "cat.jpg", "email"). They go inside the opening tag, separated by spaces. The closing tag does not repeat them — </a>, not </a href="...">.

You can read each line as a sentence. The first line says "this is a link, going to /about, with a tooltip 'About this site', and the visible label is 'About'". The third line says "this is an input, of type email, with placeholder text, and it must be filled in".

A few small syntax rules:

  • Quotes are recommended. Modern HTML lets you skip quotes for simple values (href=/about), but most teams insist on them because the moment a value contains a space or a special character, the unquoted version breaks. Use double quotes by default.
  • No spaces around the =. href = "/about" works in some browsers and breaks in others. Write href="/about".
  • Attribute names are case-insensitive. HREF and href mean the same. Convention is lowercase.

The third line above also shows a special kind of attribute. The word required sits there alone with no value attached. That is on purpose — it is a boolean attribute.

A boolean attribute is an attribute whose only job is to say "yes, this is on". It is either present (on) or absent (off). There is no middle state. You do not write required="true" or required="false"; you just write required to turn it on, or leave it off entirely.

boolean.html
<input type="email" required>            <!-- required: on -->
<input type="email">                     <!-- required: off -->
<input type="email" required="true">     <!-- still just on -->
<input type="email" required="false">    <!-- still on! -->

The last line is the trap. Writing required="false" looks like it should turn the attribute off, but the parser only checks whether the attribute is there — the value does not matter. To turn required off, leave it out completely.

check your understanding
You write <input type="text" disabled="false"> hoping the field will be enabled. What actually happens?

Global attributes

Most attributes only make sense on certain tags — href on <a>, src on <img>. But a small group of attributes can go on any element. These are called global attributes, and a few are worth meeting now because you will see them on every real page.

  • id — a unique name for an element, useful for linking to it (<a href="#contact">) or styling it from CSS.
  • class — one or more reusable names that CSS or JavaScript can target. An element can have many classes, separated by spaces.
  • lang — the language of the content inside, like lang="en" or lang="ja". Screen readers use this to pick the right pronunciation.
  • title — a tooltip that appears when you hover over the element.
globals.html
<section id="contact" class="card highlighted" lang="en">
<h2>Get in touch</h2>
<p title="Updated weekly">Open Mon–Fri, 9–5.</p>
</section>

Reading that: the <section> has the unique id "contact" (so a link href="#contact" will scroll to it), it has two CSS classes ("card" and "highlighted"), and the language inside is English. The <p> has a tooltip that shows on hover.

There is one rule about id worth pinning: an id has to be unique within the page. If you give two elements the same id, both still render, but anything that searches for that id (a #contact link, a CSS rule, a script) will only find the first one. Treat ids like seat numbers in a theatre — one per element, no duplicates.

Tip

Use class when many elements share a behaviour or style; use id when there is only ever one of that thing on the page. "Make all buttons rounded" is a class job. "Scroll to the contact form" is an id job.

check your understanding
Two elements on your page both have id="header". You set up a link <a href="#header">Back to top</a>. What happens when the link is clicked?
← prevnext lesson →
KeepLearningcertificate
for completing
HTML basics
0 of 8 read