👆 Interaction Principles

Interaction design must accommodate users with motor difficulties, ADHD, autism, and other neurodivergent conditions. Clear feedback, predictable behavior, and accessible targets are essential for inclusive design.

Design Guidelines

Principle Description Recommendation
Clear Feedback Provide immediate response Visual or auditory feedback for all actions
Predictable Behavior Meet user expectations Avoid unexpected navigation or changes
Adequate Target Size Support motor difficulties Minimum 44x44 pixels for click/touch targets
Keyboard Accessibility Enable alternative input All functionality accessible via keyboard
Flexible Timing Accommodate processing differences Avoid strict time limits or provide extensions
Error Prevention Support recovery Clear error messages with simple solutions
Progress Indication Show current position Display progress in multi-step processes

CSS Implementation

/* Adequate click targets */
.interactive-button {
  min-width: 44px;
  min-height: 44px;
  padding: 0.75rem 1.5rem;
  border-radius: 0.5rem;
  cursor: pointer;
}

/* Clear focus states */
.interactive-button:focus-visible {
  outline: 3px solid #005fcc;
  outline-offset: 2px;
}

/* Hover feedback */
.interactive-button:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* Active state */
.interactive-button:active {
  transform: translateY(0);
}

/* Skip to content link */
.skip-link {
  position: absolute;
  top: -100px;
  left: 0;
  background: #005fcc;
  color: white;
  padding: 1rem;
  z-index: 100;
  transition: top 0.3s;
}

.skip-link:focus {
  top: 0;
}

Tailwind CSS Classes

<button className="btn btn-primary min-h-[44px] min-w-[44px] px-6 py-3
  focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-primary
  hover:shadow-lg hover:-translate-y-0.5
  active:translate-y-0
  transition-all duration-150">
  Click Me
</button>

<a href="#main-content"
  className="sr-only focus:not-sr-only focus:absolute focus:top-0 focus:left-0
    focus:z-50 focus:bg-primary focus:text-primary-content
    focus:px-4 focus:py-2">
  Skip to main content
</a>

React Component

interface AccessibleButtonProps {
  children: React.ReactNode;
  onClick?: () => void;
  disabled?: boolean;
  loading?: boolean;
  variant?: "primary" | "secondary" | "outline";
  size?: "sm" | "md" | "lg";
}

export function AccessibleButton({
  children,
  onClick,
  disabled = false,
  loading = false,
  variant = "primary",
  size = "md",
}: AccessibleButtonProps) {
  const variantClasses = {
    primary: "btn-primary",
    secondary: "btn-secondary",
    outline: "btn-outline",
  };

  const sizeClasses = {
    sm: "btn-sm",
    md: "",
    lg: "btn-lg",
  };

  return (
    <button
      className={`
        btn ${variantClasses[variant]} ${sizeClasses[size]}
        min-h-[44px] min-w-[44px]
        focus-visible:ring-2 focus-visible:ring-offset-2
        transition-all duration-150
      `}
      onClick={onClick}
      disabled={disabled || loading}
      aria-busy={loading}
    >
      {loading && <Loader2 className="w-4 h-4 animate-spin mr-2" />}
      {children}
    </button>
  );
}

Progress Indicator Component

interface ProgressIndicatorProps {
  currentStep: number;
  totalSteps: number;
  labels?: string[];
}

export function ProgressIndicator({ currentStep, totalSteps, labels }: ProgressIndicatorProps) {
  return (
    <nav aria-label="Progress" className="mb-8">
      <ol className="flex items-center gap-2">
        {Array.from({ length: totalSteps }, (_, i) => {
          const step = i + 1;
          const isCurrent = step === currentStep;
          const isComplete = step < currentStep;

          return (
            <li key={step} className="flex items-center">
              <span
                className={`
                  w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium
                  ${isComplete ? 'bg-success text-success-content' : ''}
                  ${isCurrent ? 'bg-primary text-primary-content ring-2 ring-primary ring-offset-2' : ''}
                  ${!isComplete && !isCurrent ? 'bg-base-300 text-base-content' : ''}
                `}
                aria-current={isCurrent ? 'step' : undefined}
              >
                {isComplete ? '✓' : step}
              </span>
              {labels && labels[i] && (
                <span className="ml-2 text-sm">{labels[i]}</span>
              )}
              {step < totalSteps && (
                <div className="w-8 h-0.5 bg-base-300 mx-2" />
              )}
            </li>
          );
        })}
      </ol>
    </nav>
  );
}

Checklist

  • All interactions provide clear feedback
  • Behavior is predictable and expected
  • Click/touch targets are at least 44x44 pixels
  • All functionality is keyboard accessible
  • No strict time limits or extension available
  • Error messages are clear and actionable
  • Progress is shown in multi-step processes
  • Focus states are clearly visible

Last updated: 2026-10-20

Menu
Loading