mobile-ux-improver

📁 ramunasnognys/workflow-template 📅 6 days ago
1
总安装量
1
周安装量
#53207
全站排名
安装命令
npx skills add https://github.com/ramunasnognys/workflow-template --skill mobile-ux-improver

Agent 安装分布

amp 1
opencode 1
kimi-cli 1
github-copilot 1
gemini-cli 1

Skill 文档

Mobile UX Improver

Purpose

Enforce mobile-first UX best practices to ensure exceptional mobile web experiences. This skill prevents common mobile UX mistakes and guides implementation of touch-friendly, responsive, performant interfaces.

When to Use

Auto-triggers when:

  • Editing mobile UI components
  • Working with responsive layouts
  • Implementing touch interactions
  • Optimizing mobile performance
  • Using Tailwind responsive classes (sm:, md:, lg:)
  • Handling mobile gestures

Manual trigger when:

  • Reviewing mobile UX
  • Implementing new mobile features
  • Debugging mobile-specific issues

Quick Reference

Touch Targets

Minimum Sizes:

  • ✅ 48px × 48px (recommended)
  • ⚠️ 44px × 44px (absolute minimum)
  • ❌ < 44px (too small, avoid)

Spacing:

  • 8px minimum between interactive elements
  • 12px+ recommended for frequently used controls

Responsive Breakpoints (Tailwind)

// Mobile-first approach
<div className="w-full md:w-1/2 lg:w-1/3">

// Breakpoints
sm: 640px   // Small tablets
md: 768px   // Tablets
lg: 1024px  // Small desktops
xl: 1280px  // Large desktops
2xl: 1536px // Extra large

Performance Targets

  • First Contentful Paint: < 1.8s
  • Time to Interactive: < 3.8s
  • Cumulative Layout Shift: < 0.1
  • Largest Contentful Paint: < 2.5s

Core Principles

1. Mobile-First Design

Always start with mobile layout:

// ✅ CORRECT - Mobile first, then desktop
<button className="w-full px-4 py-3 md:w-auto md:px-6">
  Tap Me
</button>

// ❌ WRONG - Desktop first
<button className="w-auto px-6 sm:w-full sm:px-4">
  Tap Me
</button>

Why: Mobile constraints force better UX decisions, easier to scale up than down.

2. Touch-Friendly Targets

Minimum interactive area:

// ✅ CORRECT - 48px touch target
<button className="min-h-[48px] min-w-[48px] p-3">
  <Icon className="w-6 h-6" />
</button>

// ❌ WRONG - Too small
<button className="p-1">
  <Icon className="w-4 h-4" />
</button>

Spacing between targets:

// ✅ CORRECT - Adequate spacing
<div className="flex gap-3">
  <button className="p-3">A</button>
  <button className="p-3">B</button>
</div>

// ❌ WRONG - Targets too close
<div className="flex gap-1">
  <button className="p-1">A</button>
  <button className="p-1">B</button>
</div>

3. Responsive Typography

Use relative units for mobile:

// ✅ CORRECT - Scales with viewport
<h1 className="text-2xl md:text-4xl lg:text-5xl">
  Heading
</h1>

// ✅ CORRECT - Clamp for fluid scaling
<p className="text-base leading-relaxed">
  Body text
</p>

// ⚠️ AVOID - Fixed pixel sizes
<h1 style={{ fontSize: '60px' }}>
  Heading
</h1>

4. Viewport Configuration

Required meta tag:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5">

Why maximum-scale=5: Allows zoom for accessibility while preventing excessive zoom accidents.


Touch Targets & Spacing

Target Sizing Chart

Element Type Minimum Size Recommended Size Spacing
Primary Button 44px 48px 12px
Icon Button 44px 48px 8px
Link in Text 44px height 48px height 8px vertical
Checkbox/Radio 44px 48px 12px
Slider Thumb 44px 48px N/A

Common Patterns

Primary Action Button:

<button className="w-full px-6 py-4 text-lg font-semibold rounded-lg bg-brand-blue text-white hover:bg-blue-600 active:bg-blue-700 transition-colors min-h-[48px]">
  Continue
</button>

Icon Button:

<button
  className="p-3 rounded-full hover:bg-gray-100 active:bg-gray-200 transition-colors min-h-[48px] min-w-[48px] flex items-center justify-center"
  aria-label="Close"
