Ulric
Book a call

Eugene, Oregon · one person, whole builds

Insights

Wireframes that survive contact with the build

Wireframes that survive contact with the build

A wireframe gets approved in a meeting, and then it quietly loses an argument to the browser. Nobody announces it. The build starts, a constraint nobody drew turns up in the markup, the layout moves to accommodate it, and by launch the drawing and the shipped page agree on the order of the sections and almost nothing else. The wireframing process I use now exists to stop that, and a surprising amount of it is about which decisions I refuse to make.

What is a wireframe actually supposed to carry?

Decisions that get more expensive the longer you wait. That is the whole job.

A page holds maybe a hundred decisions and only eight or nine of them harden as the build goes on: what the page is for, the order a reader meets things in, where they arrived from and where they go next, what is a link and what is a control, and every condition the data can actually be in. Change one of those in week three and you are rebuilding. The rest, typeface pairing, the spacing scale, the hue of the quiet text, the transitions, is a restyle, and a restyle in week three costs an afternoon.

So there is one test, applied to every element I am tempted to draw. If this changes later, is it a rebuild or a restyle? Rebuild goes in the wireframe. Restyle stays out on purpose, and leaving it out is the active part, not the lazy part.

Why does an approved wireframe get ignored during the build?

Because the build meets constraints the drawing could not express, and once it has broken the drawing once, it stops consulting it.

Here is a small one from this site. The post list on /insights is a row: thumbnail, date, title, teaser, and a strip of tag chips along the bottom. The whole row is a link to the post. The chips are also links, to tag archives. Drawn as boxes, that is a perfectly reasonable component. Built as HTML, it is not a thing that exists. This is the comment sitting at the top of the partial that renders it:

The row is a whole-row link, so the tag chips cannot live inside it: an anchor inside an anchor is invalid and browsers silently unnest it, which breaks the chips. They sit in a sibling element under the same wrapper.

The fix was structural, not cosmetic. The tag strip moved out of the anchor into a sibling, and a wrapper element took over the hairline between rows, because the anchor no longer spans the whole thing:

<article class="post-item">
  <a class="post-row" href="/insights/..."> thumb, date, title, teaser </a>
  <ul class="row-tags"> chips </ul>   <!-- outside the anchor, deliberately -->
</article>

The visible design did not change at all. The markup and the CSS both did. And no browser tells you: it unnests the anchor in silence and renders something close enough that you might ship it. A wireframe that says "chips inside the clickable card" is not wrong as a picture. It is wrong as a contract, and the difference only shows up in HTML.

Which states does a wireframe have to show?

Three that a mockup almost never includes: empty, error, and too long.

Empty first. Kate Kaplan made the case for it at Nielsen Norman Group back in 2021, in Designing Empty States in Complex Applications: "Empty states provide opportunities for designers to communicate system status, increase learnability of the system, and deliver direct pathways for key tasks." In that row list, the empty state is one line of template:

<?php if (!$posts): ?><p class="lede">First notes coming soon.</p><?php endif; ?>

There is a smaller empty state nested inside it that matters more, because it fires every week. The thumbnail is optional. Three published posts have no teaser image yet, so their rows render a spacer instead of a picture and the grid closes up behind it. The first version of that was one line of CSS, and I had drawn the state without drawing its constraint:

.post-row:has(.thumb-none){grid-template-columns:1fr}

That line is the only thing keeping those rows readable, and it hangs off a selector that has no fallback: when :has() is unsupported the whole rule drops and the row keeps the 88 pixel thumbnail track with nothing in it. I measured the cost by removing the rule, which is exactly what an older browser does to it. At a 390 pixel width the text column went from 342 pixels to 88, and the row grew from 228 pixels tall to 683. That is not a degraded state, it is a column of one-word lines. PHP already knows whether a post has a teaser image, so the constraint moved into the markup where it cannot silently vanish. It went in at 3:46 one morning and came back out at 4:33 the same morning:

<a class="post-row<?= $hasThumb ? '' : ' no-thumb' ?>" href="/insights/...">

.post-row .thumb-none{display:none}
/* no thumbnail: the text spans the row rather than leaving a gap. Driven by
   a PHP-emitted class, not :has() */
.post-row.no-thumb{grid-template-columns:1fr}

Nothing about the second version is clever, and that is the point: a state the server already knows should not be re-derived by the stylesheet at read time. It exists because at some point I asked what the row does when the picture is missing, and the answer had to be a decision instead of a gap. I have written before about a page that said "48 photos" over a grid of blank tiles, which is the same failure one layer down: a state nobody designed, reached by code that trusted a receipt instead of checking the artifact.

Error is the state with the worst record in the field. Baymard Institute's checkout benchmark, updated in November 2025 and built on more than 41,000 manually scored checkout metrics, files adaptive validation messages under "Improve Validation Errors with Adaptive Messages (94% Don't)". Ninety-four percent of the sites they score do not change the message to match the rule that actually failed. The wireframe move is small: draw the field with the message under it and write the message. If you cannot write it, you do not understand the rule yet.

