HTMLBeginner

HTML Attributes In Depth: Global Attributes You Should Know

Go beyond href and src: learn HTML's global attributes — id, class, style, title, lang, data-*, hidden, tabindex — and why inline style is a last resort.

All HTML lessons

What you will learn

You already know that an attribute is extra information written inside an opening tag, like href="..." on a link or src="..." on an image. Those are specific to one element — href only makes sense on <a>, src only on <img> and a few others. But HTML also has a set of global attributes: ones that work on almost every element, regardless of what it is. In this lesson you will learn the most useful global attributes, why the style attribute you have been using is actually the one to use least, and how to attach your own custom data to any element.

A quick recap: what makes an attribute

An attribute is a name="value" pair written inside the opening tag, separated by spaces, with the value in quotes:

<p id="intro" class="highlight" title="A friendly welcome">Hello!</p>

Here id, class and title are three separate attributes on the same <p>. (If any of this feels new, the elements-and-tags lesson covers the basic anatomy of tags and attributes in detail — this lesson builds on that and focuses on the attributes themselves.)

Two kinds of attributes

Kind Works on Examples
Element-specific Only certain elements href (<a>), src/alt (<img>), type (<input>)
Global Almost any HTML element id, class, style, title, lang, data-*, hidden, tabindex

This lesson is about the second kind — the attributes that are always available, no matter which element you’re writing.

id: a unique name for one element