>
  <XIcon className="w-6 h-6" />
</button>

List of Links:

<nav className="space-y-2">
  {links.map(link => (
    <a
      key={link.id}
      href={link.url}
      className="block px-4 py-3 text-base hover:bg-gray-50 active:bg-gray-100 rounded-lg min-h-[48px]"
    >
      {link.label}
    </a>
  ))}
</nav>

📖 Complete Guide: resources/touch-targets-guide.md


Responsive Design

Mobile-First Approach

Start with mobile, enhance for larger screens:

// Layout structure
<div className="
  flex flex-col gap-4          /* Mobile: stack vertically */
  md:flex-row md:gap-6         /* Tablet: horizontal */
  lg:gap-8                     /* Desktop: more spacing */
">
  <aside className="w-full md:w-64 lg:w-80">
    Sidebar
  </aside>
  <main className="flex-1">
    Content
  </main>
</div>

Container Patterns

Responsive containers:

// Full-width on mobile, constrained on desktop
<div className="
  w-full px-4                  /* Mobile: full width, padding */
  md:px-6                      /* Tablet: more padding */
  lg:max-w-7xl lg:mx-auto lg:px-8  /* Desktop: centered, max width */
">
  {children}
</div>

Grid Layouts

Responsive grid:

<div className="
  grid grid-cols-1 gap-4       /* Mobile: 1 column */
  sm:grid-cols-2 sm:gap-6      /* Small tablet: 2 columns */
  lg:grid-cols-3 lg:gap-8      /* Desktop: 3 columns */
">
  {items.map(item => (
    <Card key={item.id} {...item} />
  ))}
</div>

Hiding/Showing Elements

Conditional visibility:

// Mobile menu vs desktop nav
<>
  {/* Mobile menu button */}
  <button className="md:hidden p-3">
    <MenuIcon />
  </button>

  {/* Desktop navigation */}
  <nav className="hidden md:flex gap-6">
    <NavLink href="/about">About</NavLink>
    <NavLink href="/contact">Contact</NavLink>
  </nav>
</>

📖 Complete Guide: resources/responsive-patterns.md


Mobile Gestures

Horizontal Scrolling

Swipeable container:

<div className="
  flex gap-4 overflow-x-auto snap-x snap-mandatory
  scrollbar-hide              /* Hide scrollbar on mobile */
  pb-4                        /* Padding for scroll indicator */
  -mx-4 px-4                  /* Edge-to-edge on mobile */
  md:mx-0 md:px-0             /* Contained on desktop */
">
  {items.map(item => (
    <div
      key={item.id}
      className="flex-shrink-0 w-72 snap-center"
    >
      <Card {...item} />
    </div>
  ))}
</div>

Pull-to-Refresh

Implement with overscroll-behavior:

<main className="
  overscroll-contain          /* Prevent chain scrolling */
  overflow-y-auto
  h-screen
">
  {content}
</main>

Scroll Behavior

Smooth scrolling:

// Global CSS or Tailwind
<html className="scroll-smooth">

// Component-level
<div className="overflow-y-auto scroll-smooth">
  {longContent}
</div>

📖 Complete Guide: resources/mobile-gestures.md


Performance Optimization

Image Optimization

Responsive images:

<img
  src="/hero-mobile.jpg"
  srcSet="
    /hero-mobile.jpg 640w,
    /hero-tablet.jpg 1024w,
    /hero-desktop.jpg 1920w
  "
  sizes="
    (max-width: 640px) 100vw,
    (max-width: 1024px) 50vw,
    33vw
  "
  alt="Hero image"
  loading="lazy"
  className="w-full h-auto"
/>

Lazy Loading

Component lazy loading:

import { lazy, Suspense } from 'react';

const HeavyComponent = lazy(() => import('./HeavyComponent'));

function Page() {
  return (
    <Suspense fallback={<LoadingSpinner />}>
      <HeavyComponent />
    </Suspense>
  );
}

Font Loading

Optimize web fonts:

<link
  rel="preload"
  href="/fonts/custom-font.woff2"
  as="font"
  type="font/woff2"
  crossorigin
/>

📖 Complete Guide: resources/mobile-performance.md


Accessibility for Mobile

Screen Reader Support

Proper labeling:

<button
  aria-label="Close dialog"
  className="p-3"
>
  <XIcon className="w-6 h-6" />
</button>

Focus Management

