Skip to content
GreenSnippets

Accessible button styles with states

A base button with hover, active, disabled and focus styles that meets minimum target size.

CSS
.btn {
  --btn-bg: #16a34a;
  --btn-fg: #ffffff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  padding: 0.5rem 1.25rem;
  border: 0;
  border-radius: 0.5rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-weight: 600;
  cursor: pointer;
  transition: filter 0.15s ease, transform 0.05s ease;
}

.btn:hover { filter: brightness(0.95); }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 3px solid #1d4ed8; outline-offset: 2px; }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }

.btn--danger { --btn-bg: #b91c1c; }

Example / expected output

Output
<!-- <button class="btn">Save</button> <button class="btn btn--danger">Delete</button> -->

How it works

Buttons should be at least 44 by 44 CSS pixels on touch devices, have visible focus, and show a clear disabled state. Custom properties make variants (secondary, danger) one-line overrides. cursor: not-allowed and reduced opacity communicate disabled; keep the contrast of the label readable.

This snippet has been reviewed but was not executed by an automated test. Test it in your own environment before relying on it.