Mockup to Markup
Convert a static design mockup — a screenshot, an exported image, or a rough sketch — into semantic, responsive HTML and CSS. The method is layout-first: name the regions, get the boxes right, then apply typography and color, and only then chase pixel details. That order matters because the most common failure in mockup conversion is a set of pixel-perfect fragments floating in a broken layout.
When to use this skill
- The user shares an image of a design and asks for HTML and CSS that match it
- A hand-drawn wireframe or whiteboard photo needs to become a working page
- An existing page must be rebuilt against an updated mockup
- The user says "make this real", "code this up", or "build this screen" about a static visual
- A design handoff arrives as flat images with no written specs
Before you start
Confirm four things. If the user cannot answer, state your assumptions in one visible block and proceed:
- Is this a full page or a component destined for an existing page?
- What viewport width does the mockup represent, and which breakpoints must exist?
- Are the exact fonts available, or should visually close system stacks substitute?
- Is there an existing stylesheet or design system the output must plug into?
Workflow
- Inventory the mockup before writing any code. List every distinct region top to bottom — header, hero, card grid, sidebar, footer — and note repeated patterns. Three identical cards means one component written once, not three blocks of markup.
- Write the semantic skeleton next. Map each region to the most specific element that fits: nav, main, section, article, aside, figure. Use div only when nothing semantic applies. No classes yet. Read the bare document top to bottom and confirm the outline makes sense unstyled.
- Choose a layout mechanism per region, never one for the whole page:
- Grid for two-dimensional areas: card grids, dashboards, image walls
- Flexbox for one-dimensional rows and stacks: navbars, button rows, media objects
- Normal flow for prose; never force running text into a grid
- Extract the design constants from the image: type scale, spacing rhythm, corner radii, border weights, and the full color set. Define them as CSS custom properties in :root before styling any region. If the mockup uses six near-identical grays, collapse them to two or three and say that you did.
- Build mobile-first even when the mockup is desktop-only. Write the narrow layout, then add the fewest breakpoints that reproduce the mockup at its shown width. If a mobile layout is implied but not shown, propose one rather than guessing silently.
- Style region by region in source order, comparing against the mockup after each. Match hierarchy first — relative size, weight, spacing — and exact values second.
- Finish with a fidelity pass: alignment edges, consistent gaps, and the states the mockup implies but cannot show — hover, focus-visible, disabled, empty. A flat image never shows keyboard focus; the page must have it anyway.
Output format
Deliver a single self-contained HTML file with an embedded style block unless the project structure dictates otherwise. Precede the code with the region inventory — one line per region naming the chosen element and layout mechanism — so decisions can be reviewed before the markup is read.
Quality bar
- Every color, font size, and spacing value used more than once is a custom property
- The document outline reads sensibly with CSS disabled
- Interactive elements are real buttons and anchors, never clickable divs
- Content images carry alt text; purely decorative images carry empty alt
- No horizontal scroll at a 320px viewport width
- The layout survives 200% text zoom without overlap or clipped content
Common failure modes
- Measuring pixels before naming regions, which ends in brittle absolute positioning
- One giant grid for the whole page instead of a mechanism per region
- Magic numbers that silently encode the mockup's exact content length
- Skipping hover and focus states because the flat image never showed them
- Matching the desktop image perfectly while the narrow layout was never designed at all
Worked example: region inventory
For a typical landing-page mockup, the inventory that precedes the code might read:
header — logo left, nav links right — flex row, space-between
hero — heading, subhead, one CTA — centered column, max-width 60ch
features — three equal cards — grid, auto-fit minmax(240px, 1fr)
testimonial — quote with avatar — flex row, fixed-width avatar
footer — three link columns, one on mobile — grid collapsing below 600px
Five lines like these settle most build decisions before the first tag is written.