Keyboard + touch support:

<button className="
  p-3 rounded-lg
  focus:outline-none focus:ring-2 focus:ring-brand-blue focus:ring-offset-2
  active:bg-gray-100
">
  Action
</button>

Color Contrast

WCAG AA minimum:

  • Normal text: 4.5:1
  • Large text: 3:1
  • Interactive elements: 3:1

Common Anti-Patterns to Avoid

❌ Don’t: Hover-Only Interactions

// ❌ WRONG - No hover on touch devices
<div className="hover:visible">
  Hidden content
</div>

// ✅ CORRECT - Click/tap to reveal
<button onClick={() => setVisible(true)}>
  Show content
</button>

❌ Don’t: Fixed Positioning That Blocks Content

// ❌ WRONG - Header blocks content
<header className="fixed top-0 w-full h-16 bg-white">

<main className="pt-0">  /* Content hidden behind header */

// ✅ CORRECT - Account for header
<header className="fixed top-0 w-full h-16 bg-white z-10">

<main className="pt-16">  /* Content starts below header */

❌ Don’t: Tiny Text

// ❌ WRONG - Unreadable on mobile
<p className="text-xs">
  Important information
</p>

// ✅ CORRECT - Readable base size
<p className="text-base md:text-sm">
  Important information
</p>

❌ Don’t: Disable Zoom

<!-- ❌ WRONG - Prevents accessibility -->
<meta name="viewport" content="user-scalable=no, maximum-scale=1">

<!-- ✅ CORRECT - Allow zoom for accessibility -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5">

Example: Mobile-Optimized Component

Complete touch-friendly card:

import React from 'react';

interface ProductCardProps {
  title: string;
  price: number;
  image: string;
  onAddToCart: () => void;
}

export const ProductCard: React.FC<ProductCardProps> = ({
  title,
  price,
  image,
  onAddToCart
}) => {
  return (
    <div className="
      bg-white rounded-lg shadow-sm overflow-hidden
      hover:shadow-md transition-shadow
      w-full                          /* Mobile: full width */
      sm:w-64                         /* Tablet: fixed width */
    ">
      <img
        src={image}
        alt={title}
        loading="lazy"
        className="w-full h-48 object-cover"
      />

      <div className="p-4">
        <h3 className="text-lg font-semibold mb-2 line-clamp-2">
          {title}
        </h3>

        <p className="text-2xl font-bold text-brand-blue mb-4">
          ${price.toFixed(2)}
        </p>

        <button
          onClick={onAddToCart}
          className="
            w-full px-6 py-3 rounded-lg
            bg-brand-blue text-white font-semibold
            hover:bg-blue-600 active:bg-blue-700
            transition-colors
            min-h-[48px]              /* Touch-friendly height */
            focus:outline-none focus:ring-2 focus:ring-brand-blue focus:ring-offset-2
          "
          aria-label={`Add ${title} to cart`}
        >
          Add to Cart
        </button>
      </div>
    </div>
  );
};

export default ProductCard;

Testing Mobile UX

Manual Testing Checklist

  • Test on real mobile devices (iOS, Android)
  • Verify touch targets are 44px+ minimum
  • Check text is readable without zoom
  • Test horizontal scrolling with touch
  • Verify forms work with mobile keyboards
  • Test landscape + portrait orientations
  • Check performance on slow connections
  • Verify hover states have touch alternatives
  • Test with screen reader (VoiceOver, TalkBack)
  • Check color contrast meets WCAG AA

Browser DevTools

Chrome DevTools Mobile Emulation:

  1. Open DevTools (F12)
  2. Toggle device toolbar (Cmd+Shift+M / Ctrl+Shift+M)
  3. Select device or custom dimensions
  4. Enable touch emulation
  5. Test throttling (3G, 4G networks)

Reference Existing Components

Good examples in your codebase:

  • FilterPill.tsx – Touch-friendly pill buttons with proper spacing
  • TeamCard.tsx – Responsive card layout with touch interactions
  • Fab.tsx – Floating action button with proper touch target

Related Skills

  • frontend-dev-guidelines: React/TypeScript best practices
  • seo-specialist: Mobile SEO optimization
  • error-tracking: Performance monitoring

Skill Status: Active guardrail – Enforces mobile UX quality Line Count: < 500 (following 500-line rule) ✅ Progressive Disclosure: Reference files for detailed guides âœ