HTML Attributes
Tags tell the browser what something is. Attributes tell the browser more details about it. An <img> tag says "there's an image here," but it's the attributes that say which image file, how big, and what to describe it as if it fails to load.
If elements are the nouns of HTML, attributes are the adjectives. They add detail, behavior, and meaning to the tags you already know.
An attribute is extra information added inside an element's start tag, always written as a name, usually followed by an equals sign and a value in quotes.
Anatomy of an Attributeβ
<a href="https://codeharborhub.github.io" target="_blank">Visit CodeHarborHub</a>
| Part | Example | Meaning |
|---|---|---|
| Name | href | What kind of information this is. |
| Equals sign | = | Connects the name to its value. |
| Value | "https://codeharborhub.github.io" | The actual information, wrapped in quotes. |
An element's start tag can carry as many attributes as it needs, separated by spaces:
<img src="cat.jpg" alt="A sleeping cat" width="300" height="200" loading="lazy" />
Attributes only ever appear in the start tag. A closing tag, like </a> or </p>, never carries attributes.
Quoting Rulesβ
HTML gives you some flexibility in how you quote attribute values, but one option is clearly the professional standard.
- β Double quotes (recommended)
- π‘ Single quotes (also valid)
- β No quotes (avoid)
<a href="https://example.com">Link</a>
This is the convention used across virtually every style guide, framework, and real-world codebase. Use this by default.
<a href='https://example.com'>Link</a>
Technically valid HTML, but far less common. Useful in rare cases where your value itself contains double quotes.
<a href=https://example.com>Link</a>
This works only if the value has no spaces or special characters, but it's fragile, inconsistent, and considered bad practice. Never rely on it.
Even when HTML technically allows skipping quotes, a single space or special character in an unquoted value can silently break your markup. Quoting every value removes this entire category of bugs.
Categories of Attributesβ
Not all attributes behave the same way. Let's group them by how they work.
1. Required attributesβ
Some attributes are essential for an element to function correctly, even though HTML won't stop you from omitting them.
<img src="logo.png" alt="Company logo" />
<a href="https://example.com">Click here</a>
Without src, an <img> has nothing to display. Without href, an <a> isn't really a link at all, just plain text.
2. Optional attributesβ
These add extra behavior or refinement but are not strictly necessary for the element to work.
<img src="logo.png" alt="Company logo" width="200" loading="lazy" />
Here, width and loading are helpful, but the image would still display without them.
3. Boolean attributesβ
These are special: their mere presence turns a feature on. They don't need a value at all, and writing them any of these ways means the same thing:
- Bare (recommended)
- Empty string
- Value equals name
<input type="text" disabled />
<input type="text" disabled="" />
<input type="text" disabled="disabled" />
All three examples disable the input. The first style, just the bare attribute name, is the cleanest and most widely used.
| Boolean attribute | What it does |
|---|---|
disabled | Disables a form field or button |
checked | Pre-checks a checkbox or radio button |
required | Makes a form field mandatory |
readonly | Prevents editing, but still submits the value |
autofocus | Focuses the field automatically on page load |
multiple | Allows selecting multiple values |
Unlike other attributes, you cannot "turn off" a boolean attribute by setting it to "false". Writing disabled="false" is still treated as present, and the field stays disabled. To disable the behavior, delete the attribute completely.
Global vs. Specific Attributesβ
Some attributes work on almost any element (id, class, title, style), while others only make sense on specific tags.
- Works almost everywhere
- Specific to certain tags
<p id="intro" class="highlight" title="Introduction paragraph">
Welcome!
</p>
<div id="sidebar" class="highlight"></div>
<a href="https://example.com">Only links use href</a>
<img src="photo.jpg" alt="Only images use src and alt" />
<input type="email" />
The "works almost everywhere" group is called global attributes, and they deserve their own full lesson because there is quite a bit to cover.
π See the next lesson: Global Attributes
A Field Guide to Common Attributesβ
- Links & Media
- Forms
- General purpose
| Attribute | Used on | Purpose |
|---|---|---|
href | <a>, <link> | The destination URL |
src | <img>, <video>, <script> | The source file |
alt | <img> | Alternative text description |
target | <a> | Where to open the link (e.g. _blank) |
width / height | <img>, <video> | Dimensions |
| Attribute | Used on | Purpose |
|---|---|---|
type | <input> | The kind of field (text, email, checkbox...) |
name | Form fields | The field's identifier when submitted |
value | Form fields | The field's current or default value |
placeholder | <input>, <textarea> | A hint shown in an empty field |
required | Form fields | Marks the field as mandatory |
| Attribute | Used on | Purpose |
|---|---|---|
id | Almost any element | A unique identifier |
class | Almost any element | A reusable style/JS hook |
style | Almost any element | Inline CSS |
title | Almost any element | A tooltip shown on hover |
lang | <html> | The document or section's language |
Attributes in Actionβ
Let's see a form input change behavior live, purely through its attributes:
- Normal input
- Disabled input
- Required + type=email
<input type="text" placeholder="Type your name" />
<input type="text" placeholder="Type your name" disabled />
<input type="email" placeholder="you@example.com" required />
Same <input> tag every time. Completely different behavior, purely because of the attributes attached to it.
Custom data-* Attributesβ
Sometimes you need to attach your own custom information to an element, information meant for your JavaScript, not for the browser's built-in behavior. HTML provides an official, valid way to do this: data-* attributes.
<button data-user-id="4821" data-role="admin">Delete User</button>
You can name anything after data-, as long as it's lowercase and hyphen-separated. JavaScript can then read these values easily:
const button = document.querySelector("button");
console.log(button.dataset.userId); // "4821"
console.log(button.dataset.role); // "admin"
Inventing your own attribute like <button userid="4821"> is invalid HTML and can clash with future standard attributes. The data-* prefix is officially reserved for this exact purpose, so it's always safe and valid.
Common Attribute Mistakesβ
1. Forgetting quotes around a value with spaces
<!-- β Breaks: the browser reads "profile" as a second attribute -->
<img src=my profile.jpg alt="Profile picture">
<!-- β
Correct -->
<img src="my profile.jpg" alt="Profile picture" />
2. Using the same attribute twice on one tag
<!-- β Confusing and invalid: which class actually applies? -->
<p class="intro" class="highlight">Hello</p>
<!-- β
Correct: combine values with a space -->
<p class="intro highlight">Hello</p>
3. Trying to "disable" a boolean attribute with a false value
<!-- β Still disabled! Presence alone matters, not the value -->
<input type="text" disabled="false" />
<!-- β
Correct: remove the attribute entirely to enable the field -->
<input type="text" />
4. Forgetting essential attributes
<!-- β A link with no destination, and an image with no fallback text -->
<a>Click here</a>
<img src="chart.png">
<!-- β
Correct -->
<a href="https://example.com">Click here</a>
<img src="chart.png" alt="Sales chart for Q1" />
Quick Recapβ
- An attribute adds extra information to a tag, written as
name="value". - Attributes live only in the start tag, never in a closing tag.
- Always wrap attribute values in double quotes.
- Boolean attributes (like
disabledandchecked) turn a feature on just by being present. - Global attributes (like
idandclass) work on nearly every element. - Custom
data-*attributes let you safely attach your own information for JavaScript to use.
Frequently Asked Questionsβ
What is an HTML attribute?
An HTML attribute provides extra information about an element, written inside the start tag as a name and value pair, such as src="photo.jpg".
Do all attributes need a value?
No. Boolean attributes, like disabled and checked, only need to be present to take effect and do not require a value.
Can an element have more than one attribute?
Yes, an element can have as many attributes as needed, separated by spaces, for example <img src="a.jpg" alt="A photo" width="200" />.
Is it okay to skip quotes around attribute values?
It is technically allowed for simple values with no spaces, but it is considered bad practice. Always use double quotes to avoid subtle bugs.
What is a data-* attribute used for?
Custom data-* attributes let you attach your own information to an element for JavaScript to read later, without creating invalid or non-standard HTML.
Test Your Understandingβ
- What is the basic syntax pattern for writing an attribute?
- Why should attribute values always be quoted?
- What makes a "boolean attribute" different from a regular attribute?
- How would you correctly disable, then later re-enable, an
<input>element? - Why are
data-*attributes preferred over inventing your own custom attribute names?