<p id="welcome-message">Welcome to the site!</p>
  • Must be unique on the whole page — never reuse the same id twice.
  • Used to target one exact element from CSS (#welcome-message), from JavaScript, or as the destination of a same-page link (<a href="#welcome-message">, which you met in the links lesson).
  • No spaces allowed, and by convention it is written in lower case with hyphens: main-nav, not Main Nav.

class: a reusable label

<p class="card">First card</p>
<p class="card">Second card</p>
<p class="card highlighted">Third card, also highlighted</p>
  • Can be used on as many elements as you like.
  • One element can have multiple classes, separated by spaces — the third paragraph above has both card and highlighted.
  • Used constantly in CSS (.card { ... }) and JavaScript, to style or select a whole group of elements at once.

You met id and class already in the grouping lesson; they are worth repeating here because they are the two most-used global attributes of all.

style: inline CSS (use sparingly)

<p style="color: red; font-weight: bold;">Important notice</p>

style lets you write CSS directly on one element. It is useful for quick experiments, but on a real project it is usually the wrong tool, for three reasons:

  1. It cannot be reused. If ten paragraphs need the same red, bold style, you must repeat the same style text ten times.
  2. It is hard to maintain. Changing the look later means hunting through your HTML file for every style="" instead of editing one CSS rule.
  3. It always wins, even over CSS you write carefully in a stylesheet, which can cause confusing bugs (you will learn why in the CSS specificity lesson).

The better habit, almost always:

<!-- Instead of this -->
<p style="color: red; font-weight: bold;">Important notice</p>

<!-- Do this -->
<p class="notice">Important notice</p>
.notice {
  color: red;
  font-weight: bold;
}

Keep style for quick testing in the editor, or for a value that is genuinely different on every single element (like a dynamically calculated width set by JavaScript).

title: a tooltip

<p title="This paragraph explains the title attribute.">Hover over me.</p>
<abbr title="Hypertext Markup Language">HTML</abbr>

Hovering over the element shows the title text as a small tooltip. It is handy for a short explanation of an abbreviation, or an extra hint — but do not rely on it for anything important, since it is invisible on touchscreens (there’s no “hover” on a phone) and easy for a visitor to miss entirely.

lang: declaring the language

You’ve already seen this one on every page you’ve written, on the <html> tag:

<html lang="en">

lang tells browsers, search engines and screen readers what language the content is written in. A screen reader uses it to choose the correct pronunciation rules — English rules would badly mispronounce Hindi or French text. You can also set it on a smaller piece of content that switches language:

<p>My favourite word in French is <span lang="fr">bonjour</span>.</p>

Always set lang on <html>. It is a one-line habit with a real accessibility benefit.

hidden: hide an element completely

<p hidden>You will not see this at all.</p>

hidden is a boolean attribute (you met these in the elements-and-tags lesson — its presence alone turns it on, it needs no value). An element with hidden is removed from the page exactly like CSS display: none — it takes up no space and is skipped by screen readers. It is most useful for content that JavaScript will reveal later, such as a message that only appears after a form is submitted.

tabindex: keyboard navigation order

Pressing the Tab key on a keyboard moves focus between interactive elements (links, buttons, inputs) in the order they appear in the HTML. tabindex lets you adjust that:

<input type="text" tabindex="1">
<input type="text" tabindex="2">
<button tabindex="0">Submit</button>
Value Meaning
tabindex="0" Include this element in the natural tab order (useful to make a non-interactive element, like a <div>, keyboard-focusable)
tabindex="-1" Remove this element from the tab order, but it can still be focused by JavaScript
tabindex="1", "2", … A custom, explicit order

Be careful with positive numbers. They override the natural reading order of your page, and if you forget to number every focusable element, keyboard navigation can jump around unpredictably. Prefer writing your HTML in the order you want people to tab through, and reach for tabindex="0" or "-1" only when needed.

contenteditable: let visitors edit text in place

<p contenteditable="true">Click me and start typing!</p>

Turns any element into an editable text box, right there on the page. It is what powers rich-text editors and simple “click to edit” interfaces on real sites (usually combined with JavaScript to save the changes).

draggable: enable drag-and-drop

<p draggable="true">Drag me around</p>

Marks an element as draggable. By itself it doesn’t do much — you pair it with JavaScript’s Drag and Drop API to actually respond to the drag — but the attribute is what makes an element eligible in the first place.

data-*: your own custom attributes

Sometimes you want to attach information to an element that has no built-in attribute for it — information meant purely for your own JavaScript to read later. HTML lets you invent any attribute you like, as long as it starts with data-:

<p data-user-id="482" data-role="admin" data-signed-up="2026-01-15">
  Priya Sharma
</p>

<button data-product-id="A104" data-price="799">Add to Cart</button>

These attributes do nothing visible by themselves. They exist so JavaScript can read them later, for example when the “Add to Cart” button is clicked:

const button = document.querySelector("button");
console.log(button.dataset.productId); // "A104"
console.log(button.dataset.price);     // "799"

Notice the naming pattern: data-product-id in HTML becomes dataset.productId in JavaScript (hyphens turn into camelCase). You will use data-* attributes constantly once you reach the JavaScript and DOM lessons — they are the standard way to link a piece of HTML to information your script needs, without inventing a non-standard attribute that could clash with a future version of HTML.

The full list of global attributes (for reference)

You do not need to memorise all of these. The ones above are what you will actually reach for as a beginner. Here is the rest, so you recognise them if you see them:

Attribute What it does
accesskey Assigns a keyboard shortcut to jump to the element
dir Text direction: ltr (left-to-right) or rtl (right-to-left, for languages like Arabic and Urdu)
spellcheck Turns the browser’s spell-checker on or off for editable content
translate Hints to browser translation tools whether this content should be translated
contextmenu Associates a custom right-click menu (rarely supported today)

Attribute rules, revisited

A few rules from the elements-and-tags lesson are worth restating here, because they apply to every attribute in this lesson too:

  • Attributes go only in the opening tag.

  • Separate multiple attributes with spaces, and the order does not matter:

    <p id="a" class="b" title="c">...</p>
    <p title="c" class="b" id="a">...</p>  <!-- identical meaning -->
  • Always wrap the value in quotes.

  • Boolean attributes (hidden, disabled, required, checked) need no value — just writing the name turns them on.

Common mistakes

  • Reusing an id on more than one element. CSS, JavaScript and same-page links can all behave unpredictably when an id is not unique.
  • Reaching for style="" by default. It works, but it does not scale — use a class and a stylesheet for anything you will reuse or need to maintain.
  • Skipping lang on <html>. A one-line fix that genuinely helps screen reader users and search engines.
  • Using large positive tabindex values everywhere. It is easy to create a confusing tab order. Let the natural HTML order do the work whenever possible.
  • Inventing a custom attribute without the data- prefix, such as <div info="482">. Browsers may not recognise it correctly, and it can clash with a future official HTML attribute. Always prefix custom attributes with data-.
  • Forgetting that data-* values are always strings. data-price="799" gives you the text "799" in JavaScript, not the number 799 — you will need to convert it (Number(...)) before doing maths with it.

Interview-style questions

What is a global attribute? An attribute that can be used on almost any HTML element, regardless of its type — such as id, class, style, title, lang and data-*, as opposed to element-specific attributes like href or src.

Why is the style attribute generally discouraged over a CSS class? It cannot be reused across elements, it is harder to maintain since styles are scattered through the HTML, and it overrides stylesheet rules, which can cause confusing specificity issues.

What is a data-* attribute used for? To attach custom information to an element for your own JavaScript to read, when no built-in HTML attribute fits — for example data-product-id on a button.

What does tabindex="0" do? It adds the element to the natural keyboard tab order without changing that order, which is often used to make a non-interactive element (like a styled <div>) keyboard-focusable.

Practice

  1. Use the Practice in Editor button. Add a title attribute to the second paragraph and hover over it to see the tooltip.

  2. Add a data-price attribute to the editable paragraph, then imagine (or write, if you know a little JavaScript) how you would read it with element.dataset.price.

  3. Rewrite this paragraph so it no longer uses style, using a class and CSS instead:

    <p style="background: yellow; padding: 10px; border-radius: 6px;">
      Special offer!
    </p>
  4. Find one real website, right-click any element, choose Inspect, and look for at least one data-* attribute in its HTML. Note what you think it might be used for.

Recap

  • Global attributes (id, class, style, title, lang, data-*, hidden, tabindex, contenteditable, draggable) work on almost any element; element-specific attributes (href, src) only work on certain ones.
  • id names one unique element; class labels a reusable group.
  • style writes CSS directly on an element — prefer a class and a stylesheet whenever the style will repeat or needs maintaining.
  • lang on <html> helps screen readers and search engines; hidden removes an element completely.
  • tabindex adjusts keyboard tab order — use 0 and -1 more than large custom numbers.
  • data-* attributes let you attach your own custom information to any element for JavaScript to read later.