Cheat sheet

Rules of thumb I design and build by, each with a live example.

Interface

Long reads: How to nest rounded corners, Why centered icons look off-center and Shadows vs borders for depth.

  • Align things by eye, not by the math. A play icon centered geometrically reads as off; nudge it until it looks centered.
    Not recommended
    Recommended
  • Nested corners should share a center. Inner radius = outer radius minus the padding between them, otherwise the corners fight each other.
    Not recommended
    Recommended
  • Reach for a stacked box-shadow before a border. A hairline plus a soft drop gives depth a flat 1px line never will.
  • An icon’s stroke should weigh the same as the text beside it. A 1px icon next to 14px medium text looks thin; 1.5px matches.
    Not recommended
    Recommended
  • When a button carries an icon, trim the padding on the icon side. Icons bring visual air of their own, so equal padding looks lopsided.
    Not recommended
    Recommended
  • Photos and thumbnails get a 1px inset outline: black at 8% on light backgrounds, white at 8% on dark. It keeps bright images from bleeding into the page.
    Sea at daytime

Motion

Long reads: How fast UI animations should be, Animating entrances and exits and CSS transitions vs keyframes.

  • Let buttons give a little when pressed: scale to 0.95 to 0.98 with transition: scale 200ms ease-out.
    Not recommended
    Recommended
  • Nothing should animate on page load unless you mean it to. A toast that slides in on every refresh is a bug, not delight.
    Draft saved
    Not recommended
    Draft saved
    Recommended
  • Popovers should grow out of the thing that opened them. Set transform-origin to the trigger’s corner, not the center.
  • Exits are quieter than entrances. On the way out, move a shorter distance, fade the opacity and add a 4px blur.
    Not recommended
    Recommended
  • When one icon replaces another, cross-fade them: the new one scales from 0.25 to 1, opacity 0 to 1, blur 4px to 0px. Mirror it for the outgoing icon.
  • Transitions can reverse mid-flight, keyframes cannot. Use transitions for anything a person can toggle back; keep keyframes for one-shot sequences.
    Not recommended
    Recommended
  • List the properties you actually animate. transition: all catches things you did not intend, and it costs more.
    Not recommendedtransition-all
    Recommendedtransition-colors
  • Bring content in as a few small groups with a short delay between them. One giant block sliding in reads as heavy.
    Ship interfaces that feel finished
    Notes on the small decisions that make a product feel considered.
  • Everyday interactions stay instant or close to it. A hover color change should not take half a second.
    Not recommended
    Recommended
  • Menus people open dozens of times a day should appear instantly and only animate on the way out.
    Right-click in each area
    Enter and exit
    Not recommended
    Exit only
    Recommended
  • If something jitters by a pixel while it moves, give it will-change: transform. Safari on iOS is the usual culprit.
    Hover me
  • Turn every transition off while switching themes. Otherwise each element changes color on its own schedule.
    AppearanceSyncs with your system.
    Save
    Not recommended
    AppearanceSyncs with your system.
    Save
    Recommended

Type