Too long is the one that breaks layouts outright. The W3C's internationalization guidance carries a table borrowed from IBM's global design guidelines: an English string of ten characters or fewer averages 200 to 300 percent expansion once translated, and the shorter the source string, the worse the ratio. You do not need a second language for it to bite, either. Real data is longer and stranger than sample data, always.

On 13 August 2026 I ran a mobile audit across three sites at a 390 by 664 WebKit viewport and hit the same trap in two of them the same day. A bare 1fr grid track floors at min-content, so one wide child silently pushes the whole grid past the phone viewport, and if an ancestor clips, the page does not even scroll. It just renders cut off. The fix is always minmax(0,1fr), plus overflow-wrap:anywhere on strings that cannot break. The row list carries the same guard in one declaration, .row-main{min-width:0}. I knew to put it there only because the failure had been measured from outside the page rather than reported by the page, which is the same verify step every automated loop I run lives on.

A mockup with a nine-word title and a lorem paragraph passes all three of those.

A wireframe of one list row drawn five times in the Ulric palette. State one, loaded, shows an image box, a date bar, two title bars, two teaser bars and three tag chips, labeled the only state in the comp. State two, empty, shows a single italic line reading First notes coming soon. State three, no image, drops the thumbnail and lets the text bars span the full width. State four, too long, shows a title running four bars deep inside the column without pushing the grid. State five, error, shows an email field outlined in terracotta with the message add the part after the at sign, then submit again.
The same component in five conditions. Only the first one gets drawn, and the other four are where layouts break in production.

Which width should you wireframe at?

The one where your layout actually changes, which is a number you can read straight out of your own stylesheet.

This site's theme CSS is 2,015 lines on the day I write this, 4 September 2026, and it has plenty of media queries, but only a couple carry real weight: max-width:700px and max-width:719px do most of the restacking, and the content column tops out at 1120. A wireframe drawn 1,440 pixels across is therefore a drawing of a state the design barely has. I draw at 390, and at the widest the container will ever be, and I skip everything in between, because in between the CSS is already doing the work.

Drawing at the true size is easy if the frames are HTML. On a social launch plan I built for a client, the wireframes were plain boxes with the real shape locked in:

.wire      { border: 1.5px dashed #C9BEB4; padding: 14px;
             display: flex; flex-direction: column; gap: 8px; }
.wire.r916 { aspect-ratio: 9 / 16; max-width: 280px; }
.wire.r45  { aspect-ratio: 4 / 5;  max-width: 300px; }
.wire .push{ margin-top: auto; }

Two things there are the entire technique. aspect-ratio makes the frame the true shape of the surface, so a line that does not fit does not fit in the wireframe either. And .push pins the closing line to the bottom of the frame, which turns vertical placement into a decision rather than a by-product of how long the text happened to be. Real copy went in the boxes, never lorem. That is the diagnosis Evan Sunwall wrote up for NN/g in May 2024 when he proposed promptframes: "placeholder content (especially the notorious lorem ipsum) can be a barrier to gathering insightful feedback from users and stakeholders." His answer is to fill the frames with generative AI. Mine is usually to write the real line. Either way, the container was never the thing being evaluated.

Does low fidelity really find fewer problems?

The best controlled experiment I can find says no, and it is 24 years old, which is worth saying out loud before anyone leans on it.

Miriam Walker, Leila Takayama and James Landay ran a two-by-two at Berkeley: low- and high-fidelity website prototypes, on paper and on a computer, 28 participants, published at HFES 2002. Participants made 1,270 comments in total, an average of 45 each, and each identified 34.6 distinct usability issues out of 169 found across the study. Their abstract:

We found that low- and high-fidelity prototypes are equally good at uncovering usability issues. Usability testing results were also found to be independent of medium, despite differences in interaction style.

The nuance every summary of that paper drops sits in the results section. The number of issues did not differ by fidelity. The types did, at chi-square 30.70, p < 0.01, and the authors say plainly that their analysis cannot attribute the difference to any particular type. So the finding is not "fidelity does not matter." It is closer to "both find about as many problems, and not the same problems," which argues for a little of each rather than for picking a side. Read the paper itself: the prepress PDF is on Takayama's site.

Now the number I could not use. A line that turns up all over the place says teams who validate across all fidelity levels see "37% fewer post-launch usability issues," attributed to Nielsen Norman Group. I went looking. The only source I can reach is a prototyping tool's blog post from April 2025 that names the group and links to nothing, and I cannot find the figure in anything NN/g has published. So it does not ship here. If you have seen it on a slide, that is where it came from.

What has changed since 2002 is the price, not the finding. In the July issue of ACM Interactions, posted online in June, Christopher Hundhausen made the argument in his title: "Rethinking Prototype Fidelity in the Age of Generative AI: When High-Fidelity Becomes Cheap, It's Time to Revisit Our Foundational Design Wisdom" (volume 33, issue 4). The full text sits behind ACM's paywall and I only reached the title and the metadata, so I will not put words in his mouth. The premise needs no help: the case for low fidelity was always partly economic, and that half of it weakens every quarter.

What should a wireframe deliberately leave undecided?

Everything a later change would only restyle. Holding that line is harder than drawing the boxes.

