Skip to main content

Button Component

Accessible, responsive button component with multiple variants and states

Live Demo

Loading demo...

Documentation

# Button Component

A versatile, accessible button component with multiple styles, sizes, and states. Built with pure HTML, CSS, and JavaScript following best practices for accessibility and user experience.

Features

  • Multiple Variants: Primary and secondary button styles
  • Size Options: Small, default, and large sizes
  • States: Hover, active, focus, disabled, and loading states
  • Accessibility: Full ARIA support and keyboard navigation
  • Responsive: Mobile-first design with responsive sizing
  • Interactive: Ripple effect animation on click
  • Dark Mode: Automatic dark mode support
  • Icon Support: Built-in icon button variants

Usage

Basic HTML Structure




Size Variants





Icon Buttons



Loading State


JavaScript API

Creating Buttons Programmatically

// Create a button using the static method
const button = ButtonComponent.createButton({
text: 'Click Me',
type: 'primary', // 'primary' or 'secondary'
size: 'default', // 'small', 'default', or 'large'
disabled: false,
loading: false,
icon: null, // HTML string for icon
onClick: () => console.log('Button clicked'),
ariaLabel: 'Custom action button'
});

// Append to container
document.body.appendChild(button);

Managing Loading State

const buttonComponent = new ButtonComponent();
const button = document.querySelector('.my-button');

// Set loading state
buttonComponent.setLoadingState(button, true);

// Remove loading state
setTimeout(() => {
buttonComponent.setLoadingState(button, false);
}, 3000);

CSS Variables

Customize the button appearance using CSS variables:

:root {
--btn-primary-bg: #3b82f6;
--btn-primary-bg-hover: #2563eb;
--btn-primary-bg-active: #1d4ed8;
--btn-primary-text: #ffffff;

--btn-secondary-bg: #e5e7eb;
--btn-secondary-bg-hover: #d1d5db;
--btn-secondary-bg-active: #9ca3af;
--btn-secondary-text: #374151;

--btn-disabled-bg: #e5e7eb;
--btn-disabled-text: #9ca3af;

--btn-focus-ring: rgba(59, 130, 246, 0.5);
--btn-radius: 0.375rem;
--btn-transition: all 0.2s ease;
}

Accessibility

  • ARIA Labels: All buttons include appropriate aria-label attributes
  • Keyboard Navigation: Full support for Enter and Space key activation
  • Focus Management: Clear focus indicators with customizable focus ring
  • Screen Reader Support: Proper announcements for button states
  • Disabled State: Uses both disabled attribute and aria-disabled
  • Loading State: Uses aria-busy for loading announcements

Browser Support

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 14+
  • Mobile browsers (iOS Safari, Chrome Mobile)

Best Practices

1. Always provide meaningful labels: Use aria-label for icon-only buttons
2. Indicate loading states: Use aria-busy for asynchronous operations
3. Maintain focus visibility: Never remove focus indicators
4. Use semantic HTML: Prefer

Async Action Button

async function handleAsyncAction(button) {
// Set loading state
button.classList.add('btn-loading');
button.setAttribute('aria-busy', 'true');
button.disabled = true;

try {
await performAction();
// Success handling
} catch (error) {
// Error handling
} finally {
// Remove loading state
button.classList.remove('btn-loading');
button.setAttribute('aria-busy', 'false');
button.disabled = false;
}
}

Button Group





Component Code

HTML Structure
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Button Component Demo</title>
    <link rel="stylesheet" href="component.css">
</head>
<body>
    <div class="demo-container">
        <h1>Button Component Examples</h1>

        <section class="button-group">
            <h2>Primary Buttons</h2>
            <button class="btn btn-primary" aria-label="Primary action">
                Primary Button
            </button>
            <button class="btn btn-primary" disabled aria-disabled="true">
                Disabled Primary
            </button>
        </section>

        <section class="button-group">
            <h2>Secondary Buttons</h2>
            <button class="btn btn-secondary" aria-label="Secondary action">
                Secondary Button
            </button>
            <button class="btn btn-secondary" disabled aria-disabled="true">
                Disabled Secondary
            </button>
        </section>

        <section class="button-group">
            <h2>Button Sizes</h2>
            <button class="btn btn-primary btn-small" aria-label="Small button">
                Small
            </button>
            <button class="btn btn-primary" aria-label="Default button">
                Default
            </button>
            <button class="btn btn-primary btn-large" aria-label="Large button">
                Large
            </button>
        </section>

        <section class="button-group">
            <h2>Icon Buttons</h2>
            <button class="btn btn-primary btn-icon" aria-label="Download file">
                <svg class="btn-icon-svg" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
                    <polyline points="7 10 12 15 17 10"/>
                    <line x1="12" y1="15" x2="12" y2="3"/>
                </svg>
                <span>Download</span>
            </button>
            <button class="btn btn-secondary btn-icon-only" aria-label="Settings">
                <svg class="btn-icon-svg" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <circle cx="12" cy="12" r="3"/>
                    <path d="M12 1v6m0 6v6m4.22-13.22l4.24 4.24M1.54 12h6m6 0h6"/>
                </svg>
            </button>
        </section>

        <section class="button-group">
            <h2>Loading State</h2>
            <button class="btn btn-primary btn-loading" aria-busy="true" aria-label="Loading, please wait">
                <span class="btn-spinner"></span>
                <span>Loading...</span>
            </button>
        </section>

        <section class="button-group">
            <h2>Full Width Button</h2>
            <button class="btn btn-primary btn-block" aria-label="Full width action">
                Full Width Button
            </button>
        </section>
    </div>

    <script src="component.js"></script>
</body>
</html>

Properties & Features

Tags

buttoninteractiveaccessibleresponsive

Last Updated

2025-10-30

Usage Tips

Installation

Copy the HTML, CSS, and JavaScript code above into your project files.

Customization

Modify CSS variables and classes to match your design system.

Accessibility

Ensure all interactive elements have proper ARIA labels and keyboard support.

Responsive Design

Test the component across different screen sizes and devices.