The long read: CSS typography for interfaces.

  • Balance headings with text-wrap: balance and tidy descriptions with text-wrap: pretty so no word is left alone on the last line. Skip both for long articles.
    wrap

    Interfaces that feel obvious the first time

    Good motion explains itself. Nobody should have to notice it.

    Not recommended
    balance + pretty

    Interfaces that feel obvious the first time

    Good motion explains itself. Nobody should have to notice it.

    Recommended
    Width220px
  • Numbers that change, such as timers, counters and prices, need font-variant-numeric: tabular-nums. Every digit gets the same width, so nothing shifts as the value ticks. Monospace fonts already do this.
    1000
    Not recommended
    1000
    Recommended
  • Serve fonts as .woff2 only. .ttf and .otf are desktop formats and download far heavier.
    FormatNameUsage
    .woff2
    Web Open Font Format 2All modern browsers
    Use this
    .woff
    Web Open Font FormatLegacy fallback
    Fallback
    .ttf
    TrueTypeDesktop and old browsers
    Avoid
    .otf
    OpenTypeDesktop and old browsers
    Avoid
  • Cap reading text at roughly 60 to 75 characters per line. Any wider and the eye loses its place on the way back.
    Not recommended

    Lines that run the full width of a wide container, well past 75 characters.

    Recommended

    The same text with its measure capped, so each line stays between 60 and 75 characters.

  • Underlines should not slice through descenders. Set text-underline-position: from-font and text-decoration-skip-ink: auto.
    Gravity pulls every glyph
  • Long tokens, links and IDs need overflow-wrap: break-word so they stay inside their box. Badges and labels get white-space: nowrap so they never break in half.
    break-word
    Not recommended

    Your token tk_7Qm4xRz9vL2pWd8nKcYb3sH is live.

    Recommended

    Your token tk_7Qm4xRz9vL2pWd8nKcYb3sH is live.

    nowrap
    Not recommended
    Updated 3 min ago
    Recommended
    Updated 3 min ago
  • If you cut text with an ellipsis, offer the full text somewhere: a tooltip, or a way to expand it.

    Interfaces that feel obvious the first time, for everyone who opens them.

  • Set -webkit-font-smoothing: antialiased and -moz-osx-font-smoothing: grayscale once at the root. Text comes out crisper and lighter on macOS.

    Subpixel text

    macOS smooths text with subpixel antialiasing by default.

    Antialiased text

    Grayscale antialiasing renders lighter, crisper text.

  • Write copy in sentence case and let text-transform handle uppercase or lowercase when the design calls for it. The source text stays readable.
    Considered detailsnone
    Considered detailsuppercase
    Considered detailslowercase
    Considered detailscapitalize
  • Use real typographic marks: curly quotes, an en dash (–) for ranges, an em dash (—) for asides and a single ellipsis (…) rather than three periods.
    "good type"“good type”
    Quotes
    1999-20041999–2004
    En dash
    fast - simplefast—simple
    Em dash
    saving...saving…
    Ellipsis

Color

The long read: Structuring color tokens.

  • Components consume semantic tokens like --color-text-secondary, never raw primitives like --green-500. The primitive is a value; the token is a job.
    --green-500
    Not recommended
    --green-500
    --color-accent-solid
    Recommended
  • Name tokens after their role, not their color: --color-accent-solid still makes sense after a rebrand, --color-green-button does not.
    --color-accent-solid
    Recommended

    Still true after a rebrand, whatever the color becomes.

    --color-green-button
    Not recommended

    Says green, renders violet. The name lied the day the brand changed.

    --color-panel-gray
    Not recommended

    Retint one panel and every surface that borrowed the token moves with it.

  • Every step of a gray ramp should earn its place: page background, hover, border, solid fill, body text. Delete the steps nothing uses.
    gray-100page background
    gray-200
    gray-300component hover
    gray-400
    gray-500border
    gray-600
    gray-700
    gray-800
    gray-900solid fill
    gray-1000
    gray-1100
    gray-1200body text
  • Check contrast against the surface the text actually sits on, not the page behind it. Same text, different ratio.

    This label sits on a card, not on the page.

    page 1.3:1
    Not recommended
    surface 4.8:1
    Recommended
    Text lightness90%
  • Call the brand color accent. If primary means both the brand and the darkest text, nobody knows which one you mean.
    heading
    --color-primary
    body
    --color-secondary
    button
    --color-primary
    Not recommended
    heading
    --color-text-primary
    body
    --color-text-secondary
    button
    --color-accent-solid
    Recommended
  • Design a dark palette on its own terms. Inverting the light one gives you pure black and glaring white.
    Monthly notesOne email, once a month.
    Follow
    Not recommended
    Monthly notesOne email, once a month.
    Follow
    Recommended
  • Pick a single switch for themes, prefers-color-scheme or a .dark class, and apply it to every token. Mixing them leaves half the UI in the wrong mode.
    WorkspaceSigned in as Mina.
    surface: .dark · text: media query
    Not recommended
    WorkspaceSigned in as Mina.
    all tokens: .dark
    Recommended
  • Gradients can interpolate in different color spaces: in oklab for even brightness, in oklch for livelier midtones, in srgb for the softer, muddier blend.
    sRGB
    oklab
    oklch

Accessibility

