---
description: Mobile accessibility standards per WCAG 2.5.8 Target Size (Minimum), 2.4.1 Bypass Blocks, and 1.3.4 Orientation requirements
globs: *.vue, *.jsx, *.tsx, *.html, *.php, *.js, *.ts, *.css, *.scss, *.sass, *.less
alwaysApply: false
---

# Mobile Accessibility Best Practices

Ensures mobile interfaces follow WCAG compliance and provide proper accessibility for touch interactions, spacing, and orientation flexibility.

<rule>
name: mobile_accessibility_standards
description: Enforce mobile accessibility standards per WCAG requirements for touch targets, spacing, and orientation
filters:
  - type: file_extension
    pattern: "\\.(vue|jsx|tsx|html|liquid|php|js|ts|css|scss|sass|less)$"

actions:
  - type: enforce
    conditions:
      # Touch targets smaller than minimum recommended size
      - pattern: "(width|height):\\s*(?:1[0-9]|2[0-3])\\s*(?:px|rem|em|%)"
        pattern_negate: "(min-width|min-height|max-width|max-height)"
        message: "Touch targets should be at least 24x24px (Level AA) or 44x44px (Level AAA) for optimal accessibility. Use CSS padding to increase touch area without affecting visual design."

      # Touch targets with insufficient padding
      - pattern: "padding:\\s*(?:0|1|2|3|4)\\s*(?:px|rem|em)"
        pattern_negate: "(min-width|min-height|max-width|max-height)"
        message: "Consider increasing padding to create larger touch targets. Google recommends 48x48px with 8px spacing, Apple recommends 44x44px minimum."

      # Interactive elements without proper touch target sizing
      - pattern: "<(button|a|input|select|textarea)[^>]*>"
        pattern_negate: "(min-width|min-height|width|height|padding)"
        message: "Interactive elements should have sufficient touch target size. Use CSS min-width/min-height or padding to ensure accessibility compliance."

      # Touch targets too close together (less than 8px spacing)
      - pattern: "(margin|gap):\\s*(?:0|1|2|3|4|5|6|7)\\s*(?:px|rem|em)"
        pattern_negate: "(min-width|min-height|max-width|max-height)"
        message: "Touch targets should have at least 8px spacing between them to prevent accidental activation. Consider increasing margins or gaps."

      # Fixed orientation restrictions
      - pattern: "orientation:\\s*(portrait|landscape)"
        message: "Avoid restricting content orientation. Allow users to consume content in any orientation they prefer or require for their computing environment."

      # Viewport meta tag preventing orientation changes
      - pattern: "<meta[^>]*name=\"viewport\"[^>]*>"
        pattern_negate: "(width=device-width|initial-scale)"
        message: "Viewport meta tag should support responsive design and orientation flexibility. Avoid restrictions that prevent content reflow."

      # CSS that prevents orientation flexibility
      - pattern: "@media\\s*\\(orientation:\\s*(portrait|landscape)\\)"
        pattern_negate: "(min-width|max-width|flex-direction|grid-template)"
        message: "Orientation media queries should enhance layout, not restrict functionality. Ensure content remains accessible in both orientations."

      # Fixed positioning that may cause issues in different orientations
      - pattern: "position:\\s*fixed"
        pattern_negate: "(top|bottom|left|right|transform)"
        message: "Fixed positioning may cause accessibility issues in different orientations. Consider using relative positioning with responsive adjustments."

      # Touch targets without proper focus indicators
      - pattern: "<(button|a|input|select|textarea)[^>]*>"
        pattern_negate: "(:focus|:focus-visible|outline|box-shadow)"
        message: "Touch targets should have visible focus indicators for keyboard navigation accessibility."

      # Mobile-specific elements without touch-friendly sizing
      - pattern: "(?i)<(button|a|input|select|textarea)[^>]*class=\"[^\"]*(?:mobile|touch|small)[^\"]*\"[^>]*>"
        pattern_negate: "(min-width|min-height|width|height|padding)"
        message: "Mobile-specific interactive elements must have adequate touch target sizes for accessibility compliance."

      # Grid layouts without proper spacing
      - pattern: "display:\\s*grid"
        pattern_negate: "(gap|grid-gap|margin|padding)"
        message: "Grid layouts should include proper spacing between elements to prevent accidental touch activation."

      # Flexbox layouts without proper spacing
      - pattern: "display:\\s*flex"
        pattern_negate: "(gap|margin|padding|justify-content|align-items)"
        message: "Flexbox layouts should include proper spacing and alignment to ensure touch target accessibility."

  - type: suggest
    message: |
      **WCAG Mobile Accessibility Requirements:**

      **Touch Target Size (WCAG 2.5.8 Target Size Minimum):**
      - **Level AA (Required):** Minimum 24x24 pixels
      - **Recommended:** 44x44 pixels or larger for optimal usability
      - **Industry Standards:** Google (48x48px), Apple (44x44px)
      - **Spacing:** At least 8 pixels between touch targets

      **Touch Target Implementation:**

      **1. CSS Padding Approach:**
      ```css
      /* Good: Touch target meeting minimum requirements */
      .touch-button {
        min-width: 24px;  /* WCAG 2.5.8 AA minimum */
        min-height: 24px;
        padding: 12px 16px; /* Padding increases effective touch area */
        border: none;
        background: #0056b3;
        color: white;
        border-radius: 4px;
      }

      /* Better: Larger touch target for optimal usability */
      .touch-button-optimal {
        min-width: 44px;  /* Recommended size */
        min-height: 44px;
        padding: 12px 16px;
        border: none;
        background: #0056b3;
        color: white;
        border-radius: 4px;
      }

      /* Good: Icon button with sufficient touch area */
      .icon-button {
        width: 24px;
        height: 24px;
        padding: 12px; /* Total touch area: 48x48px */
        border: none;
        background: transparent;
      }
      ```

      **2. Minimum Dimensions:**
      ```css
      /* Good: Meets WCAG 2.5.8 AA minimum */
      .mobile-button {
        min-width: 24px;
        min-height: 24px;
        padding: 8px 16px;
        font-size: 16px; /* Prevents zoom on iOS */
      }

      /* Better: Recommended size for optimal usability */
      .mobile-button-optimal {
        min-width: 44px;
        min-height: 44px;
        padding: 8px 16px;
        font-size: 16px;
      }

      /* Good: Responsive touch targets */
      .responsive-button {
        min-width: clamp(24px, 8vw, 120px);
        min-height: clamp(24px, 8vh, 60px);
        padding: 12px;
      }
      ```

      **3. Touch Target Spacing:**
      ```css
      /* Good: Proper spacing between touch targets */
      .button-group {
        display: flex;
        gap: 12px; /* 8px minimum, 12px recommended */
        align-items: center;
      }

      /* Good: Grid with minimum touch target size */
      .touch-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(24px, 1fr));
        gap: 12px;
        padding: 16px;
      }

      /* Better: Grid with recommended touch target size */
      .touch-grid-optimal {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(44px, 1fr));
        gap: 12px;
        padding: 16px;
      }
      ```

      **Spacing Between Elements (WCAG 2.4.1 Bypass Blocks):**

      **1. White Space for Navigation:**
      ```css
      /* Good: Adequate spacing for motor impairment users */
      .navigation-links {
        display: flex;
        gap: 16px; /* Prevents accidental activation */
        padding: 20px;
        flex-wrap: wrap;
      }

      /* Good: Callout action spacing */
      .callout-actions {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: 20px; /* Generous spacing for accessibility */
        margin: 24px 0;
      }
      ```

      **2. Touch-Friendly Spacing:**
      ```css
      /* Good: Touch-friendly button spacing */
      .touch-buttons {
        display: flex;
        flex-direction: column;
        gap: 16px; /* Vertical spacing for thumb navigation */
      }

      /* Good: Horizontal button spacing */
      .horizontal-buttons {
        display: flex;
        gap: 12px;
        padding: 0 16px; /* Side padding for edge safety */
      }
      ```

      **Orientation Flexibility (WCAG 1.3.4 Orientation):**

      **1. Responsive Design Implementation:**
      ```css
      /* Good: Flexible layout that works in any orientation */
      .responsive-container {
        display: flex;
        flex-direction: row;
        gap: 16px;
        padding: 20px;
      }

      /* Responsive adjustments for different orientations */
      @media (orientation: portrait) {
        .responsive-container {
          flex-direction: column;
          gap: 12px;
        }
      }

      @media (orientation: landscape) {
        .responsive-container {
          flex-direction: row;
          gap: 20px;
        }
      }
      ```

      **2. Viewport Meta Tag:**
      ```html
      <!-- Good: Flexible viewport configuration -->
      <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes">
      ```

      **3. CSS Grid for Orientation Flexibility:**
      ```css
      /* Good: Grid that adapts to orientation */
      .adaptive-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
        gap: 20px;
        padding: 20px;
      }

      /* Orientation-specific adjustments */
      @media (orientation: portrait) {
        .adaptive-grid {
          grid-template-columns: 1fr;
          gap: 16px;
        }
      }
      ```

      **Mobile Accessibility Best Practices:**

      **1. Touch Target Guidelines:**
      - **Minimum size:** 24x24px per WCAG 2.5.8 AA
      - **Recommended size:** 44x44px or larger for optimal accessibility
      - **Spacing:** At least 8px between interactive elements
      - **Padding:** Use CSS padding to increase touch area
      - **Visual feedback:** Provide clear touch feedback
      - **Font size:** Minimum 16px to prevent zoom on iOS

      **2. Spacing and Layout:**
      - **White space:** Generous spacing prevents accidental activation
      - **Grid gaps:** Use CSS Grid gap property for consistent spacing
      - **Flexbox spacing:** Use gap property or margins for flex layouts
      - **Touch margins:** Add margins around touch targets for safety
      - **Visual separation:** Clear visual boundaries between interactive elements

      **3. Orientation Support:**
      - **Responsive design:** Content should reflow in any orientation
      - **Flexible layouts:** Use CSS Grid and Flexbox for adaptability
      - **No restrictions:** Avoid forcing specific orientations
      - **User choice:** Allow users to choose their preferred orientation
      - **Testing:** Test in both portrait and landscape modes

      **Implementation Examples:**

      **Touch-Friendly Button Component:**
      ```html
      <!-- Good: Accessible touch button meeting WCAG 2.5.8 AA -->
      <button class="touch-button"
              type="button"
              aria-label="Submit form">
        Submit
      </button>

      <style>
        .touch-button {
          min-width: 24px;  /* WCAG 2.5.8 AA minimum */
          min-height: 24px;
          padding: 12px 24px; /* Padding creates larger effective size */
          font-size: 16px;
          border: 2px solid #0056b3;
          background: #0056b3;
          color: white;
          border-radius: 6px;
          cursor: pointer;
          transition: all 0.2s ease;
        }

        .touch-button:hover,
        .touch-button:focus {
          background: #004085;
          border-color: #004085;
          outline: 3px solid #0056b3;
          outline-offset: 2px;
        }
      </style>
      ```

      **Responsive Touch Grid:**
      ```html
      <!-- Good: Responsive touch-friendly grid -->
      <div class="touch-grid">
        <button class="grid-button">Action 1</button>
        <button class="grid-button">Action 2</button>
        <button class="grid-button">Action 3</button>
        <button class="grid-button">Action 4</button>
      </div>

      <style>
        .touch-grid {
          display: grid;
          grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
          gap: 16px;
          padding: 20px;
        }

        .grid-button {
          min-width: 24px;  /* WCAG 2.5.8 AA minimum */
          min-height: 24px;
          padding: 16px; /* Padding creates larger effective size */
          font-size: 16px;
          border: 1px solid #ddd;
          background: white;
          border-radius: 4px;
          cursor: pointer;
        }

        /* Orientation-specific adjustments */
        @media (orientation: portrait) {
          .touch-grid {
            grid-template-columns: repeat(2, 1fr);
            gap: 12px;
          }
        }

        @media (orientation: landscape) {
          .touch-grid {
            grid-template-columns: repeat(4, 1fr);
            gap: 20px;
          }
        }
      </style>
      ```

      **Touch-Friendly Navigation:**
      ```html
      <!-- Good: Touch-friendly navigation menu -->
      <nav class="touch-navigation" role="navigation">
        <ul class="nav-list">
          <li><a href="/" class="nav-link">Home</a></li>
          <li><a href="/about" class="nav-link">About</a></li>
          <li><a href="/services" class="nav-link">Services</a></li>
          <li><a href="/contact" class="nav-link">Contact</a></li>
        </ul>
      </nav>

      <style>
        .touch-navigation {
          padding: 16px;
        }

        .nav-list {
          display: flex;
          flex-direction: column;
          gap: 16px;
          list-style: none;
          margin: 0;
          padding: 0;
        }

        .nav-link {
          display: block;
          min-height: 24px;  /* WCAG 2.5.8 AA minimum */
          padding: 12px 16px; /* Padding creates larger effective size */
          text-decoration: none;
          color: #333;
          background: #f8f9fa;
          border-radius: 6px;
          border: 2px solid transparent;
          transition: all 0.2s ease;
        }

        .nav-link:hover,
        .nav-link:focus {
          background: #e9ecef;
          border-color: #0056b3;
          outline: none;
        }

        /* Landscape orientation adjustment */
        @media (orientation: landscape) {
          .nav-list {
            flex-direction: row;
            gap: 20px;
          }
        }
      </style>
      ```

      **Testing and Validation:**

      **Touch Target Testing:**
      - Use browser dev tools to measure element dimensions
      - Test with touch devices to verify target sizes
      - Verify spacing between interactive elements
      - Check that padding creates adequate touch areas
      - Test with different screen densities

      **Orientation Testing:**
      - Test in both portrait and landscape modes
      - Verify content reflows properly
      - Check that functionality remains accessible
      - Test with different device orientations
      - Verify touch targets remain accessible

      **Accessibility Testing:**
      - Test with screen readers in different orientations
      - Verify keyboard navigation works in all orientations
      - Check that focus indicators remain visible
      - Test with motor impairment simulators
      - Validate touch target sizes meet WCAG requirements

      **Common Mistakes to Avoid:**
      - Touch targets smaller than 24x24px (WCAG 2.5.8 AA minimum)
      - Not using recommended 44x44px or larger sizes for optimal usability
      - Insufficient spacing between interactive elements (minimum 8px)
      - Fixed orientation restrictions
      - Viewport meta tags preventing orientation changes
      - CSS that doesn't adapt to different orientations
      - Touch targets without proper focus indicators
      - Grid layouts without adequate gaps
      - Flexbox layouts without proper spacing
      - Fixed positioning that causes orientation issues
      - Mobile elements without touch-friendly sizing

metadata:
  priority: high
  version: 1.0
</rule>
