11 KiB
11 KiB
Common Rules for Professional UI + Pre-Delivery Checklist
Load this file before final delivery of native/mobile app UI (iOS/Android/React Native/Flutter), or when the user reports the UI "doesn't look professional" and the cause isn't obvious from the priority table in SKILL.md.
Scope notice: everything below targets native/mobile app UI. For web/desktop interaction patterns, use references/quick-reference.md (stack-agnostic) instead — these tables assume touch targets, safe areas, and platform gesture conventions that don't apply 1:1 to desktop web.
These are frequently overlooked issues that make UI look unprofessional.
Icons & Visual Elements
| Rule | Standard | Avoid | Why It Matters |
|---|---|---|---|
| No Emoji as Structural Icons | Use vector-based icons (e.g., Lucide, react-native-vector-icons, @expo/vector-icons). | Using emojis (🎨 🚀 ⚙️) for navigation, settings, or system controls. | Emojis are font-dependent, inconsistent across platforms, and cannot be controlled via design tokens. |
| Vector-Only Assets | Use SVG or platform vector icons that scale cleanly and support theming. | Raster PNG icons that blur or pixelate. | Ensures scalability, crisp rendering, and dark/light mode adaptability. |
| Contextual Semantics | Choose semantics from use, not glyph: hide decorative icons beside visible text from the accessibility tree; give meaningful standalone icons a text alternative; give icon controls an accessible name and expose selected/pressed/expanded state when applicable. | Treating one icon name as permanently decorative, meaningful, or interactive. | The same glyph can serve different purposes in different components. |
| Stable Interaction States | Use color, opacity, or elevation transitions for press states without changing layout bounds. | Layout-shifting transforms that move surrounding content or trigger visual jitter. | Prevents unstable interactions and preserves smooth motion/perceived quality on mobile. |
| Correct Brand Logos | Use official brand assets and follow their usage guidelines (spacing, color, clear space). | Guessing logo paths, recoloring unofficially, or modifying proportions. | Prevents brand misuse and ensures legal/platform compliance. |
| Consistent Icon Sizing | Define icon sizes as design tokens (e.g., icon-sm, icon-md = 24pt, icon-lg). | Mixing arbitrary values like 20pt / 24pt / 28pt randomly. | Maintains rhythm and visual hierarchy across the interface. |
| Stroke Consistency | Use a consistent stroke width within the same visual layer (e.g., 1.5px or 2px). | Mixing thick and thin stroke styles arbitrarily. | Inconsistent strokes reduce perceived polish and cohesion. |
| Filled vs Outline Discipline | Use one icon style per hierarchy level. | Mixing filled and outline icons at the same hierarchy level. | Maintains semantic clarity and stylistic coherence. |
| Touch Target Minimum | Use at least 44pt on iOS and 48dp on Android; expand the hit area when the visual icon is smaller. | Small icons without expanded tap area, or one unit reused across platforms. | Matches platform-specific target guidance. |
| Icon Alignment | Align icons to text baseline and maintain consistent padding. | Misaligned icons or inconsistent spacing around them. | Prevents subtle visual imbalance that reduces perceived quality. |
| Icon Contrast | Meaningful icons and control boundaries need at least 3:1 against adjacent colors; decorative icons must not carry information. | Low-contrast icons that carry meaning or state. | Applies the non-text contrast role instead of a text-size rule. |
Interaction (App)
| Rule | Do | Don't |
|---|---|---|
| Tap feedback | Provide clear pressed feedback (ripple/opacity/elevation) within 80-150ms | No visual response on tap |
| Animation timing | Use shared tokens chosen for distance, complexity, platform, and user context | One duration/easing copied to every transition |
| Accessibility focus | Ensure screen reader focus order matches visual order and labels are descriptive | Unlabeled controls or confusing focus traversal |
| Disabled state clarity | Use disabled semantics (disabled/native disabled props), reduced emphasis, and no tap action |
Controls that look tappable but do nothing |
| Touch target minimum | Keep tap areas >=44x44pt (iOS) or >=48x48dp (Android), expand hit area when icon is smaller | Tiny tap targets or icon-only hit areas without padding |
| Gesture conflict prevention | Keep one primary gesture per region and avoid nested tap/drag conflicts | Overlapping gestures causing accidental actions |
| Semantic native controls | Prefer native interactive primitives (Button, Pressable, platform equivalents) with proper accessibility roles |
Generic containers used as primary controls without semantics |
Light/Dark Mode Contrast
| Rule | Do | Don't |
|---|---|---|
| Surface readability (light) | Keep cards/surfaces clearly separated from background with sufficient opacity/elevation | Overly transparent surfaces that blur hierarchy |
| Text contrast (light) | Maintain body text contrast >=4.5:1 against light surfaces | Low-contrast gray body text |
| Text contrast (dark) | Maintain normal text contrast >=4.5:1 on dark surfaces; 3:1 is only for large text or non-text UI | Muted normal text that falls below the text threshold |
| Border and divider visibility | Ensure separators are visible in both themes (not just light mode) | Theme-specific borders disappearing in one mode |
| State contrast parity | Keep pressed/focused/disabled states equally distinguishable in light and dark themes | Defining interaction states for one theme only |
| Token-driven theming | Use semantic color tokens mapped per theme across app surfaces/text/icons | Hardcoded per-screen hex values |
| Scrim and modal legibility | Measure the composed result and use a scrim strong enough to isolate foreground content | Reusing one opacity without checking the actual background |
Layout & Spacing
| Rule | Do | Don't |
|---|---|---|
| Safe-area compliance | Respect top/bottom safe areas for all fixed headers, tab bars, and CTA bars | Placing fixed UI under notch, status bar, or gesture area |
| System bar clearance | Add spacing for status/navigation bars and gesture home indicator | Let tappable content collide with OS chrome |
| Consistent content width | Keep predictable content width per device class (phone/tablet) | Mixing arbitrary widths between screens |
| 8dp spacing rhythm | Use a consistent 4/8dp spacing system for padding/gaps/section spacing | Random spacing increments with no rhythm |
| Readable text measure | Keep long-form text readable on large devices (avoid edge-to-edge paragraphs on tablets) | Full-width long text that hurts readability |
| Section spacing hierarchy | Define clear vertical rhythm tiers (e.g., 16/24/32/48) by hierarchy | Similar UI levels with inconsistent spacing |
| Adaptive gutters by breakpoint | Increase horizontal insets on larger widths and in landscape | Same narrow gutter on all device sizes/orientations |
| Scroll and fixed element coexistence | Add bottom/top content insets so lists are not hidden behind fixed bars | Scroll content obscured by sticky headers/footers |
Pre-Delivery Checklist (canonical — the only one)
Before delivering app UI code, verify every item below. Start with the process steps, then the per-area checkboxes.
Process
- Ran only searches relevant to the interface, such as
"keyboard focus modal" --domain uxfor modal keyboard behavior - Reviewed
quick-reference.md§1–§3 (CRITICAL + HIGH) as a final pass - Tested on 375px (small phone) and in landscape orientation
- Verified behavior with reduced-motion enabled and Dynamic Type/largest system text size
- Checked dark mode contrast independently (never assume light-mode values carry over)
- Confirmed all touch targets ≥44pt and no content hidden behind safe areas
Visual Quality
- No emojis used as icons (use SVG instead)
- All icons come from a consistent icon family and style
- Official brand assets are used with correct proportions and clear space
- Pressed-state visuals do not shift layout bounds or cause jitter
- Semantic theme tokens are used consistently (no ad-hoc per-screen hardcoded colors)
Interaction
- All tappable elements provide clear pressed feedback (ripple/opacity/elevation)
- Touch targets meet minimum size (>=44x44pt iOS, >=48x48dp Android)
- Micro-interaction timing uses shared, platform-appropriate tokens and remains responsive in context
- Disabled states are visually clear and non-interactive
- Screen reader focus order matches visual order, and interactive labels are descriptive
- Gesture regions avoid nested/conflicting interactions (tap/drag/back-swipe conflicts)
Light/Dark Mode
- Primary text contrast >=4.5:1 in both light and dark mode
- Normal primary and secondary text contrast >=4.5:1 in both light and dark mode
- Dividers/borders and interaction states are distinguishable in both modes
- Modal/drawer scrim is measured against the real background and preserves foreground legibility
- Both themes are tested before delivery (not inferred from a single theme)
Layout
- Safe areas are respected for headers, tab bars, and bottom CTA bars
- Scroll content is not hidden behind fixed/sticky bars
- Verified on small phone, large phone, and tablet (portrait + landscape)
- Horizontal insets/gutters adapt correctly by device size and orientation
- 4/8dp spacing rhythm is maintained across component, section, and page levels
- Long-form text measure remains readable on larger devices (no edge-to-edge paragraphs)
Accessibility
- Decorative icons beside visible text are hidden from the accessibility tree (
aria-hidden="true"on web or the native equivalent) - Meaningful images/icons without equivalent visible text have a text alternative
- Icon controls have an accessible name and announce applicable selected/pressed/expanded state
- Form fields have labels, hints, and clear error messages
- Color is not the only indicator
- Reduced motion and dynamic text size are supported without layout breakage
- Sticky UI and overlays do not obscure keyboard focus
- Dragging and swipe-only interactions have button/keyboard alternatives
- Authentication allows password managers and paste, with a non-cognitive alternative
- Auto-rotating content has pause/stop controls and stops on focus or reduced motion
- Failed forms retain inline field errors; multi-error forms also focus a linked error summary after submit