devbook
Frontend Development

Design Engineering

The intersection of design and engineering, building beautiful experiences

Design Engineering

Design engineering sits at the intersection of design and development, focusing on crafting exceptional user experiences through code.

Core Principles

Design Thinking

  • Empathy with users
  • Define problems clearly
  • Ideate multiple solutions
  • Prototype quickly
  • Test and iterate

Engineering Excellence

  • Clean, maintainable code
  • Performance optimization
  • Accessibility standards
  • Cross-browser compatibility

CSS & Styling

Modern CSS Techniques

CSS Custom Properties

:root {
  --color-primary: #0070f3;
  --color-secondary: #7928ca;
  --spacing-unit: 8px;
  --border-radius: 12px;
  
  /* Responsive values */
  --container-width: min(1200px, 100% - 2rem);
}

.button {
  background: var(--color-primary);
  padding: calc(var(--spacing-unit) * 2);
  border-radius: var(--border-radius);
}

Grid & Flexbox

/* Modern grid layout */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--spacing-unit);
}

/* Flexbox utilities */
.flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

Container Queries

@container (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: 1fr 2fr;
  }
}

Tailwind CSS Patterns

// Composition
const buttonClasses = cn(
  'px-4 py-2 rounded-lg font-medium transition-colors',
  'hover:bg-opacity-90 active:scale-95',
  'focus:outline-none focus:ring-2 focus:ring-offset-2',
  variant === 'primary' && 'bg-blue-600 text-white',
  variant === 'secondary' && 'bg-gray-200 text-gray-900',
  disabled && 'opacity-50 cursor-not-allowed'
)

// Dark mode
<div className="bg-white dark:bg-gray-900 text-gray-900 dark:text-white">
  {/* Content */}
</div>

// Responsive design
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
  {/* Items */}
</div>

Animation & Motion

Framer Motion

import { motion } from 'framer-motion'

// Basic animation
<motion.div
  initial={{ opacity: 0, y: 20 }}
  animate={{ opacity: 1, y: 0 }}
  transition={{ duration: 0.5 }}
>
  Content
</motion.div>

// Variants
const variants = {
  hidden: { opacity: 0, scale: 0.8 },
  visible: { 
    opacity: 1, 
    scale: 1,
    transition: {
      duration: 0.4,
      ease: [0.4, 0, 0.2, 1]
    }
  }
}

<motion.div
  variants={variants}
  initial="hidden"
  animate="visible"
>
  Content
</motion.div>

// Gesture animations
<motion.button
  whileHover={{ scale: 1.05 }}
  whileTap={{ scale: 0.95 }}
  transition={{ type: 'spring', stiffness: 400, damping: 17 }}
>
  Click me
</motion.button>

CSS Animations

/* Smooth transitions */
.card {
  transition: transform 200ms ease, box-shadow 200ms ease;
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
}

/* Keyframe animations */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.animated {
  animation: fadeInUp 0.5s ease-out;
}

Micro-interactions

Loading States

function Button({ isLoading, children, ...props }: ButtonProps) {
  return (
    <button disabled={isLoading} {...props}>
      {isLoading ? (
        <span className="flex items-center gap-2">
          <Spinner />
          Loading...
        </span>
      ) : (
        children
      )}
    </button>
  )
}

Toast Notifications

import { toast } from 'sonner'

// Success toast
toast.success('Changes saved successfully')

// Error toast
toast.error('Something went wrong')

// Custom toast
toast.custom((t) => (
  <div className="bg-white rounded-lg shadow-lg p-4">
    <h3 className="font-semibold">Custom Notification</h3>
    <p className="text-sm text-gray-600">With custom content</p>
  </div>
))

Skeleton Screens

function Skeleton() {
  return (
    <div className="animate-pulse">
      <div className="h-4 bg-gray-200 rounded w-3/4 mb-4" />
      <div className="h-4 bg-gray-200 rounded w-1/2 mb-4" />
      <div className="h-32 bg-gray-200 rounded" />
    </div>
  )
}

Responsive Design

Mobile-First Approach

// Tailwind mobile-first
<div className="
  p-4 
  md:p-6 
  lg:p-8
  text-sm 
  md:text-base 
  lg:text-lg
">
  Content
</div>

// CSS mobile-first
@media (min-width: 768px) {
  .container {
    padding: 2rem;
  }
}

@media (min-width: 1024px) {
  .container {
    padding: 3rem;
  }
}

Fluid Typography

/* Clamp for responsive sizing */
h1 {
  font-size: clamp(2rem, 5vw, 4rem);
}

p {
  font-size: clamp(1rem, 2vw, 1.125rem);
}

