M. MAUN STUDIO
Let's Work Together
All posts
Blog4 min read

Web Design for Engineers Who Don't Design

Practical web design principles that make sense to engineers. Less aesthetics, more systems thinking about layout, typography, and user interfaces.

Web Design for Engineers Who Don't Design

The Engineer's Design Problem

Most engineers I've worked with can build complex distributed systems but freeze when asked to design a simple form. The problem isn't ability—it's that design is taught as intuition and taste when it's actually a set of constraints and systems.

I'm not a designer. But I've shipped enough interfaces to know that good web design follows patterns you can learn and apply systematically. Here's what actually matters when you're building for the web.

Layout as a Grid System

Forget pixel-perfect positioning. Modern web design is constraint-based layout using flexbox and grid.

.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
}

This snippet does something simple: create as many columns as fit, each at least 300px wide, with consistent spacing. The browser handles the math. You define the constraints.

Think of layout in terms of:

  • Container max-width: 65-75 characters for reading, ~1200px for dashboards
  • Spacing scale: use multiples of 4 or 8 (8px, 16px, 24px, 32px...)
  • Breakpoints: mobile (<640px), tablet (640-1024px), desktop (>1024px)

Don't position things absolutely unless you're building a canvas tool or game. Let the layout system work.

Typography Is 95% of Design

A well-set page with good typography and no other styling looks professional. A poorly-set page with fancy graphics looks amateur.

Start here:

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  color: #333;
}

h1 { font-size: 2.5rem; line-height: 1.2; margin-bottom: 1rem; }
h2 { font-size: 2rem; line-height: 1.3; margin-top: 2rem; }
p { margin-bottom: 1rem; max-width: 65ch; }

Key principles:

  • Line height: 1.5-1.6 for body text, tighter (1.2-1.3) for headings
  • Line length: 45-75 characters per line for readability
  • Scale: each heading level should be noticeably different (1.25-1.5x ratio)
  • System fonts: they're free, fast, and familiar

If you want to use custom fonts, load them properly:

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap">

And limit yourself to 2-3 weights maximum. Every weight is another network request.

Color: Work in HSL, Not Hex

Hex colors are how computers store RGB values. HSL (Hue, Saturation, Lightness) is how humans think about color.

:root {
  --primary-hue: 210;
  --primary: hsl(var(--primary-hue), 70%, 50%);
  --primary-dark: hsl(var(--primary-hue), 70%, 35%);
  --primary-light: hsl(var(--primary-hue), 70%, 95%);
}

Now you can derive hover states, backgrounds, and borders by adjusting lightness while keeping hue consistent. This creates visual harmony without a design system.

For text contrast, aim for 4.5:1 ratio minimum (7:1 is better). Use a contrast checker—don't guess.

Whitespace Is a Feature, Not a Bug

Beginners fill every pixel. Experienced designers use emptiness deliberately.

Good spacing creates visual hierarchy:

  • Related items: 0.5-1rem apart
  • Separate sections: 2-4rem apart
  • Major page divisions: 4-8rem apart
section + section {
  margin-top: 4rem;
}

.card {
  padding: 2rem;
}

.card > * + * {
  margin-top: 1rem;
}

That last rule (the "lobotomized owl" selector) adds spacing between any adjacent children. It's a surprisingly effective default.

Interaction States Matter

Every interactive element needs at least three states: default, hover, and active/focus.

.button {
  background: var(--primary);
  transition: all 0.2s ease;
}

.button:hover {
  background: var(--primary-dark);
  transform: translateY(-1px);
}

.button:active {
  transform: translateY(0);
}

.button:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 2px;
}

The focus state is required for accessibility. Never set outline: none without a visible replacement.

Responsive by Default

Mobile isn't an afterthought—it's often the majority of traffic. Design mobile-first, then enhance.

/* Mobile-first base */
.nav { flex-direction: column; }

/* Desktop enhancement */
@media (min-width: 768px) {
  .nav { flex-direction: row; }
}

This is easier than trying to undo desktop styles for mobile. Start constrained, then expand.

Test on real devices, not just browser DevTools. Touch targets need to be at least 44x44px. Hamburger menus are fine.

Tools That Actually Help

Skip Photoshop. Modern web design happens in the browser or in tools like Figma.

What I actually use:

  • Browser DevTools: live CSS editing, layout debugging
  • Figma: when I need to share mockups with actual designers
  • Can I Use: checking browser support before using new features
  • WebAIM Contrast Checker: ensuring text is readable

Most of the time, I write HTML and CSS directly. The feedback loop is faster than any design tool.

The Real Secret

Good web design isn't about having taste—it's about having constraints. Pick a spacing scale and stick to it. Choose two fonts maximum. Establish a color palette and derive everything from it. Use a consistent layout grid.

Within tight constraints, most decisions make themselves. You're not paralyzed by infinite options because you've already eliminated 95% of them.

The websites you think look "designed" are usually just consistently applied systems. Build the system, then fill in the content. That's engineering thinking applied to design.

And when you really need something custom? That's when you hire a designer. But for most internal tools, documentation sites, and portfolio pages, these principles will get you 90% of the way there.