⚡ Skill Hub+ New Skill
← All skills
frontenduxfrontend

UX Designer

Practical UX rules for user-facing frontend work — the four screen states, action feedback, forms, destructive actions, cognitive load and accessibility. Style-agnostic: applies to any design system or brand.

by Joakim-Edvardsen30 Jul 2026

UX Designer

Polish is the sum of small things. Every point below holds regardless of visual style — apply them all.

Consistency

Many points below leave a choice open — how required fields are marked, how errors are worded, which actions get undo, how long a transition runs. Whenever there's a choice, check what the app already does and follow it. Only decide fresh when there is no precedent, then apply that decision everywhere. Users learn a pattern once; two reasonable conventions side by side are worse than either one applied consistently.

Cognitive load

  • Meet existing expectations (Jakob's Law). Users spend most of their time in other apps and arrive expecting yours to behave the same way. Put familiar things where they're already looked for, per device — a cart sits top-right on web and within thumb reach on mobile. Core flows like cart and checkout get zero friction and zero surprises; spend originality on the parts that aren't load-bearing.
  • Fewer choices at a time (Hick's Law). Decision time grows with the number and complexity of options. Group and sequence them rather than presenting everything at once — the goal is fewer choices per step, not fewer capabilities.
  • Progressive disclosure. Show what's needed right now and keep the rest one step away. Caveat: never bury a primary action so deep it needs a tutorial to find.
  • Absorb the complexity (Tesler's Law). Complexity doesn't disappear, it only moves. Every burden the system can carry — sensible defaults, inference, doing the tedious step for them — is one the user doesn't.

States

Every screen has four: success, loading, empty and error. Success always gets built; the other three are where polish is won or lost.

Loading

Show a skeleton that mirrors the layout of the real content.

Note: A skeleton out of sync is worse than no skeleton — it shifts the layout on load. Match the final layout exactly.

  • Delay the skeleton by a beat so fast responses never show one. A skeleton that appears and vanishes inside a second makes the app feel slower than no skeleton at all.
  • Never hold a screen hostage to its slowest request. Render each section as its data arrives, keeping indicators only on what's still pending.
  • For actions rather than page loads, put the feedback on the trigger: disable it, show inline progress, make double-submission impossible.

Empty

  • No content yet — the first thing most users see, so it matters most. Say what will appear here and give one clear call to action. E.g. a projects page with none created: "No projects yet" + "Create your first project". Where getting started genuinely takes several steps, a short wizard beats a lone button.
  • Happy empty — empty is the desired state. Make it feel earned; this is the one place a little delight is justified. E.g. "Inbox all clear. Time for a coffee break", with an illustration or animation worth arriving at.

Error

  • Answer three things: what happened, why, and what the user can do about it.
  • Never render backend, database or stack-trace detail in production. Behind a dev flag, fine.
  • Scope the error to what actually failed. One dead section must not blank a page whose other data loaded fine — degrade gracefully around it.
  • Failed loads get a retry; failed actions keep the user's input.

Feedback

Every interaction gets a visible response immediately, even when the result takes longer.

Success: match the weight of the action. Finishing a signup or a purchase can carry a full success screen and some celebration; completing a todo should strike it through and fade it out of the list, nothing more. Where the outcome is self-evident — landing on the project you just created — that is the feedback, so don't stack a toast on top of it. The one unacceptable option is nothing at all, leaving the user asking "did that go through?"

Failure: always explicit, and shown next to the thing that failed — the form, the row, the button that was clicked. A toast alone is too easy to miss and disconnects the error from its cause.

Optimistic updates: where an action nearly always succeeds and is cheap to reverse — toggling a favourite, checking off a task, reordering a list — apply the change instantly and reconcile in the background. Skip it when failure is likely or a silent rollback would confuse the user, and always surface the revert if one happens.

Animations & transitions

Subtle enough to go unnoticed — the user should only feel their absence, as a vague sense that something is missing. An animation you clearly notice is too much. Keep them short, ease-out, and on cheap properties (transform/opacity). Respect prefers-reduced-motion.

Forms

  • Break long forms into logical groups or steps rather than one flat wall of equally-weighted fields. Grouping shows how much is left and turns one intimidating task into several small ones.
  • Mark required vs optional explicitly — * on required or (optional) on optional, never both: mixing them makes an unmarked field ambiguous.
  • Hold submit until every required field is filled, and make what's missing visible on the page. A disabled button with no explanation is its own dead end.
  • Validate on the client for fast feedback. Validate on blur, not on every keystroke.
  • Show strict requirements (password rules, formats, limits) up front instead of letting the user guess and fail.
  • On submit, highlight every invalid field with its message beside it. On long forms, scroll to and focus the first invalid one.
  • Write validation messages for the end user, not for debugging.
  • Never clear the form. Preserve what the user typed through validation errors, failed submits and back-navigation. Retyping everything is the most punishing thing a form can do.
  • Label every input (a placeholder is not a label). Use correct input types and autocomplete so mobile keyboards and password managers work.

Destructive actions

  • Confirm before destroying.
  • Label the specific action, never the abstraction: "Delete this project?" with "Delete project" / "Keep project" — not "Are you sure? Yes/No".
  • Where the action is cheap to reverse, prefer a short-lived undo over a confirmation dialog. Judge per case; not every action needs it.

Accessibility

  • Everything reachable and operable by keyboard alone, in a logical tab order — for assistive tech and power users alike.
  • Visible focus indicator on every interactive element. Never remove the outline without replacing it.
  • Dialogs and modals: trap focus, close on Escape, return focus to the trigger.
  • Give icon-only controls accessible names.
  • Never rely on colour alone to carry meaning.

Danger zone

Edit