Interface Cheat Sheet
User Interface
- When nesting elements, make their border radius concentric. The outer radius equals the inner radius plus the padding between the elements.Not recommendedRecommended
- Prioritize optical alignment over geometric alignment.Not recommendedRecommended
- A button with text and an icon gets slightly smaller padding on the side of the icon.Not recommendedRecommended
- Use a layered
box-shadowto give elements depth instead of using borders. - Give images a
1pxoutline, offset by-1px: black at8%opacity in light mode, white at8%in dark mode.

- Match the icon’s stroke to the text next to it.Not recommendedRecommended
Animation
- Make elements animate from the trigger rather than the center. Set
transform-originbased on the trigger’s position. - For menus people open often, skip the opening animation and only animate when they close.Right-click in each areaEnter and exitNot recommendedExit onlyRecommended
- Make exit animations more subtle than entrances. Move the element by a shorter distance as it fades out with
opacityand a4pxblur.Not recommendedRecommended - Name the exact properties you want to animate in a transition. Never use
transition: all.Not recommendedtransition-allRecommendedtransition-colors - Make buttons scale down slightly when pressed. Use a scale between
0.95and0.98withtransition: scale 200ms ease-out.Not recommendedRecommended - When icons swap, fade one out as the other fades in. Animate the new icon’s scale from
0.25to1, opacity from0to1and blur from4pxto0px. Reverse these for the old icon. - Use CSS transitions for interactions so the animation can change direction halfway through. Use keyframes for sequences that only run once.Not recommendedRecommended
- Disable all transitions when switching between light and dark mode.AppearanceSyncs with your system.Not recommendedSaveAppearanceSyncs with your system.RecommendedSave
- If an element randomly shifts by 1–2px while animating, add
will-change: transformto it. This is especially useful in Safari on iOS.Hover me - When elements enter, animate them in small groups with a short delay between each group instead of animating one giant block.Build software that never breaksInterfere is the experience layer for modern product teams.
- Prevent elements from animating on page load, unless it’s intentional.Changes savedNot recommendedChanges savedRecommended
- Keep frequent interactions instant or very fast, like an item changing color when you hover it.
Typography
- Always use
.woff2font files on the web, never.ttfor.otf.FormatNameSizeUsage.woff2Web Open Font Format 2All modern browsersUse this.woffWeb Open Font FormatLegacy fallbackFallback.ttfTrueTypeDesktop and old browsersAvoid.otfOpenTypeDesktop and old browsersAvoid - Use
font-variant-numeric: tabular-numsin timers, counters, prices and tables. It gives every digit the same width which prevents layout shifts when the values change. Skip it if you’re already using a monospace font.1000Not recommended1000Recommended - Keep lines in articles and other long text to 60–75 characters. Long form text that is wider than that is difficult to read.Not recommended
Lines that run the full width of a wide container, well past 75 characters.
RecommendedThe same text with its measure capped, so each line stays between 60 and 75 characters.
- Use
text-wrap: balanceto even out headings andtext-wrap: prettyon descriptions to prevent orphaned words. Use neither for long form text.wrapDesigning interfaces that feel natural and intuitive
Great design is invisible. It guides users without them ever noticing.
Not recommendedbalance + prettyDesigning interfaces that feel natural and intuitive
Great design is invisible. It guides users without them ever noticing.
RecommendedWidth220px - Keep long words, links and IDs inside their container with
overflow-wrap: break-word. Usewhite-space: nowrapto prevent labels and badges from wrapping.break-wordNot recommendedYour API key ak_92hFqL7xVtN3mYc8RwJd5pZk is ready.
RecommendedYour API key ak_92hFqL7xVtN3mYc8RwJd5pZk is ready.
nowrapNot recommendedLast synced 2 min agoRecommendedLast synced 2 min ago - Set
-webkit-font-smoothing: antialiasedand-moz-osx-font-smoothing: grayscaleon the root layout to make text appear sharper.Subpixel rendering
Default font smoothing uses subpixel antialiasing on macOS.
Antialiased rendering
Grayscale antialiasing produces thinner, crisper light text.
- Write text with normal capitalization. Use
text-transformwhen you want to display it in uppercase or lowercase.Typographic detailnoneTypographic detailuppercaseTypographic detaillowercaseTypographic detailcapitalize - Use smart punctuation: curly quotes, an en dash (–) for ranges, an em dash (—) for asides and an ellipsis (…) instead of three dots."web type"“web type”Quotes2010-20202010–2020En dashtype - cleartype—clearEm dashloading...loading…Ellipsis
- Keep underlines from crossing the tails of letters like g and y. Use
text-underline-position: from-fontwithtext-decoration-skip-ink: auto.Typography enjoys gravity - When you shorten text with an ellipsis, let people read the full text in a tooltip or an expanded view.
Designing interfaces that feel natural and intuitive for everyone who uses them.
Colors
- Every step in a color palette should have a purpose: page background, component hover, border, solid fill, body text. Don’t add steps that nothing uses.gray-100page backgroundgray-200gray-300component hovergray-400gray-500bordergray-600gray-700gray-800gray-900solid fillgray-1000gray-1100gray-1200body text
- Components should use semantic tokens (
--color-text-secondary), never primitives (--blue-500). The primitive is the raw value, the token is how the value is used.Not recommended--blue-500Recommended--blue-500--color-accent-solid - Name color tokens by purpose:
--color-accent-solidinstead of--color-blue-buttonor--color-sidebar-gray.--color-accent-solidRecommendedThe name still makes sense when the color changes.
--color-blue-buttonNot recommendedIt's called 'blue' even though the color is now violet.
--color-sidebar-grayNot recommendedChanging the sidebar color now changes it across the app.
- Reserve
accentfor the brand color soprimarynever means both the brand and the main body text.- heading
- --color-primary
- body
- --color-secondary
- button
- --color-primary
- heading
- --color-text-primary
- body
- --color-text-secondary
- button
- --color-accent-solid
- Measure contrast against the background directly behind an element.
This text renders on the surface, not the page.
page 1.3:1Not recommendedsurface 4.8:1RecommendedText lightness90% - Create a separate color palette for dark mode instead of inverting the light mode palette.Not recommendedWeekly digestFive links every Friday.SubscribeRecommendedWeekly digestFive links every Friday.Subscribe
- Choose one way to switch themes:
prefers-color-schemeor a.darkclass. Don’t mix both.Not recommendedsurface: .dark · text: media queryAccountSigned in as Ada.Recommendedall tokens: .darkAccountSigned in as Ada. - You can define how colors blend in a gradient. Use
in oklabfor even brightness,in oklchfor more vivid colors in the middle orin srgbfor more muted midtones.
Accessibility
- Use native HTML elements:
<button>for buttons and<a>for links, for example. Native elements already have a lot of accessibility and other expected behavior built in.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 - Style
:focus-visibleinstead of:focus. Don’t remove the outline without a replacement.Press Tab to move focus through the buttonsNot recommendednoneRecommendeddefaultRecommendedcustom - Only use
tabindex="0"andtabindex="-1". Positive values change the expected order of the elements.Not recommendedTab through the buttons to record the order focus visits them.
RecommendedTab through the buttons to record the order focus visits them.
Click in and press Tab to cycle through items - Give buttons that only have an icon a descriptive
aria-label. Never putaria-hidden="true"on an element that can be focused.Not recommendedRecommended - Write alternative text that explains the image’s purpose and what it shows. Give decorative images
alt="".Not recommended
alt="image"Recommended
alt="Close up of a focus ring curving around an element's rounded corner" - Give every input a visible label using
<label>. Set itstypeandinputmodeto match what people should enter.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 recommendedRecommended - Never block paste. People paste in things like passwords and one-time codes.Copy the code and paste it into both fieldsNot recommendedRecommended
- Keep the submit button enabled until the request starts. Check for errors when people submit. Mark invalid fields with
aria-invalid="true", connect each error message witharia-describedbyand move focus to the first invalid field. - Make hit areas at least
24x24px. Aim for44x44pxon touch screens and40x40pxon desktop where possible. Make sure they never overlap.Not recommendedRecommended - Use
pointer-events: noneon decorative elements like glows and gradients so events are never swallowed.Presses: 0
- Put hover styles inside
@media (hover: hover). On touch screens,:hoverstays active after a tap and makes an item look selected.Not recommendedRecommended - Respect people’s reduced motion setting. Put animations inside
@media (prefers-reduced-motion: no-preference)so they only play for people who don’t have motion reduced.Not recommendedRecommended - Use
role="status"to announce routine updates to screen readers. Saverole="alert"for urgent errors. - Never use color alone to show a status change. Add an icon, a label or an underline too.Not recommendedRecommended
Enter a valid email address
- Make the skip-to-content link the first stop when someone presses Tab.Skip to content
Main content
Layout
- Use
scroll-margin-topto leave space above headings when people follow links to them.Click Pricing in each headerNot recommendedPricing
RecommendedPricing
- Leave at least twice as much space between groups as between items in a group. For example, use
8pxbetween items and16pxor more between groups.NotificationsNot recommendedEmailPushPrivacyProfileReceiptsRecommendedNotificationsEmailPushPrivacyProfileReceipts
Writing
- Start button labels with a verb: “Save draft” or “Delete project”, never “OK!” or a bare “Yes”.Not recommended
Save your changes?
Your draft has edits that are not saved yet.
RecommendedSave your changes?
Your draft has edits that are not saved yet.
- Make confirmation buttons say what will happen: “Delete project” next to “Cancel”.Not recommended
Delete this project?
This removes the project and all of its files.
RecommendedDelete this project?
This removes the project and all of its files.
- Use the same label to move to the next step throughout a flow. Choose “Continue” or “Next” and use it for every step.Not recommendedStep 1 of 3Step 2 of 3Step 3 of 3RecommendedStep 1 of 3Step 2 of 3Step 3 of 3
- Describe where a link goes.
Click here to learn more.
Not recommendedRead the docs to learn more.
Recommended - Capitalize buttons, headings and labels the same way everywhere. Sentence case, like “Save changes”, is the safer default.Not recommended
SETTINGS
Choose Where We Send Updates.
Email AddressRecommendedSettings
Choose where we send updates.
Email address - Label toggles with what happens when they’re on: “Send read receipts”, not “Disable read receipts”.Not recommendedDisable read receiptsRecommendedSend read receipts
- When a view is empty, explain what belongs there and give people one action to get started instead of nothing.
No results.
Not recommendedRecommendedNo projects yet
Projects keep your files, notes and tasks in one place.
- Address the reader as “you”, not “the user”.
The user will receive an email.
Not recommendedYou'll receive an email.
Recommended