The long read: Accessibility basics for interfaces.

  • Style :focus-visible, not :focus, and never strip the outline without putting something in its place.
    Press Tab to move focus through the buttons
    Not recommendednone
    Recommendeddefault
    Recommendedcustom
  • Prefer the native element: a <button> for actions, an <a> for navigation. Middle-click, right-click and keyboard support come for free.
    Not recommended<div>

    This side is the same link built from a div with a click handler. Without an href the browser cannot open it in a new tab, offer it in the right-click menu, preview its address on hover or list it as a link.

    Recommended<a>
    Try a middle click, a right click and a Cmd-click on each one
  • Targets should be at least 24x24px, ideally 40x40px on desktop and 44x44px on touch, and they must never overlap.
    Not recommended
    Recommended
  • Every field gets a visible <label>. Match type and inputmode to the data so phones open the right keyboard.

    This field only has a placeholder, which disappears as soon as you type and its text type brings up the generic keyboard on touch devices.

    Not recommended
    Recommended
  • Leave the submit button enabled until the request starts, then validate. Flag fields with aria-invalid="true", link the message with aria-describedby and move focus to the first error.

  • Color cannot be the only signal that something changed. Pair it with an icon, a message or an underline.

    Not recommended

    Enter a valid email address

    Recommended
  • Icon-only buttons need a real aria-label. And never put aria-hidden="true" on anything that can take focus.
    Not recommended
    Recommended
  • Alt text should say what the image is for and what it shows. Purely decorative images get alt="".
    imagealt="image"
    Not recommended
    A focus ring following the rounded corner of a cardalt="A focus ring following the rounded corner of a card"
    Recommended
  • Stick to tabindex="0" and tabindex="-1". Positive values reorder focus in ways nobody expects.

    Tab through the buttons to record the order focus visits them.

    Not recommended

    Tab through the buttons to record the order focus visits them.

    Recommended
    Click in and press Tab to cycle through items
  • Do not block paste. Passwords and one-time codes arrive by paste all the time.
    Copy the code and paste it into both fields
    Not recommended
    Recommended
  • A skip-to-content link should be the very first thing Tab lands on.
    Skip to content

    Main content

  • Honor reduced motion. Wrap animations in @media (prefers-reduced-motion: no-preference) so they only run for people who want them.
    Not recommended
    Recommended
  • Wrap hover styles in @media (hover: hover). On touch screens a tapped item otherwise stays lit as if selected.
    Not recommended
    Recommended
  • Glows, gradients and other decoration get pointer-events: none so they never eat a click meant for the control underneath.

    Clicks: 0

  • Announce routine confirmations with role="status". Keep role="alert" for errors that need attention now.

Layout

  • Space between groups should be at least double the space inside them: 8px between items, 16px or more between groups.
    Alerts
    Email
    Push
    Sharing
    Public profile
    Read receipts
    Not recommended
    Alerts
    Email
    Push
    Sharing
    Public profile
    Read receipts
    Recommended
  • Give headings scroll-margin-top so a sticky header never covers them after an anchor jump.
    Click Roadmap in each header

    Roadmap

    Not recommended

    Roadmap

    Recommended

Copy

The long read: Writing clear UI copy.

  • Buttons start with a verb: “Save changes”, “Remove workspace”. Never “OK!” or a lone “Yes”.

    Keep these edits?

    This draft has edits you have not saved.

    Not recommended

    Keep these edits?

    This draft has edits you have not saved.

    Recommended
  • Use one word to advance through a flow. Pick “Continue” or “Next” and keep it on every step.
    Step 1 of 3
    Step 2 of 3
    Step 3 of 3
    Not recommended
    Step 1 of 3
    Step 2 of 3
    Step 3 of 3
    Recommended
  • A confirmation button names the outcome: “Remove workspace” beside “Cancel”, not “Yes” beside “No”.

    Remove this workspace?

    This removes the workspace and everything in it.

    Not recommended

    Remove this workspace?

    This removes the workspace and everything in it.

    Recommended
  • Keep capitalization consistent across buttons, headings and labels. Sentence case, “Save changes”, is the safest default.

    PREFERENCES

    Pick Where Alerts Go.

    Email Address
    Not recommended

    Preferences

    Pick where alerts go.

    Email address
    Recommended
  • Name a toggle after what happens when it is on: “Show previews”, not “Turn off previews”.
    Turn off previews
    Not recommended
    Show previews
    Recommended
  • An empty view should say what belongs there and offer one way to start, instead of a bare “Nothing here”.

    Nothing here.

    Not recommended

    No boards yet

    Boards collect your screens, notes and links in one place.

    Recommended
  • Link text should say where the link goes. “Read the changelog”, not “Click here”.

    Click here for the details.

    Not recommended

    Read the changelog for the details.

    Recommended
  • Talk to the reader as “you”, never as “the user”.

    The user will get a confirmation.

    Not recommended

    You'll get a confirmation.

    Recommended

The live examples follow the ones on interfaces.dev, rebuilt by hand as a study in interaction detail.