HTML pages are built from elements. An element describes a piece of content, such as a heading, paragraph, link, image, list, table, form field, or page section. Most elements are written with an opening tag, content, and a closing tag.
Attributes provide extra information about an element. They configure behavior, identify elements for CSS and JavaScript, improve accessibility, connect resources, and describe relationships. Attributes are written inside the opening tag.
A normal HTML element has three parts: an opening tag, content, and a closing tag. The tag name tells the browser what type of content the element represents.
<!-- Opening tag + content + closing tag -->
<h1>HTML Tutorial</h1>
<p>This is a paragraph of text.</p>
<strong>Important text</strong>
The browser reads these elements and builds a document tree called the DOM. CSS styles the DOM, and JavaScript can read or modify it.
Attributes are written in the opening tag. Most attributes use the format name="value". The attribute name describes what you are configuring, and the value provides the setting.
<a href="https://example.com" target="_blank">Visit Example</a>
<img src="profile.jpg" alt="Portrait of Asha" width="300">
<input type="email" name="email" required>
In the examples above, href, target, src, alt, width, type, name, and required are attributes.
| Concept | Purpose | Example |
|---|---|---|
| Element | Defines content or structure | <p>Hello</p> |
| Opening tag | Starts an element | <p> |
| Closing tag | Ends an element | </p> |
| Attribute | Adds information or configuration | class="intro" |
| Attribute value | The setting assigned to an attribute | "intro" |
Most HTML elements have opening and closing tags. Some elements are void elements, which means they cannot contain content and do not need a closing tag.
<!-- Normal elements -->
<h2>About Us</h2>
<p>We build learning resources for web developers.</p>
<button>Read More</button>
<!-- Void elements -->
<br>
<hr>
<img src="logo.png" alt="Company logo">
<input type="text" name="username">
<meta charset="UTF-8">
<link rel="stylesheet" href="styles.css">
| Common Void Element | Purpose |
|---|---|
<img> | Displays an image. |
<br> | Creates a line break. |
<hr> | Creates a thematic break. |
<input> | Creates a form input control. |
<meta> | Provides document metadata. |
<link> | Links external resources such as stylesheets. |
HTML elements can be nested inside other elements. The inner element should close before the outer element closes. Correct nesting creates a predictable document structure.
<!-- Correct nesting -->
<article>
<h2>HTML Basics</h2>
<p>Learn <strong>elements</strong> and <em>attributes</em>.</p>
</article>
<!-- Wrong: overlapping tags -->
<!-- <strong><em>text</strong></em> -->
Bad nesting can confuse browsers, validators, screen readers, and future developers reading your code.
HTML elements have default display behavior. Some elements naturally start on a new line, while others flow inside text. This behavior can be changed with CSS, but the default behavior matters when writing clean markup.
| Type | Behavior | Examples |
|---|---|---|
| Block elements | Start on a new line and usually take full width. | div, p, h1, section, ul |
| Inline elements | Flow inside text and take only needed width. | span, a, strong, em, code |
| Replaced / inline-block-like elements | Have intrinsic dimensions or special rendering. | img, input, button, select |
<div>This is a block element.</div>
<p>This paragraph contains an <a href="#">inline link</a> inside text.</p>
<span>Inline span</span>
<strong>Inline strong text</strong>
A semantic element clearly describes the meaning of its content. A non-semantic element is a generic container. Semantic HTML helps browsers, search engines, assistive technologies, and developers understand the page structure.
<!-- Less meaningful -->
<div class="header">Site Header</div>
<div class="nav">Navigation</div>
<div class="article">Article content</div>
<!-- More semantic -->
<header>Site Header</header>
<nav>Navigation</nav>
<article>Article content</article>
| Element | Purpose | Example |
|---|---|---|
<h1> to <h6> | Headings | <h1>Page Title</h1> |
<p> | Paragraph | <p>Text</p> |
<a> | Link | <a href="/">Home</a> |
<img> | Image | <img src="cat.jpg" alt="Cat"> |
<ul>, <ol>, <li> | Lists | <li>Item</li> |
<table> | Tabular data | <table>...</table> |
<form> | User input | <form>...</form> |
<section> | Thematic page section | <section>...</section> |
<article> | Self-contained content | <article>...</article> |
<button> | Clickable button | <button>Save</button> |
Global attributes can be used on almost any HTML element. They are useful for styling, scripting, accessibility, language, interaction, and metadata.
| Attribute | Purpose | Example |
|---|---|---|
id | Unique identifier for one element. | id="main-title" |
class | Reusable CSS class names. | class="tl-card featured" |
style | Inline CSS styles. | style="color: red;" |
title | Advisory text, often shown as a tooltip. | title="More details" |
lang | Language of the content. | lang="en" |
hidden | Hides an element. | hidden |
tabindex | Controls keyboard focus behavior. | tabindex="0" |
data-* | Stores custom data. | data-user-id="42" |
aria-* | Adds accessibility information. | aria-label="Close" |
Some attributes only make sense on certain elements. For example, href belongs on links, src belongs on media elements, and type configures form controls or scripts.
<a href="/contact" target="_blank" rel="noopener">Contact Us</a>
<img src="banner.jpg" alt="Students learning HTML" loading="lazy">
<input type="email" name="email" placeholder="you@example.com" required>
<button type="submit">Create Account</button>
<video src="lesson.mp4" controls width="640"></video>
Boolean attributes are true when they are present and false when they are absent. They do not need a value. Writing disabled, disabled="", or disabled="disabled" all means the attribute is present.
<input type="checkbox" checked>
<input type="email" required>
<button disabled>Submit</button>
<video controls muted></video>
<details open>
<summary>Read more</summary>
<p>Extra content is visible by default.</p>
</details>
id and class are two of the most used HTML attributes. Both are used by CSS and JavaScript, but they have different purposes.
| Attribute | Rule | Use Case |
|---|---|---|
id | Should be unique on the page. | Fragment links, unique JS lookup, unique landmark. |
class | Can be reused across many elements. | Reusable styling and grouping. |
<h1 id="page-title">HTML Elements and Attributes</h1>
<p class="intro highlight">This paragraph has two classes.</p>
<p class="intro">This paragraph reuses the intro class.</p>
<a href="#page-title">Back to top</a>
data-* attributes store custom data on HTML elements. They are useful when JavaScript needs extra information from the markup without inventing invalid attributes.
<button
class="buy-button"
data-product-id="42"
data-price="499">
Buy Now
</button>
const button = document.querySelector('.buy-button');
console.log(button.dataset.productId); // "42"
console.log(button.dataset.price); // "499"
ARIA attributes can improve accessibility when native HTML alone cannot express enough information. Use semantic HTML first, then add ARIA only when it is needed.
<button type="button" aria-label="Close dialog">
×
</button>
<div role="alert" aria-live="polite">
Your profile was saved successfully.
</div>
Do not use ARIA to replace good HTML. For example, use <button> for a button instead of <div role="button"> whenever possible.
HTML supports event attributes such as onclick, onchange, and onsubmit, but modern best practice is to keep JavaScript in separate files and attach listeners with JavaScript.
<!-- Works, but mixes HTML and JavaScript -->
<button onclick="alert('Saved')">Save</button>
<button id="save-button" type="button">Save</button>
document
.querySelector('#save-button')
.addEventListener('click', () => {
alert('Saved');
});
HTML tag names and attribute names are not case-sensitive in normal HTML documents, but lowercase is the standard convention. Attribute values should normally be quoted, especially when they contain spaces, special characters, or URLs.
<!-- Recommended -->
<input type="text" name="full-name" placeholder="Your full name">
<!-- Avoid inconsistent casing and missing quotes -->
<INPUT TYPE=text NAME=full-name>
Attributes should be used on elements that support them. Browsers may ignore unknown or invalid attributes, but invalid markup makes your page harder to maintain and may break accessibility or validation.
<!-- Correct: href belongs on anchor -->
<a href="/about">About</a>
<!-- Correct: src and alt belong on image -->
<img src="team.jpg" alt="Our team">
<!-- Avoid: href does not make a div a real link -->
<div href="/about">About</div>
The following example combines semantic elements, global attributes, element-specific attributes, boolean attributes, data attributes, and accessibility attributes.
<article class="product-card" data-product-id="101">
<img src="keyboard.jpg"
alt="Mechanical keyboard with backlit keys"
width="400"
loading="lazy">
<h2 id="product-title">Mechanical Keyboard</h2>
<p>Compact keyboard for developers and writers.</p>
<button type="button"
class="buy-button"
aria-describedby="product-title">
Add to Cart
</button>
</article>
HTML elements and attributes are the foundation of every web page. Elements define what content is, while attributes describe or configure that content. When you choose meaningful elements and write clear attributes, your pages become easier to style, script, maintain, index, and use with assistive technology.
The best way to master HTML is to think in terms of meaning first. Use headings for headings, links for navigation, buttons for actions, images with useful alt text, forms with labels, and semantic sections for page structure. Attributes should support that structure, not hide poor markup.
<div href="/about">About</div>
<a href="/about">About</a>
<img src="logo.png">
<img src="logo.png" alt="Company logo">
<h1 id="title"></h1><p id="title"></p>
<h1 id="title"></h1><p class="title-note"></p>
<p><div>Wrong nesting</div></p>
<div><p>Correct nesting</p></div>
id, class, title, lang, and data-* can be used widely.
id for one unique element and class for reusable styling or grouping.
Explore 500+ free tutorials across 20+ languages and frameworks.