HTML Attribute Reference

Every HTML element can carry extra information through attributes — name/value pairs written inside the opening tag that configure, identify, or describe that element. Attributes are how you turn a generic <input> into an email field, mark a paragraph with an id for linking, or attach custom data for scripts to read later. Understanding how attributes are written, parsed, and applied is essential to writing correct, robust HTML.

Overview: How Attributes Work

An attribute lives inside the start tag of an element, after the tag name, and never appears in the closing tag. The browser’s HTML parser reads the tag name first, then scans for a sequence of name="value" pairs (or bare names) until it reaches the closing >. Each attribute becomes a property on the corresponding node in the DOM (Document Object Model) — the tree structure the browser builds from your markup. For example, when the parser sees <a href="/about">, it creates an anchor node in the DOM and stores href as an attribute on that node, which the browser then uses to make the element a clickable link.

Attributes fall into a few broad categories:

  • Global attributes — usable on virtually any element (id, class, title, lang, tabindex, hidden, style, data-*).
  • Element-specific attributes — only meaningful on certain elements (href on <a>, src on <img>, type on <input>).
  • Boolean attributes — attributes whose mere presence means “true”, regardless of the value written (disabled, checked, required, readonly).
  • Event handler attributes — attributes like onclick that run script code; these belong to the JavaScript course and are only mentioned here for completeness.

Attribute values are almost always treated as plain text (strings) by the parser, even when they look numeric — data-price="19.99" is stored as the string "19.99", not a number, until a script explicitly converts it.

Syntax

<tagname attribute1="value1" attribute2="value2" booleanattribute>content</tagname>
  • Placement: attributes only appear in the opening tag, separated from the tag name and from each other by whitespace.
  • Quoting: values should be wrapped in double quotes (single quotes are also valid HTML, but double quotes are the near-universal convention). Quotes are technically optional for values with no spaces or special characters, but omitting them is a frequent source of bugs (see Common Mistakes).
  • Case: attribute names are case-insensitive in HTML, but lowercase is the standard convention.
  • Boolean attributes: written with no value at all (disabled) or, if you prefer, with the value equal to the attribute name itself (disabled="disabled") — both mean the same thing.
  • Custom data: any attribute prefixed with data- is reserved for your own custom information and will never clash with a future standard HTML attribute.

Examples

Example 1: Global attributes on a section

<section id="intro" class="highlight" title="Read this first" lang="en" tabindex="0">
  <h1>Welcome to the Guide</h1>
  <p>This section uses several global attributes.</p>
</section>

Result: The browser renders a heading and a paragraph as normal block content. Nothing about the attributes changes the visual layout by themselves, but hovering the section shows a tooltip reading “Read this first” (from title), the element becomes reachable by keyboard Tab navigation (from tabindex="0"), and scripts or CSS could target it via #intro or .highlight.

This shows the key idea: attributes rarely change what an element looks like on their own — they add hooks for styling, scripting, accessibility, and identification.

Example 2: Boolean attributes on form controls

<form>
  <label for="email">Email</label>
  <input type="email" id="email" name="email" required>

  <label for="terms">
    <input type="checkbox" id="terms" name="terms" checked disabled>
    I already agreed to the terms
  </label>

  <button type="submit">Submit</button>
</form>

Result: A form appears with an email input that the browser will refuse to submit empty (because of required), and a checkbox that appears pre-checked but greyed out and unclickable (because of checked plus disabled). The submit button renders normally.

Notice that required, checked, and disabled have no ="value" at all — their presence alone activates the behavior.

Example 3: Custom data-* attributes

<ul class="product-list">
  <li data-id="101" data-price="19.99" data-in-stock="true">Wireless Mouse</li>
  <li data-id="102" data-price="49.50" data-in-stock="false">Mechanical Keyboard</li>
</ul>

Result: A plain bulleted list showing “Wireless Mouse” and “Mechanical Keyboard” — visually, the data-* attributes produce no visible change at all. They exist purely as a structured place to store information (like a product id or price) that a script can later read through the DOM, without inventing non-standard attributes that could collide with future HTML features.

