How to Simplify Complex UI Designs
Problem
My dashboard was a mess. Three different CTAs competed for attention on the hero section. The sidebar had 47 navigation items. The form had 28 fields, all visible at once. Users were bouncing after 15 seconds.
I kept adding features, and each feature added buttons, options, labels, and visual noise. When I stepped back and looked at the interface, I felt overwhelmed. And I built the thing.
Here’s what my color palette looked like:
:root { --primary: #3b82f6; --secondary: #8b5cf6; --tertiary: #ec4899; --success: #22c55e; --warning: #f59e0b; --error: #ef4444; --info: #06b6d4; --accent-1: #f472b6; --accent-2: #a78bfa; --accent-3: #67e8f9; /* Plus 50 shades of gray for good measure */}And my typography:
:root { --text-xs: 0.75rem; --text-sm: 0.875rem; --text-base: 1rem; --text-lg: 1.125rem; --text-xl: 1.25rem; --text-2xl: 1.5rem; --text-3xl: 1.875rem; --text-4xl: 2.25rem; --text-5xl: 3rem; --text-6xl: 3.75rem; --text-7xl: 4.5rem; --text-8xl: 6rem; --text-9xl: 8rem;}I had 12 font sizes. I used maybe 4 of them consistently.
What happened?
I realized that complexity accumulates. Every feature adds elements. Every element competes for attention. Every option creates decision fatigue. I was adding, but I should have been subtracting.
The insight hit me: Simplicity is not about removing features. It’s about removing obstacles between users and their goals.
I audited my interface and found these sources of complexity:
- Too many elements competing for attention: 3 CTAs in the hero, 47 sidebar items, 8 notification badges
- Excessive variation: 12 font sizes, 9 colors, 6 button styles
- Information overload: Everything visible at once, no hierarchy
- Visual noise: Unnecessary borders, shadows, decorative elements
- Feature creep: Secondary actions had equal weight to primary actions
How to solve it?
I approached simplification across five dimensions: information architecture, visual, layout, interaction, and content.
1. Information Architecture: Progressive Disclosure
The biggest change was hiding complexity until needed.
Before: My settings page showed everything at once.
+--------------------------------------------------+| Settings |+--------------------------------------------------+| [Account] [Security] [Notifications] [Privacy] || [Billing] [Integrations] [API Keys] [Team] || || Email: [________________] || Password: [________________] || 2FA: [ ] Enable || Notifications: [Email] [Push] [SMS] || Privacy: [Public] [Private] [Friends Only] || Billing: [Card ****1234] [Change] || API Keys: [Key 1] [Key 2] [Generate New] || Team: [User 1] [User 2] [Invite] |+--------------------------------------------------+After: One primary action, progressive disclosure for the rest.
+--------------------------------------------------+| Settings |+--------------------------------------------------+| || Email || [[email protected]] [Change] || || > Security (password, 2FA) || > Notifications (email, push, SMS) || > Privacy & Billing || > Advanced (API keys, team) |+--------------------------------------------------+The code change was straightforward:
<!-- BEFORE: Everything visible --><div class="settings"> <div class="account">...</div> <div class="security">...</div> <div class="notifications">...</div> <div class="privacy">...</div> <div class="billing">...</div> <div class="integrations">...</div> <div class="api-keys">...</div> <div class="team">...</div></div>
<!-- AFTER: Progressive disclosure --><div class="settings"> <div class="primary"> <label>Email</label> <button>Change</button> </div>
<details> <summary>Security (password, 2FA)</summary> <!-- Hidden until expanded --> </details>
<details> <summary>Notifications (email, push, SMS)</summary> <!-- Hidden until expanded --> </details>
<!-- Rarely used sections grouped --> <details> <summary>Privacy & Billing</summary> <!-- Hidden until expanded --> </details>
<details> <summary>Advanced (API keys, team)</summary> <!-- Hidden until expanded --> </details></div>2. Visual: Reduce to Essentials
I cut my color palette to the bone:
:root { /* One primary color */ --color-primary: oklch(60% 0.15 250);
/* Neutrals for everything else */ --neutral-100: oklch(98% 0.01 250); --neutral-200: oklch(95% 0.01 250); --neutral-300: oklch(90% 0.01 250); --neutral-500: oklch(60% 0.01 250); --neutral-700: oklch(35% 0.01 250); --neutral-900: oklch(15% 0.01 250);
/* Semantic colors only for feedback */ --color-success: oklch(65% 0.2 145); --color-error: oklch(60% 0.25 25);}That’s it. One primary color, neutrals, and two semantic colors. No secondary, no tertiary, no accent palette.
For typography, I went from 12 sizes to 4:
:root { /* Four sizes, that's it */ --text-sm: 0.875rem; /* Captions, labels */ --text-base: 1rem; /* Body text */ --text-lg: 1.25rem; /* Subheadings */ --text-xl: 2rem; /* Headings */}3. Layout: Linear Flow
I removed sidebars. I removed multi-column layouts. I removed floating panels.
Before: Three-column layout with sidebar.
+----------+------------------------+----------+| | | || Sidebar | Main Content | Right || | | Panel || 47 items | competing with | || | both panels | ads & || every | | CTAs || visible | | || | | |+----------+------------------------+----------+After: Single-column, generous white space.
+------------------------------------------+| || Main Content || || Nothing competing. Clear hierarchy. || || Secondary actions at the bottom. || |+------------------------------------------+The CSS for linear flow:
/* BEFORE: Complex grid */.layout { display: grid; grid-template-columns: 240px 1fr 300px; gap: 1rem;}
/* AFTER: Single column */.layout { max-width: 65ch; margin: 0 auto; padding: 2rem;}
/* Secondary actions, if needed */.secondary { margin-top: 4rem; padding-top: 2rem; border-top: 1px solid var(--neutral-200);}4. Interaction: Fewer Choices
Every additional choice creates decision fatigue. I reduced choices ruthlessly.
Before: 5 buttons with equal visual weight.
<div class="actions"> <button class="primary">Save Draft</button> <button class="primary">Publish Now</button> <button class="secondary">Schedule</button> <button class="secondary">Preview</button> <button class="tertiary">Cancel</button></div>After: ONE primary action, secondary actions as text links.
<div class="actions"> <button class="primary">Publish</button> <span class="secondary-actions"> <a href="#">Save draft</a> <a href="#">Schedule</a> <a href="#">Preview</a> </span></div>The styling:
.primary { background: var(--color-primary); color: white; padding: 0.75rem 2rem; border-radius: 0.5rem; font-weight: 600;}
.secondary-actions a { color: var(--neutral-500); margin-left: 1rem; font-size: var(--text-sm);}
.secondary-actions a:hover { color: var(--neutral-700);}5. Content: Cut in Half, Then Half Again
I wrote my error message:
“We’re sorry, but there seems to be an issue with your request. Please try again later, or contact support if the problem persists.”
Then I cut it in half:
“There was an issue with your request. Please try again or contact support.”
Then in half again:
“Something went wrong. Please try again.”
And one more time:
“Please try again.”
The original was 27 words. The final version is 3 words. Same information, no fluff.
The reason
Why does this work? Three principles:
1. Every element must justify its existence. If I can’t explain why an element helps users achieve their goal, I remove it. Decorations don’t justify themselves. “It looks nice” is not a justification.
2. Progressive disclosure reduces cognitive load. Users don’t need to see everything at once. Show them what they need now. Hide the rest behind clear entry points.
3. Constraints create clarity. By limiting colors, sizes, and choices, I force myself to make clearer decisions. 4 font sizes mean I have to use hierarchy intentionally. 1 primary color means I have to know what’s actually important.
What to avoid
Simplification has pitfalls:
Don’t remove necessary functionality. A calculator that only adds is simple but useless. Complexity is sometimes required. The goal is to make complexity accessible, not to remove it.
Don’t sacrifice accessibility. High contrast, clear labels, keyboard navigation. A minimal interface that’s hard to use is a failure.
Don’t make things unclear. Mystery meat navigation is not minimalism. An icon without a label that users have to guess is bad design, not clean design.
Don’t remove information users need. I once hid the file size in an upload interface to “simplify.” Users couldn’t tell if their file was too large. That’s not simplification, that’s broken design.
The result
After applying these changes, my dashboard went from:
- 47 sidebar items to 6 primary navigation items
- 12 font sizes to 4
- 9 colors to 1 primary + neutrals
- 3 competing CTAs to 1 primary action
- 28 form fields visible at once to 4 primary fields + progressive disclosure
The codebase got smaller. The interface got clearer. Users stopped bouncing.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments