Common UI Patterns
Users spend most of their time on other apps and websites. They arrive at yours with expectations already set โ Jakob's Law. Following established UI conventions means users spend their mental energy on your content, not your interface. Breaking those conventions means friction, confusion, and drop-off.
This page covers the patterns that work, the anti-patterns that don't, and the reasoning behind each.
Navigationโ
Persistent Navigationโ
Main navigation should be visible on every page โ top bar, sidebar, or both. Users need to always know where they are and how to get somewhere else. Navigation is how users build a mental map of your application; hide it and they get lost.
- Keep primary navigation visible at all times on desktop. Don't hide it behind creative layouts or animations.
- Provide a clear "home" affordance โ usually the logo in the top-left corner.
- Use consistent placement across all pages. Moving navigation between pages breaks spatial memory.
- Consider sticky or fixed navigation on long pages so users can navigate without scrolling back to the top.
Anti-pattern: Hiding all navigation behind an unlabeled icon on desktop. The hamburger menu (โฐ) is understood on mobile โ on desktop, it buries discoverability.
Breadcrumbsโ
Use breadcrumbs for sites with three or more levels of hierarchy. They show users where they are in the structure and provide a fast way to jump up.
- Place breadcrumbs below the main navigation, above the page title.
- Use Schema.org BreadcrumbList markup for SEO benefit.
- Don't rely on breadcrumbs as the only back-navigation โ they supplement, not replace, the main nav.
Mobile Navigationโ
- Bottom tab bar for up to 5 primary destinations. Tabs sit in the thumb-friendly zone and leverage the Serial Position Effect โ put the most important items first and last.
- Hamburger menu (โฐ) for secondary items. It's a universal convention on mobile โ users know what it means.
- Never put the only navigation behind a hamburger menu on desktop. Desktop has the screen real estate to show navigation directly.
Active Statesโ
Always indicate the current page or section in the navigation. Users should never have to guess where they are.
- Highlight the active nav item with a visual indicator โ bold text, underline, background color, or left border.
- Use
aria-current="page"on the active link for screen readers. - See Accessibility as Design for more on accessible navigation.
Anti-patterns to avoid:
- More than 7โ8 top-level navigation items โ Hick's Law says decision time increases with options.
- Hover-only dropdown menus that disappear when the cursor drifts off by a pixel.
- Identical-looking items that link to different content types (mixing pages, downloads, and external links with no visual distinction).
Form Designโ
Layoutโ
Single-column forms outperform multi-column layouts. Users complete them roughly 15 seconds faster because there's no ambiguity about reading order (Baymard Institute research). Use a single column unless you have a strong reason not to.
- Group related fields with
<fieldset>and<legend>. - Keep forms as short as possible โ every field you can remove increases completion rate (Parkinson's Law).
- Break long forms into logical steps with a progress indicator.
Labels and Placeholdersโ
Place labels above their fields. This layout produces the fastest completion times, works on all screen sizes, and accommodates labels of varying length.
Never use placeholder text as the only label for a form field. Placeholder text disappears when the user starts typing, removing the context they need to verify their input. This is also an accessibility failure โ placeholder text typically has insufficient contrast and is not reliably announced by screen readers.
Placeholder text is supplementary. Use it to show format examples ("e.g., jane@example.com") alongside a visible label, never instead of one.
Validationโ
Validate inline on blur โ when the user leaves a field. Don't validate on every keystroke (it's distracting while typing), and don't wait until form submission (it's too late).
- Error messages should say what went wrong and how to fix it: "Password must be at least 8 characters" โ not "Invalid password."
- Show all errors at once, not one at a time. Revealing errors sequentially makes users feel like they're playing whack-a-mole.
- Use
aria-describedbyto associate error messages with their fields for screen readers. - Pair the red error color with an icon (โ ๏ธ) โ color alone is not enough for colorblind users.
Show success states too, not just errors. A green checkmark next to a validated email field gives users confidence that they're on track.
Smart Defaultsโ
Every field you can pre-fill is one less decision for the user.
- Pre-select the most common choice (country, language, currency).
- Use proper
autocompleteattributes so browsers can auto-fill name, email, address, and payment fields. - Auto-detect locale for country, currency, and date format when possible.
- Default radio buttons and toggles to the most common option rather than leaving them unselected.
Submit Buttonsโ
The button label should describe what happens. Use "Create Account" not "Submit." Use "Save Changes" not "OK."
- Place the primary submit button at the bottom-left of the form โ the natural terminus of the user's eye flow in LTR layouts.
- Disable the button briefly after click to prevent double-submission, or implement idempotent submission on the server side.
- Show a loading spinner on the button during submission so users know their action was received.
- For destructive actions, use a confirmation step โ not just a different button color.
Responsive Designโ
Mobile-Firstโ
Start with the smallest screen, then add complexity as the viewport grows. Use min-width media queries, not max-width:
/* Mobile-first: base styles are mobile */
.card { padding: 1rem; }
/* Add complexity for larger screens */
@media (min-width: 768px) {
.card { padding: 2rem; display: grid; grid-template-columns: 1fr 1fr; }
}
This approach forces prioritization. If the content doesn't fit on a small screen, ask whether it's truly essential.
Breakpointsโ
Don't design for specific devices โ design for where your layout breaks. Test by resizing your browser and adding breakpoints where the content stops looking right.
Common starting points (Tailwind CSS defaults):
| Token | Width | Typical Usage |
|---|---|---|
sm | 640px | Large phones in landscape |
md | 768px | Tablets |
lg | 1024px | Small laptops |
xl | 1280px | Desktops |
2xl | 1536px | Large screens |
These are starting points, not gospel. Adjust based on your content and layout needs.
Fluid Typographyโ
Instead of jumping between fixed sizes at breakpoints, use clamp() for smooth scaling:
h1 {
font-size: clamp(1.875rem, 1rem + 2vw, 2.5rem);
}
body {
font-size: clamp(1rem, 0.5rem + 1.5vw, 1.25rem);
}
No media queries needed. See Visual Design Fundamentals for the full typography section.
Touch Targetsโ
Minimum touch target size: 44ร44 CSS pixels (WCAG 2.5.5 AAA). Google Material Design recommends 48ร48px.
- Ensure at least 8px of spacing between adjacent interactive targets.
- This is especially critical when destructive actions sit next to safe ones โ "Delete" next to "Edit" with no gap is an accident waiting to happen.
- See Accessibility as Design for comprehensive touch target guidance.
Loading Statesโ
Timing Thresholdsโ
Match your loading UI to how long the user is waiting. The Doherty Threshold tells us that perceived responsiveness drops sharply after 400ms.
| Response Time | User Perception | Recommended UI |
|---|---|---|
< 100ms | Feels instant | No indicator needed |
| 100โ300ms | Slight delay | Subtle indicator (button spinner, disabled state) |
| 300msโ1s | Noticeable wait | Skeleton screen or loading shimmer |
| 1โ10s | Significant wait | Progress bar or descriptive message |
> 10s | Too long | Explain what's happening, allow cancel |
Skeleton Screensโ
Prefer skeleton screens over spinners for content loading. Skeletons show the shape of the upcoming content with pulsing gray placeholders. This approach reduces perceived wait time (users see progress, not emptiness) and prevents Cumulative Layout Shift (CLS) because the skeleton reserves the space the real content will occupy.
.skeleton {
background: linear-gradient(
90deg,
#e5e7eb 25%,
#f3f4f6 50%,
#e5e7eb 75%
);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
border-radius: 4px;
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
Optimistic Updatesโ
Update the UI immediately on user action, then reconcile with the server in the background. This makes the interface feel instant.
- Best for low-risk, reversible actions: liking, bookmarking, toggling settings, reordering items.
- Roll back the UI change on failure with a clear error message.
- Provide a subtle undo option for reversible actions.
Only use optimistic updates for reversible, low-risk actions. For destructive or financial operations, wait for server confirmation before updating the UI.
Anti-pattern: Full-page loading spinners that block all interaction. Prefer inline, contextual loading states that let users continue interacting with the rest of the page.
Error Statesโ
Inline Field Errorsโ
Display errors directly below the field they apply to. Combine multiple signals so the error is unmistakable:
- Red border on the field.
- Error icon (โ ๏ธ) โ don't rely on color alone, as some users can't distinguish red.
- Descriptive text explaining the problem and how to fix it.
- Use
aria-describedbyto associate the error message with the field for screen readers. - Show all errors at once. Revealing them one at a time forces unnecessary resubmissions.
Error Pagesโ
Error pages are often an afterthought, but they're a critical part of the user experience โ especially when something goes wrong.
- 404 (Not Found): Be helpful, not just apologetic. Include search, suggested pages, or navigation links. A dead-end 404 is a lost user.
- 500 (Server Error): Be honest. "We couldn't load your data. Try refreshing the page." โ not "An error occurred." Provide a retry action and a way back (link to home, search bar).
- Use plain language in all error pages. Technical jargon helps nobody.
- Include a consistent header and navigation on error pages so users can self-recover.
Network Errorsโ
- Detect offline status with
navigator.onLineandonline/offlineevents. - Show a banner, not a full-page error โ users may still have cached content they can read.
- Queue actions for retry when connectivity returns, if your architecture supports it.
Non-Destructive Error Handlingโ
The cardinal rule of error handling: never lose the user's work.
- Never clear form data on submission error โ preserve every field the user filled in.
- Never navigate away from the user's current context on error.
- Use toasts for transient, non-critical errors. Auto-dismiss after 5โ8 seconds.
- Persist important errors (data loss, payment failure) until the user explicitly dismisses them.
- Don't stack more than 3 toasts at once โ it overwhelms the screen and the user.
Empty Statesโ
An empty state is a design opportunity, not a blank page.
First-Use Empty Statesโ
An empty dashboard on first login is a missed onboarding moment. The user has just committed to your product โ this is your chance to guide them.
Instead of a blank screen, show:
- A clear explanation of what will appear here ("No projects yet").
- A primary call-to-action ("Create your first project").
- Optionally, a brief illustration or icon to soften the emptiness.
- If applicable, a sample or template the user can explore before creating their own.
Guide the user toward their first meaningful action. Don't make them figure out how to get started.
No-Results Statesโ
When a search or filter returns nothing:
- Show the search term back to confirm what was searched: "No results for 'flutterby'."
- Suggest next steps: check spelling, broaden criteria, try different keywords.
- If possible, show related or popular results as a fallback.
User-Cleared Statesโ
When the user has deleted or archived everything in a list:
- Confirm the action succeeded ("All items archived").
- Offer a clear way to add new items or undo the last action.
Anti-pattern: A blank white page with no guidance. A data table showing column headers and zero rows with no explanation. Both leave users wondering if something is broken.
Further Readingโ
- Laws of UX โ The psychological principles behind these patterns.
- Visual Design Fundamentals โ Typography, color, spacing, and hierarchy.
- Accessibility as Design โ Accessible navigation, forms, and touch targets.
- Design Tools & Resources โ Checklist Design, Mobbin, and other pattern references.
- NNGroup โ Evidence-based UX research on navigation, forms, error handling, and more.
- Baymard Institute โ Form and e-commerce UX research.