CSS Advanced
CSS Buttons
Well-styled buttons make an interface feel polished and clickable. This guide builds attractive CSS buttons from scratch: base styles, hover and active feedback, colour variants, sizes, and disabled states, all with runnable examples.
Styling a Button
Native buttons carry browser default styles that vary by platform. To take control, reset the essentials — background, border, padding, font and cursor — then build up your own look. A pointer cursor and comfortable padding are the two changes that most improve a button's feel.
.btn {
padding: 10px 18px;
border: none;
border-radius: 8px;
background: #4f46e5;
color: #fff;
font: 600 15px sans-serif;
cursor: pointer;
}Hover and Active Feedback
Interactive states tell the user the button is responding. :hover darkens on mouse-over, :active gives a pressed feel, and a transition makes the change smooth rather than abrupt.
<!DOCTYPE html>
<html>
<head>
<style>
.btn {
padding: 12px 22px;
border: none;
border-radius: 8px;
background: #4f46e5;
color: #fff;
font: 600 15px sans-serif;
cursor: pointer;
transition: background .2s, transform .05s;
}
.btn:hover { background: #4338ca; }
.btn:active { transform: translateY(1px); }
</style>
</head>
<body>
<button class="btn">Click me</button>
</body>
</html>Button Variants
A design system usually offers several button styles for different levels of emphasis. Below are solid, outline, ghost and danger variants sharing one base class.
<!DOCTYPE html>
<html>
<head>
<style>
.btn {
padding: 10px 18px;
border-radius: 8px;
font: 600 14px sans-serif;
cursor: pointer;
border: 2px solid transparent;
transition: all .2s;
}
.solid { background: #16a34a; color: #fff; }
.solid:hover { background: #15803d; }
.outline { background: #fff; color: #16a34a; border-color: #16a34a; }
.outline:hover { background: #16a34a; color: #fff; }
.ghost { background: transparent; color: #16a34a; }
.ghost:hover { background: #dcfce7; }
.danger { background: #dc2626; color: #fff; }
.danger:hover { background: #b91c1c; }
</style>
</head>
<body>
<button class="btn solid">Solid</button>
<button class="btn outline">Outline</button>
<button class="btn ghost">Ghost</button>
<button class="btn danger">Danger</button>
</body>
</html>Sizes, Block and Disabled
| Modifier | Effect |
|---|---|
| Small | Reduce padding and font-size |
| Large | Increase padding and font-size |
| Block | width: 100% to fill its container |
| :disabled | Dim, remove pointer, block interaction |
<!DOCTYPE html>
<html>
<head>
<style>
.btn { padding: 12px; border: none; border-radius: 8px; background: #0ea5e9; color: #fff; font: 600 15px sans-serif; cursor: pointer; }
.block { display: block; width: 100%; margin-bottom: 10px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
</style>
</head>
<body>
<button class="btn block">Full-width button</button>
<button class="btn" disabled>Disabled</button>
</body>
</html>Always add a visible :focus-visible outline so keyboard users can see which button is selected. Removing focus outlines without a replacement is an accessibility failure.
cursor: pointer is a visual hint, not a substitute for using a real <button> element. Semantic buttons are keyboard-focusable and announced correctly by screen readers.
Key points
- Reset background, border and padding, then add your own look and cursor: pointer.
- Use :hover and :active with a transition for responsive feedback.
- Share a base class and layer variant classes (solid, outline, ghost, danger).
- Use display: block; width: 100% for full-width buttons and :disabled to dim.
- Keep a visible focus indicator for keyboard accessibility.
