How to Build Bad

A field guide to the quiet failures that ship with every other website.

Sometimes the build isn't the problem.

Plot twist: a perfectly built site can drift into chaos after launch. An image gets uploaded without alt text. A heading gets picked because it's the right font size, not the right level. A screenshot of text replaces actual text because it was faster. Every link on the page says "Click here" because nobody mentioned that was a problem.

None of this is malicious. It's just what happens when the tools make it easy to do the wrong thing and nobody's been shown what "right" looks like. The CMS gave everyone a heading dropdown. They used it as a font-size picker. That's not a bug—it's a training gap wearing a bug costume. But it shows up in the scan the same way, so here we are.

The rest of this page is about the build itself.

The technical decisions—or spectacular non-decisions—that produce websites that look fine and function like a shopping cart with three wheels. None of these are impossible to fix. Most of them would've been caught by a scan before launch.

Color contrast: the most popular failure on the internet.

Step one: pick a light gray. Step two: put it on white. Step three: pat yourself on the back because it looks "clean" and "minimal." Step four: exclude everyone with low vision, anyone sitting near a window, and most people over 45. WCAG requires a 4.5:1 contrast ratio. Most brand palettes couldn't clear 3:1 with a running start.

This text is #999 on a light background. It looks fine in a cave. It vanishes on a phone in daylight. But hey, the designer said it was "on brand."

This one is #C0C0C0. At this point we're basically writing in invisible ink. Aesthetic? Sure. Readable? Absolutely not.

This text blinks. In 2026. On purpose. We're not proud of it. Okay, we're a little proud.

Heading hierarchy: the outline nobody reads.

Quick reminder: headings aren't font sizes. They're a document outline. H1 is the title. H2s are chapters. H3s are sections. When you skip from H2 to H5 because the H5 "looked right," you've basically told every screen reader that your page was outlined by someone throwing darts at a board.

This heading skipped three levels to get here.

Screen readers navigate by heading level. Skip one and the user thinks they missed something. Skip two and they assume the page is haunted. Skip three and—well, that's what we just did.

Buttons and links: labeled with icons and prayers.

A button needs a name. Not a vibe. Not an icon that "everyone recognizes." A name that a screen reader can actually announce. "Button" is not a name. A hamburger icon is not a name. A magnifying glass SVG with no aria-label is just a tiny picture of a magnifying glass that means nothing to anyone who can't see it. It's a riddle wrapped in a click target.

Want to learn more? Click here. Or read more. Or learn more.

Go

Lists and tables: structured data, unstructured markup.

A list that isn't wrapped in a <ul> or <ol> is just a stack of divs cosplaying as organized content. A table without proper headers is a spreadsheet of mystery numbers. Screen readers depend on semantic structure to know what things are—without it, they're reading a ransom note made of table cells.

  • Valid list item
  • Invalid child of ul—not a list item
  • Another valid one
  • Orphaned list item with no parent list.
  • Term
    Definition

    This paragraph doesn't belong in a definition list.

    Orphaned definition term.
    Feature Status Priority
    1 Alt text Missing
    2 Heading order Broken
    Audit Results
    ItemStatus
    SchemaMissing
    Audit Results
    ItemStatus
    OG tagsMissing
    Dialog with no accessible name.
    Heading with aria-checked makes no sense.

    Images, video, and media: the silent failures.

    An image without alt text is a mystery box for screen readers. A video without captions is a silent film nobody asked for. An autoplay audio track is a jump scare for every single person wearing headphones. And we've got all three. You're welcome.

    Server-side image map
    This content is centered using a deprecated HTML element.
    And this text uses the deprecated font element.
    Deprecated align attribute on a div.
    Icon
    Duplicate class attribute.
    Tiny

    Available Monday–Friday, 9AM&endash;5PM.

    Prices start at $99 & go up from there.

    Check out our tools. Or see our scanning tools page.