Buttons are how users do things on a website: submit a form, add an item to a basket, open a menu, play a video, close a pop-up. In HTML, a button is created with the <button> element, and choosing it correctly is one of the simplest ways to make a site work well with a keyboard, a screen reader and a touch screen.
A real <button> comes with a lot built in. It can receive keyboard focus, it can be pressed with Enter or Space, screen readers announce it as a button, and inside a form it submits the form automatically. A <div> styled to look like a button has none of this unless you rebuild it all with extra code.
In this lesson you'll learn the three button types, how to disable a button, how to give icon-only buttons an accessible label, and the most common question of all: should this be a button or a link? The short answer is that links go somewhere, buttons do something.
The button element and its types
<button type="button">Show details</button>
<button type="submit">Send message</button>
<button type="reset">Clear form</button>| Type | What it does |
|---|---|
submit | Submits the form it's in. This is the default inside a form. |
reset | Resets every field in the form to its starting value. |
button | Does nothing by itself; JavaScript decides what happens. |
Always write the type attribute. A button inside a form with no type is a submit button, which often surprises people when a "Show password" button suddenly sends the form.
Disabled buttons, labels and icons
disabledmakes a button unclickable and greys it out:<button disabled>Sold out</button>. Disabled buttons can't be focused, so explain nearby why an action isn't available.- The text inside the button is its label. Make it say what will happen: "Add to basket", not "Click here".
- Buttons can contain images or SVG icons. If a button shows only an icon, give it an accessible name with
aria-label="Close"so screen-reader users know what it does. - Buttons react to clicks through JavaScript, usually with
addEventListener('click', ...), covered in the JavaScript events lesson.
Button or link?
Use a link <a href> when... | Use a <button> when... |
|---|---|
| It takes the user to another page or URL | It changes something on the current page |
| It can be opened in a new tab | It submits a form |
| It's navigation, like "Read more" | It opens a menu, dialog or pop-up |
| The result has its own address | It plays, pauses, adds, deletes or toggles |
You can style a link to look like a button and a button to look like a link. Choose the element by what it does, then style it however your design needs.
HTML Buttons Syntax
Button syntax
<button type="button">Do something</button>
<button type="submit">Submit form</button>
<button type="reset">Reset form</button>
<button type="button" disabled>Not available</button>
<button type="button" aria-label="Close dialog">×</button>
<a href="/pricing" class="btn">A link styled as a button</a>HTML Buttons Summary
<button>creates a real, accessible button with keyboard support built in.- Set
type:submitsends a form,resetclears it,buttondoes nothing by itself. disabledmakes a button unusable; explain why nearby.- Icon-only buttons need an
aria-label. - Links go somewhere; buttons do something.
HTML Buttons Examples
Each example runs in the page. Edit the code and press Run to see what changes.
Button types in a form
<form>
<label>Name <input name="name" value="Ada"></label>
<button type="submit">Send</button>
<button type="reset">Reset</button>
<button type="button" onclick="alert('Saved as a draft')">Save draft</button>
</form>Line-by-line explanation
- Line 3Pressing Send submits the form.
- Line 4Reset puts the name back to "Ada", its starting value.
- Line 5A plain button runs only the JavaScript you attach to it.
Styled buttons and a disabled state
<style>
.btn {
padding: 10px 18px;
border: 0;
border-radius: 8px;
background: #15803d;
color: white;
font-size: 16px;
cursor: pointer;
}
.btn:hover { background: #166534; }
.btn:disabled { background: #9ca3af; cursor: not-allowed; }
</style>
<button type="button" class="btn">Add to basket</button>
<button type="button" class="btn" disabled>Out of stock</button>
<p><small>This size is out of stock. Choose another size above.</small></p>Line-by-line explanation
- Lines 2 to 10CSS turns the default grey button into a branded one.
- Line 11A darker green on hover gives feedback.
- Line 12
:disabledstyles the disabled state differently. - Lines 15 to 16The disabled button is greyed out, and the note explains why.
Icon buttons with accessible names
<style>
.icon-btn { width: 44px; height: 44px; border-radius: 50%; border: 1px solid #ccc; background: white; font-size: 20px; cursor: pointer; }
</style>
<button type="button" class="icon-btn" aria-label="Previous photo">‹</button>
<button type="button" class="icon-btn" aria-label="Next photo">›</button>
<button type="button" class="icon-btn" aria-label="Add to favourites">+</button>Line-by-line explanation
- Line 2Each button is 44 pixels square, a comfortable size to tap.
- Lines 4 to 6Only a symbol is visible, so
aria-labelgives each button a spoken name.
Common HTML Buttons Mistakes
A div pretending to be a button
<div class="btn" onclick="buy()">Buy now</div><button type="button" class="btn" onclick="buy()">Buy now</button>The div can't be reached with the Tab key or pressed with Enter, and screen readers don't announce it as a button.
Using a button for navigation
<button onclick="location.href='/pricing'">See pricing</button><a href="/pricing">See pricing</a>Links can be opened in a new tab, bookmarked and followed by search engines.
Forgetting the type inside a form
<form>
<input type="password" id="pw">
<button onclick="togglePassword()">Show</button>
</form><form>
<input type="password" id="pw">
<button type="button" onclick="togglePassword()">Show</button>
</form>Without type="button", clicking Show also submits the form.
HTML Buttons in Real Projects
Buttons everywhere
"Add to basket" on shops, "Play" on video players, menu toggles on mobile sites, "Accept" on cookie banners and "Send" on chat apps are all buttons. Design systems from companies like Google, Shopify and GitHub define button styles in CSS but always use the real <button> element underneath, so every variant stays accessible.
HTML Buttons Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Complete the button so it doesn't submit the form.
<button type="">Show more</button>
type="button" does nothing by itself.What is the default type of a button inside a form?
Which should be a link rather than a button?
An icon-only close button shows "×". How do you give it a name screen readers can say?
aria-label provides the accessible name.These "buttons" are divs and the real button submits the form by accident. Use proper buttons: "Subscribe" submits the form, and "Preview" must not.
<form>
<input type="email" placeholder="Email">
<div class="btn">Subscribe</div>
<button>Preview</button>
</form>- Subscribe is a submit button
- Preview is type button
- No div acts as a button
HTML Buttons Quiz
5 questions to check what you learned.
Which element should you use for a clickable action on the page?
- button
- div
- span
- p
What does type="reset" do?
- Reloads the page
- Deletes the form
- Restores every form field to its starting value
- Submits the form
What does the disabled attribute do?
- Makes the button unclickable and unfocusable
- Hides the button
- Changes its colour to red
- Removes it from the form
What's a good minimum size for a button on touch screens?
- 10 by 10 pixels
- 20 by 20 pixels
- About 44 by 44 pixels
- 200 by 200 pixels
Why is a styled div worse than a button?
- Divs can't be styled
- It loads slower
- It can't have click events
- It lacks keyboard focus, Enter and Space activation, and a button role for screen readers
HTML Buttons Challenge
A product action bar
Create:
- A button with the text "Add to basket" and
type="button" - A disabled button with the text "Buy now"
- An icon button containing + with
aria-label="Save to wishlist"
- Add to basket button with type button
- Buy now is disabled
- Wishlist button has an aria-label
disabled needs no value.