I spent a decade in mental health, most recently as a licensed professional counselor, before I built full time, and the piece of that work that transfers most directly is intake. In an intake you are not there to solve the first thing the person says. The first thing is usually a symptom, or just the safest thing to open with, and if you start solving it you can spend months on the wrong problem while both of you feel productive the entire time. So you ask, you say it back in their own words, and you keep the formulation open until it has been earned.

Wireframing is that same act performed on a page. A client says the button needs to be bigger. Underneath it, most of the time, is that nobody can tell what the page is for, which is a hierarchy problem wearing a button costume. Leaving the button size undecided while you settle what the page is for is the difference between a wireframe that carries information into the build and one that just ratifies the first idea in the room. Deciding the hue of a chip in week one buys nothing and hands you something to defend in week four.

Motion sits on the right-hand side of that split too. Scroll-scrubbed video is something I add to a layout that already works, never something I design a layout around, because a layout organized around an effect has no fallback when the effect is unavailable.

A two-column split headed what a wireframe decides and what it refuses to. The test across the top asks: if this changes in week three, is it a rebuild or a restyle. The decide now column lists the one thing the page is for, the order of the information, where the reader arrives from and leaves to, every state including empty error too long and loading, what is a link and what is a control, and the width the layout actually changes at. The leave undecided column lists typeface pairing and type scale, the spacing scale, color past contrast, motion and transitions, illustration and image crops, and final copy past the lengths it must survive.
The split I actually use. Left-hand items cost a rebuild if they move late; right-hand items cost an afternoon.

When is the right move to skip the wireframe entirely?

When you are the person who will build it, the design system already exists, and the layout is a pattern you have shipped before. For a solo builder that is often all three at once, and the honest answer then is to open an editor.

HTML at 390 pixels wide is a wireframe that runs. It cannot lie about text wrapping, or about whether a tap target clears 44 pixels, or about a link inside a link, and it is the artifact you were going to have to produce anyway. Where I get this wrong is by starting high fidelity with nothing underneath it, which is the first thing the design rules I keep in my project files are written to catch: declare the type scale, the background colors, the layout rhythm and the section-header pattern before placing anything, because "building from your memory of what the app roughly looks like produces generic look-alikes."

Three conditions send me back to a real wireframe:

  • Someone else has to agree before I spend the build. A drawing is cheap to argue with. A finished-looking page is a thing people react to rather than interrogate.
  • The flow itself is undecided, meaning I can name two plausible orders for the same information and cannot yet say which is better.
  • I can feel myself getting attached. A page I have already styled is a page I will defend. I have no measurement of my own on that effect, and I am not going to dress up a hunch as evidence: it is a claim I believe from watching my own behavior, not from data.

The rest of the time my wireframe is a paragraph in a text file. What the page is for, the order, the states, the two widths. Then markup.

One state on that row list is still unsettled. Three posts have no teaser image, so .no-thumb collapses their rows to full width, and honestly they read a little better than the ones with pictures. I do not know yet whether that is the design or a hole I have not looked at hard enough. The alternative is to refuse to publish a post without a teaser image, which converts a layout state into an editorial rule. Until I pick one, that branch of the wireframe stays in pencil.

Common questions

What should a wireframe decide, and what should it leave open?

One test settles it: if this changes in week three, is it a rebuild or a restyle? Rebuild items belong in the wireframe. That means what the page is for, the order of the information, where the reader arrives from and leaves to, what is a link versus a control, every state the data can be in, and the width the layout really changes at. Restyle items stay out on purpose: typeface pairing, the spacing scale, color past contrast, motion, image crops, and final copy past the lengths it has to survive.

Which UI states should a wireframe include?

Empty, error and too long, at minimum, plus loading if content arrives asynchronously. Those are the ones a mockup of the happy path never shows and the ones that break layouts in production. For error states specifically, Baymard Institute's checkout benchmark (updated November 2025) reports that 94% of the sites it scores do not adapt the validation message to the rule that failed.

Is low-fidelity wireframing as effective as high-fidelity prototyping?

On the number of usability issues found, the evidence says yes, and the strongest experiment is old. Walker, Takayama and Landay tested low and high fidelity on paper and on computer with 28 participants at HFES 2002 and found no significant difference in the number or severity of issues. The types of issues did differ by fidelity (chi-square 30.70, p < 0.01), so the honest reading is "as many problems, not the same problems."

When should you skip wireframes and go straight to HTML?

When you are the person who will build it, the design system already exists, and the layout is a pattern you have shipped before. HTML at a real phone width is a wireframe that runs, and it cannot lie about wrapping, tap targets or invalid nesting. Go back to a wireframe when someone else must agree before you spend the build, when you can name two plausible orders for the same information, or when you can feel yourself getting attached to a page you already styled.

What screen width should you wireframe at?

The widths where your own CSS changes, read out of your stylesheet rather than guessed. On this site that is roughly 390 pixels and the maximum container width, because the theme does almost all of its restacking around 700 to 719 pixels and tops out at 1120. Wireframing at 1,440 pixels across draws a state the design barely has.

Related

← All insights