On this page
When people call an interface polished, they rarely point at one thing. They are reacting to hundreds of small decisions that agree with each other: every gap from the same scale, every corner from the same set of radii, every state accounted for. When those decisions disagree, the interface feels slightly off, even to people who cannot say why.
This note takes the decisions one at a time. The examples are live HTML and CSS, so the buttons and fields respond to your pointer and keyboard.
01Spacing and alignment
Most interfaces that feel messy are not short of space; they use too many different amounts of it. Pick a scale, usually based on 4 or 8 pixels, and take every margin, padding and gap from it. Then align edges: text, inputs and buttons inside a container should share the same left edge.
Gaps of 5, 15 and 11 pixels. Three slightly different left edges.
4 inside the heading pair, 16 between blocks, 24 padding. One left edge.
A scale does not make every decision for you. It makes the decisions comparable. "Is this 16 or 24?" is a question a team can answer and a reviewer can check. "Is this 13 or 15?" is not.
02Border radius and shape consistency
Corner radius sets the personality of an interface, from sharp and technical to soft and friendly. Polish comes less from the size you choose than from using few sizes, and from nesting them correctly.
The rule for nested shapes: outer radius = inner radius + the padding between them. When a rounded element sits inside a rounded container with the same radius, the gap between their corners looks thicker than the gap along their sides.
The corners bulge. The padding looks uneven although it is not.
Concentric corners. The gap is the same all the way round.
03Shadows and elevation
A shadow says "this surface is above that one." That is its only job. Strong, dark shadows say it too loudly, add visual noise, and make the interface look heavy. Soft shadows with low opacity do the job and then get out of the way.
0 4px 10px rgba(0,0,0,.45). Dark, short and smudgy. It reads as a heavy outline.
0 6px 18px -2px at 10%, plus a 1px contact shadow at 6%. Lift without weight.
A few rules that keep shadows consistent:
- Define elevation as tokens, three or four levels, and use them by meaning: a dropdown is always level 2, wherever it appears.
- Keep one light source. Vertical offset only, or a consistent small offset in one direction. Shadows pointing different ways are what make a screen feel "off".
- Use a negative spread to keep large blurs from bleeding sideways. It makes a soft shadow look like it comes from below, not from all around.
- Tint shadows with your ink colour instead of pure black, so they blend with warm or cool backgrounds.
| Token | Value | Use |
|---|---|---|
elevation.1 | 0 1px 2px / 6%, 0 1px 1px / 4% | Cards, list items that can be dragged |
elevation.2 | 0 6px 18px -2px / 10% | Menus, popovers, tooltips |
elevation.3 | 0 18px 40px -10px / 18% | Dialogs, drawers |
04Borders and surface contrast
There are three ways to separate a surface from its background: a border, a change of fill, or a shadow. Polished interfaces usually pick one main method per level and stick to it. Using all three on one card doubles the noise without adding information.
Borders also have an accessibility job. When a border is the only thing that shows where an input field is, it is part of how people identify the control. WCAG 2.2 success criterion 1.4.11 asks for a contrast of at least 3:1 for that kind of visual information. Decorative dividers can stay subtle. Field boundaries cannot.
Looks clean in a mock-up. On a bright screen, or for low-vision users, the field disappears.
Still quiet, now clearly a control. Dividers elsewhere on the page can stay light.
05Typography and line height
Small typographic settings decide whether text feels comfortable or cramped. The most important three are line height, line length and letter spacing.
Body line height 1.15, heading at 1.5, proportional figures that do not line up.
Body at 1.55, heading at 1.2 with slight negative tracking, tabular figures for amounts.
- Body text: line height around 1.5, and a line length of roughly 45 to 75 characters.
- Headings: tighter, around 1.1 to 1.25, because large text with body line height falls apart into separate lines.
- Letter spacing: slightly negative for large headings, slightly positive for small uppercase labels, zero for body text.
- Numbers: tabular figures in tables and amounts, so digits line up in columns.
Leave room for users who change these settings. WCAG 2.2 success criterion 1.4.12 expects content to keep working when people increase line height and letter spacing, so avoid fixed heights on text containers.
06Component states: default, hover, pressed, disabled and focus
A component is not finished when its default state looks good. Every interactive element needs an answer for each state, and the answers should follow one logic across the system. The buttons below are real. Hover, press and tab to them.
| State | What changes | Why |
|---|---|---|
| Hover | Background one step darker | Confirms the element is interactive, for pointer users only |
| Pressed | Dark fill, inset shadow, moves 1px down | Immediate feedback that the click registered |
| Focus | Visible ring outside the element | Shows keyboard users where they are; never removed |
| Disabled | Neutral fill, muted text, no hover | Shows the action exists but is unavailable |
| Loading | Label kept, spinner added, clicks blocked | Prevents double submission without layout shift |
Disabled buttons deserve a second thought. A greyed-out "Submit" with no explanation leaves people guessing what is missing. Often it is better to keep the button enabled and explain the problem when it is pressed, or to show the reason next to it.
07Accessible contrast and visible focus indicators
Polish that only works for some users is not polish. Two checks catch most problems: text contrast and focus visibility.
- Text contrast: at least 4.5:1 for body text and 3:1 for large text under WCAG 2.2 level AA. Light grey placeholder text and muted labels are the usual failures.
- Focus visible: success criterion 2.4.7 requires a visible focus indicator for keyboard users. Removing the browser outline without a replacement is one of the most common accessibility failures in polished-looking interfaces.
- Focus not hidden: criterion 2.4.11, new in WCAG 2.2, requires that the focused element is not fully hidden behind sticky headers, banners or cookie bars.
The ring itself is a design token like any other: one colour, one width, one offset, used for every focusable element. CSS :focus-visible lets you show it to keyboard users without showing it on every mouse click.
08Putting it together: one component, before and after
Here is a small settings card with every decision from this note applied. The content barely changed: one line of context and a clearer button label. Everything else is a dozen values.
The refined version uses fewer visual effects than the original, not more. That is typical. Polish usually comes from removing inconsistencies, then letting a small set of values do the work.
09An interface-quality checklist
- Every margin, padding and gap comes from the spacing scale.
- Content inside a container shares one left edge.
- Radii come from a small scale, and nested radii follow outer = inner + padding.
- Shadows use elevation tokens by meaning, with one light source.
- Each surface uses one main separation method: border, fill or shadow.
- Field boundaries and icons that carry meaning reach 3:1 contrast; text reaches 4.5:1.
- Body text has a line height around 1.5; headings are tighter; amounts use tabular figures.
- Every interactive element has hover, pressed, focus, disabled and, where relevant, loading states.
- Focus is always visible and never hidden behind sticky elements.
- Nothing on the screen uses a value that is not in the system. If it must, the system gets a new token.