Under the Hood: How the Parser Reads Attributes

When the browser’s HTML tokenizer encounters a start tag, it moves through a well-defined state machine: after the tag name, it looks for whitespace, then an attribute name, then optionally an = sign followed by a quoted or unquoted value. Each attribute name/value pair is attached to the element node the parser is building. If the same attribute name appears twice on one tag, the HTML specification says the parser keeps the first occurrence and ignores the rest — this is why duplicate attributes are a validation error rather than useful for “overriding” a value.

Once the DOM node exists, some attributes are also exposed as JavaScript properties (for example, the id attribute becomes element.id), while attributes the browser doesn’t specifically recognize are still stored and retrievable through methods like getAttribute(). This is exactly how data-* attributes work: the browser doesn’t understand what “price” or “in-stock” means, but it faithfully preserves the attribute so your own code can read it later via the dataset property.

Common Mistakes

Mistake 1: Unquoted values containing spaces

<input type=text value=Product Name>

Why it’s wrong: Without quotes, the parser treats whitespace as the end of the attribute value. Here it reads value="Product" and then treats the word Name as an entirely separate, meaningless boolean attribute — the input’s value silently becomes just “Product” instead of “Product Name”.

<input type="text" value="Product Name">

Fix: Always quote attribute values, especially any value that could contain spaces, so the full string is captured correctly.

Mistake 2: Assuming a boolean attribute’s value turns it off

<button disabled="false">Click me</button>

Why it’s wrong: For boolean attributes like disabled, checked, and required, the browser only checks whether the attribute is present — the text of the value is irrelevant. Writing disabled="false" still disables the button, which surprises many beginners.

<button>Click me</button>

Fix: To leave a boolean attribute “off”, omit it completely rather than setting it to a falsy-looking string.

Mistake 3: Duplicate ids across elements

<div id="main">First block</div>
<div id="main">Second block</div>

Why it’s wrong: The id attribute must be unique within the whole document. With two elements sharing id="main", calls like document.getElementById("main") and CSS rules like #main only ever reliably reach the first match, silently breaking scripts or styles meant for the second element.

<div id="main-first">First block</div>
<div id="main-second">Second block</div>

Fix: Give every id a distinct name, and use class instead when you need to group several elements under a shared label.

Best Practices

  • Always quote attribute values with double quotes, even when the current value has no spaces — it protects you if the value changes later.
  • Use data-* attributes instead of inventing non-standard attribute names for custom information.
  • Keep id values unique per page; use class for anything shared by multiple elements.
  • Write boolean attributes in their shorthand form (required, not required="required") for readability, and never rely on a “false” string value to turn one off.
  • Prefer semantic, element-specific attributes (like alt on images or for on labels) over generic title tooltips for accessibility — screen readers treat them very differently.
  • Avoid style attributes for anything beyond a quick test; move real styling into CSS, which is covered in the CSS course.
  • Set lang on the <html> element (and on any element whose text is in a different language) so assistive technology can choose the right pronunciation rules.

Practice Exercises

  • Exercise 1: Write a <button> element that is disabled by default, along with a second, identical-looking button that is enabled. Explain in your own notes which HTML feature makes the difference.
  • Exercise 2: Create three <li> elements representing tasks, each with a unique data-priority attribute set to “high”, “medium”, or “low”. No visual change is expected — the goal is correct, well-formed use of custom data attributes.
  • Exercise 3: Take a snippet with an unquoted, multi-word attribute value (like title=Click here now) and rewrite it correctly, explaining what the browser would have done with the broken version.

Summary

  • Attributes are name/value pairs written inside an element’s opening tag that configure or describe it.
  • Global attributes like id, class, and data-* work on nearly every element; others are specific to certain tags.
  • Boolean attributes (disabled, checked, required) are on when present, regardless of their value text.
  • Always quote attribute values, especially ones containing spaces, to avoid the parser misreading your markup.
  • id values must be unique per page; duplicates silently break scripts and styles.
  • data-* attributes are the standard, collision-free way to attach custom information to elements.