Visual hierarchy is using size, weight, color, and spacing to signal what matters most on a screen, in what order. A page where every element is the same size and weight forces the user to figure out priority themselves — a page with clear hierarchy tells them immediately where to look first.
.headline { font-size: 32px; font-weight: 700; }
.subheading { font-size: 18px; font-weight: 400; color: #666; }
.body-text { font-size: 15px; font-weight: 400; color: #333; }
This isn't decoration — it's communication. A user scanning a page (which is most users, most of the time) relies on hierarchy to find what they came for without reading every word.
Every user action — a click, a form submission, a drag — should produce some visible response, even if the underlying operation takes time. A button that shows no change when clicked leaves the user wondering whether it registered, and often leads to a frustrated second (or third) click.
<button onClick={handleSubmit} disabled={isSubmitting}>
{isSubmitting ? 'Saving...' : 'Save'}
</button>
A loading state, a disabled button during submission, and a success or error message afterward are the minimum feedback loop for any action that takes noticeable time.
If a primary action button is blue and rounded on one screen, it should be blue and rounded everywhere — a button that looks different in different places forces the user to relearn the interface repeatedly instead of building confidence in it. A shared design system or component library is what makes this consistency achievable at scale rather than relying on individual developers remembering every convention.
A button should look clickable; a text input should look like something you type into. When an interactive element doesn't visually signal that it's interactive — flat text with no visual distinction, styled like a clickable link — users miss it entirely, no matter how logically it's placed.
A developer implementing a design often makes dozens of small decisions a designer's mockup didn't specify exactly — hover states, error states, loading states, edge cases with very long or very short text. Understanding these principles is what lets a developer fill those gaps in a way that's still coherent with the overall design intent, rather than accidentally undermining it.
Comments