Component Design

Atomic Design

Atoms: Button, Input, Label

Molecules: FormField, SearchBar

Organisms: LoginForm, Header

Templates: DashboardLayout

Pages: Dashboard

Compound Components

function Card({ children }: { children: React.ReactNode }) {
  return <div className="card">{children}</div>
}

Card.Header = function CardHeader({ children }: { children: React.ReactNode }) {
  return <div className="card-header">{children}</div>
}

Card.Body = function CardBody({ children }: { children: React.ReactNode }) {
  return <div className="card-body">{children}</div>
}

// Usage
<Card>
  <Card.Header>Title</Card.Header>
  <Card.Body>Content</Card.Body>
</Card>

Accessibility (a11y)

Semantic HTML

// ✅ Use semantic elements
<nav>
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
  </ul>
</nav>

<article>
  <h1>Article Title</h1>
  <p>Content...</p>
</article>

// ❌ Avoid div soup
<div>
  <div>
    <div>Home</div>
    <div>About</div>
  </div>
</div>

ARIA Attributes

<button
  aria-label="Close modal"
  aria-pressed={isPressed}
  aria-expanded={isExpanded}
  aria-controls="menu"
>
  <Icon />
</button>

<div role="alert" aria-live="polite">
  {errorMessage}
</div>

Keyboard Navigation

function Menu() {
  const handleKeyDown = (e: React.KeyboardEvent) => {
    switch (e.key) {
      case 'ArrowDown':
        focusNext()
        break
      case 'ArrowUp':
        focusPrevious()
        break
      case 'Escape':
        closeMenu()
        break
    }
  }
  
  return (
    <div role="menu" onKeyDown={handleKeyDown}>
      {/* Menu items */}
    </div>
  )
}

Performance

Image Optimization

import Image from 'next/image'

<Image
  src="/hero.jpg"
  alt="Hero image"
  width={1200}
  height={600}
  priority
  placeholder="blur"
  blurDataURL="data:image/..."
  sizes="(max-width: 768px) 100vw, 50vw"
/>

Code Splitting

import dynamic from 'next/dynamic'

const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <Skeleton />,
  ssr: false
})

Virtualization

import { useVirtualizer } from '@tanstack/react-virtual'

function VirtualList({ items }: { items: string[] }) {
  const parentRef = useRef<HTMLDivElement>(null)
  
  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 50
  })
  
  return (
    <div ref={parentRef} className="h-screen overflow-auto">
      <div
        style={{
          height: `${virtualizer.getTotalSize()}px`,
          position: 'relative'
        }}
      >
        {virtualizer.getVirtualItems().map(virtualItem => (
          <div
            key={virtualItem.key}
            style={{
              position: 'absolute',
              top: 0,
              left: 0,
              width: '100%',
              transform: `translateY(${virtualItem.start}px)`
            }}
          >
            {items[virtualItem.index]}
          </div>
        ))}
      </div>
    </div>
  )
}

Design Tokens

Token Structure

export const tokens = {
  colors: {
    brand: {
      primary: '#0070f3',
      secondary: '#7928ca',
      accent: '#ff0080'
    },
    semantic: {
      success: '#00d9a3',
      warning: '#f5a623',
      error: '#ff4444',
      info: '#0070f3'
    },
    neutral: {
      50: '#fafafa',
      100: '#f5f5f5',
      // ...
      900: '#171717'
    }
  },
  spacing: {
    xs: '4px',
    sm: '8px',
    md: '16px',
    lg: '24px',
    xl: '32px',
    '2xl': '48px'
  },
  typography: {
    fontFamily: {
      sans: 'Inter, system-ui, sans-serif',
      mono: 'Fira Code, monospace'
    },
    fontSize: {
      xs: '12px',
      sm: '14px',
      base: '16px',
      lg: '18px',
      xl: '20px',
      '2xl': '24px',
      '3xl': '30px',
      '4xl': '36px'
    },
    fontWeight: {
      normal: 400,
      medium: 500,
      semibold: 600,
      bold: 700
    }
  }
} as const

Tools & Resources

  • Figma: Design and prototyping
  • Framer Motion: React animations
  • Radix UI: Unstyled components
  • Tailwind CSS: Utility-first CSS
  • Shadcn UI: Component library
  • React Aria: Accessibility primitives
  • Storybook: Component development

Best Practices

  • Design with real content
  • Test on real devices
  • Prioritize performance
  • Build accessible by default
  • Use consistent spacing
  • Maintain visual hierarchy
  • Consider dark mode
  • Optimize for touch
  • Progressive enhancement