Published in full / ssc-1.2 / 31 checks

The standard we score against, in full.

Every check we run, what it costs a score when it fails, and exactly how that score is calculated. None of it is proprietary: a standard you cannot read is a slogan, and a score you cannot recompute is a sales tactic.

How the score works

You can check our arithmetic.

We publish this for one reason: a score we could quietly adjust would not be worth selling. If you disagree with a finding, the rules below are enough to recompute the number yourself and tell us we got it wrong.

Each category starts at 100 and loses points for every check that fails. The category scores are then combined using the weights below.

penalty = base × (1 + log₁₀(occurrences)), capped per severity

Occurrences matter, but with diminishing returns. Forty missing image descriptions is worse than four — but it is usually one template rendered forty times, and one fix clears them all.

What each severity costs

SeverityWhat it meansBaseMost it can cost
criticalStops someone completing what they came to do.1226
seriousMakes it substantially harder for some people.716
moderateA real barrier for some, with a workaround for most.38
minorWorth fixing; nobody is blocked by it.13

What each category is worth

CategoryWhyWeightLivePlanned
AccessibilityIt is what we are actually assessing.76146
SecurityCheap to get right, expensive to get wrong.1360
Site healthBroken links and missing policies cost enquiries.1141

Plannedchecks are published and weighted here but not yet automated, so no site loses points for them today. A category containing planned checks therefore scores higher than the weights imply — uniformly, for every site, in the site’s favour. There are 7 of them, listed with the rest below and marked.

Scores from different versions of this checklist are not comparable, so every scan records the version that produced it. This page is ssc-1.2. How we run each check, and what we keep as evidence, is on the methodology page.

Accessibility / weight 76 / 20 checks

Accessibility

  • A-1.1.1seriousWCAG 1.1.1Automated

    Images have meaningful alternative text

    Every image that carries information needs a text description.

    What it costs you
    Someone using a screen reader hears "image" instead of what you are showing them. Search engines are equally blind to it.
    How it gets fixed
    In the CMS or template, add an alt attribute to every image that conveys information — a short, specific description of what it shows, not the filename. Leave alt empty (alt="") on purely decorative images so they are skipped rather than mis-described. Verify by viewing the page with images blocked in the browser: every meaningful image should be replaced by readable text.
    Roughly how long
    a few minutes per image, through the media library where one exists
  • A-1.1.1-MseriousWCAG 1.1.1Human review

    Alternative text is actually useful

    The description says what the image shows, not "DSC_0421.jpg".

    What it costs you
    Alt text that exists but says nothing passes every automated tool and helps nobody. A machine cannot tell the difference; a person can.
    How it gets fixed
    Rewrite any alt text that is a camera filename, a keyword list, or a copy of the nearby caption so it instead says what the image shows and why it is there. Read each description as if you could not see the image — does it tell you what is happening? Nothing here needs code, only better words in the same alt field used for A-1.1.1.
    Roughly how long
    a few minutes per image
  • A-1.3.1seriousWCAG 1.3.1Automated

    Page structure is marked up correctly

    Headings, lists and tables are built as headings, lists and tables — not text styled to look like them.

    What it costs you
    Screen reader users navigate by structure. Without it they read the whole page top to bottom or leave.
    How it gets fixed
    Rebuild the elements axe flagged using real HTML — an actual <ul>/<ol> for lists, an actual <table> with <th> header cells for tabular data — instead of styled elements that only look like a list or table. This usually means editing the page template or theme rather than page content. Verify with the browser accessibility tree inspector: the flagged element should show the correct role (list, table, and so on), not "generic".
    Roughly how long
    half a day, depending on how the template was built
  • A-1.3.1-HmoderateWCAG 1.3.1Automated

    Heading levels are in order

    Headings go h1, h2, h3 without skipping levels.

    What it costs you
    Skipped levels break the outline people use to jump around your page.
    How it gets fixed
    Go through the page top to bottom and set each heading to the level that matches its place in the outline — one h1, then h2 for its major sections, h3 only under an h2 — without skipping a level for visual size alone. Where a heading looks empty, either give it real text or remove the heading markup and style the text a different way. Verify with your browser accessibility inspector or a heading-outline extension: the levels should step down one at a time with no gaps.
    Roughly how long
    a sentence-length change per page — picking the right heading style in the editor
  • A-1.4.3criticalWCAG 1.4.3Automated

    Text has enough contrast against its background

    Normal text needs a 4.5:1 contrast ratio; large text needs 3:1.

    What it costs you
    Low contrast is the single most common failure on the web. It affects anyone with reduced vision, and everyone on a phone in sunlight.
    How it gets fixed
    For each flagged text/background pair, pick a darker text color or a lighter background until the contrast ratio the report measured clears 4.5:1 for normal text or 3:1 for large text, then update the color in the stylesheet or theme settings. A free online contrast checker will confirm the new pair before you ship it. Verify by checking the pair again in the contrast checker — the ratio should read at or above the threshold.
    Roughly how long
    an hour or two, most of it picking new colors
  • A-1.4.1moderateWCAG 1.4.1Human review

    Colour is not the only way information is conveyed

    Errors, required fields and status are marked with more than just red or green.

    What it costs you
    Roughly one in twelve men has some colour vision deficiency. If red is your only signal, they miss it.
    How it gets fixed
    For every place color alone marks meaning — an error, a required field, a status badge, a link in a paragraph — add a second signal: an icon, an underline, bold text, or a text label, so removing color removes nothing. Links inside body copy specifically need an underline or a strong contrast difference, not just a different hue. Verify by opening the page with a grayscale filter (most browser dev tools have one) — every piece of information that mattered in color should still be legible.
    Roughly how long
    an hour or two
  • A-1.4.4moderateWCAG 1.4.4Automated (keyboard)Planned — not yet scored

    Text survives being zoomed to 200%

    Zooming to twice the size does not cut off or overlap content.

    What it costs you
    Many people browse zoomed in permanently. If your layout breaks, your site is unusable for them.
    How it gets fixed
    Set the browser zoom to 200% and find every place text gets clipped, cut off by a fixed-height container, or overlaps other content, then switch those containers to flexible sizing (min-height, overflow visible, or relative units) instead of a fixed pixel height. Repeat with the OS text-size setting where the platform allows it. Verify by zooming to 200% again — nothing should be cut off, overlapping, or pushed outside the visible page.
    Roughly how long
    half a day, depending on how rigid the layout is
  • A-1.4.10seriousWCAG 1.4.10Automated (keyboard)

    No horizontal scrolling at phone width

    At 320 pixels wide the page reflows instead of forcing sideways scrolling.

    What it costs you
    More web traffic worldwide now comes from phones than desktops. Sideways scrolling reads as broken and people leave.
    How it gets fixed
    At a 320px-wide viewport, find the element wider than the screen — often a fixed-width image, table, or a container with a hardcoded pixel width — and switch it to a relative width (max-width: 100%, or a percentage) so it shrinks with the screen instead of forcing a sideways scrollbar. Verify by loading the page in a phone-width browser window (or device emulator) and confirming there is no horizontal scrollbar.
    Roughly how long
    a few hours — usually one wide element to track down
  • A-2.1.1criticalWCAG 2.1.1Automated (keyboard)Planned — not yet scored

    Everything works with a keyboard alone

    Every button, link, menu and gallery can be reached and operated without a mouse.

    What it costs you
    People with motor impairments, and anyone using assistive tech, navigate by keyboard. A lightbox that only closes on click traps them on the page.
    How it gets fixed
    For every custom control that only responds to a mouse click (a gallery, a dropdown, a lightbox), add the same behavior on Enter and Space key presses, and make sure Tab actually reaches it — usually by using a real <button> or <a> element instead of a plain <div> with a click handler. Verify by not touching the mouse and tabbing through the whole page — every control a visitor can click should also be reachable and operable this way.
    Roughly how long
    half a day to a day, depending on how many custom widgets the site has
  • A-2.1.2criticalWCAG 2.1.2Automated (keyboard)Planned — not yet scored

    No keyboard traps

    Focus can always move forward and back out of any component.

    What it costs you
    A trap means the only way out is closing the tab. It is the most hostile failure on this list.
    How it gets fixed
    Find the component that traps focus — usually a menu, modal, or lightbox built without keyboard support — and add an Escape handler that closes it and returns focus to the control that opened it, plus normal Tab and Shift+Tab movement in and out. Verify by tabbing into the component and pressing Escape — focus should land back where it started, and Tab/Shift+Tab should never get stuck cycling in place.
    Roughly how long
    half a day
  • A-2.4.1moderateWCAG 2.4.1Automated

    A skip link lets people jump past the navigation

    Keyboard users can skip repeated menus and get to the content.

    What it costs you
    Without it, every page starts with a long tab through the same menu before reaching the content.
    How it gets fixed
    Add a "Skip to content" link as the very first focusable element on the page, hidden until it receives keyboard focus, pointing at the main content landmark. Alternatively, make sure the page uses real header, nav and main landmarks, which screen reader users can jump between without a visible skip link. Verify by pressing Tab once from the address bar — the skip link should appear and, when activated, move focus past the navigation.
    Roughly how long
    an hour or two
  • A-2.4.3seriousWCAG 2.4.3Automated (keyboard)Planned — not yet scored

    Focus order follows the visual order

    Tabbing moves through the page in the order things appear, and focus moves into and out of menus and dialogs correctly.

    What it costs you
    When an open menu leaves focus behind it, keyboard users are typing into a page they cannot see.
    How it gets fixed
    Remove any positive tabindex values, which are almost always the cause, and reorder the HTML — not just the visual CSS layout — so the document order matches the order things should be read and tabbed through. Make sure opening a menu or dialog moves focus into it, and closing it returns focus to the control that opened it. Verify by tabbing through the whole page and confirming focus moves in the same order a sighted visitor would read it.
    Roughly how long
    half a day
  • A-2.4.4moderateWCAG 2.4.4Automated

    Link text says where the link goes

    No bare "click here" or "read more" without context.

    What it costs you
    Screen reader users often pull up a list of links alone. A page full of identical "read more" entries gives them nothing to go on.
    How it gets fixed
    Rewrite generic link text — "click here", "read more", "learn more" — so each link's own words say where it goes, for example "read more about our roofing warranty" instead of a bare "read more". Where the visible words must stay short, add a visually-hidden span or aria-label with the fuller destination. Verify with your screen reader's link list (or by reading just the linked words down the page) — each one should make sense without its surrounding sentence.
    Roughly how long
    a sentence per link
  • A-2.4.7criticalWCAG 2.4.7Automated (keyboard)Planned — not yet scored

    The focused element is visibly marked

    Whatever the keyboard is on has a clear outline. Nobody has removed it in the stylesheet.

    What it costs you
    Removing the focus ring for looks makes keyboard navigation impossible — you cannot see where you are.
    How it gets fixed
    Search the stylesheet for outline:none or outline:0 and remove them, or replace them with a visible alternative — a box-shadow, border, or background change — that appears the moment an element receives focus. Make sure the replacement indicator has enough contrast against what is behind it, not just any visible change. Verify by tabbing through the page — every stop should show a clearly visible marker.
    Roughly how long
    an hour or two
  • A-2.5.8moderateWCAG 2.5.8Automated (keyboard)Planned — not yet scored

    Tap targets are large enough

    Buttons and links are at least 24 by 24 pixels.

    What it costs you
    Small targets are missed by anyone with a tremor, and by everyone on a bumpy bus.
    How it gets fixed
    For each undersized button or link, increase its clickable area to at least 24 by 24 CSS pixels — usually by adding padding rather than changing the visible icon or text size — or add at least 24px of clear space around it if the visual size cannot change. Verify by measuring the element in browser dev tools at a 375px-wide viewport, or by trying to tap it accurately on a real phone.
    Roughly how long
    an hour or two
  • A-3.1.1minorWCAG 3.1.1Automated

    The page declares its language

    A lang attribute tells assistive tech which language to pronounce.

    What it costs you
    Without it, a screen reader may read English with the wrong accent and rules — sometimes unintelligibly.
    How it gets fixed
    Add lang="en" (or the correct BCP 47 code for the site's language) to the opening html tag in the page template. Most website builders expose this as a language setting in site settings rather than requiring template edits, so check there first. Verify by viewing the page source — the html tag should carry a valid, non-empty lang attribute.
    Roughly how long
    a sentence in the page template — a one-line change
  • A-3.3.2criticalWCAG 3.3.2Automated

    Every form field has a label

    Each input has a real label element, not just placeholder text.

    What it costs you
    A field with no label gives a screen reader nothing to announce, so someone using one has no way to tell what the box is asking for. Quote and contact forms are where this matters most.
    How it gets fixed
    For every input, select, and textarea the report flagged, add a real label element (or wrap the field in one) connected to that field's id — placeholder text alone does not count. Prioritize the contact, quote, and booking forms first, since those are the ones that cost an enquiry when they fail. Verify with a screen reader or the browser accessibility inspector — each field should announce a real label, not just its type.
    Roughly how long
    an hour or two per form
  • A-3.3.1moderateWCAG 3.3.1Human review

    Errors are identified in text and explain the fix

    A rejected form says what was wrong and how to correct it.

    What it costs you
    A red border with no message leaves people guessing. Most of them just give up on the form.
    How it gets fixed
    When a form submission is rejected, show the specific problem in text next to the field it belongs to — not just a red border — and say what would be accepted instead, for example "Enter a valid email address like name@example.com". Move keyboard focus to the first error, or announce it through an aria-live region, so it is not only visible. Verify by submitting the form with one deliberately wrong field and confirming the message is both visible and read aloud by a screen reader.
    Roughly how long
    half a day per form
  • A-4.1.2criticalWCAG 4.1.2Automated

    Controls have accessible names

    Buttons, links and widgets announce what they do — including icon-only carousel arrows.

    What it costs you
    An unnamed button is announced as just "button". Carousel and lightbox controls are the usual offenders.
    How it gets fixed
    For every icon-only button, link, or widget the report flagged — carousel arrows and lightbox close buttons are the usual culprits — add an aria-label or visually-hidden text describing what it does, for example aria-label="Next slide". Verify by checking the computed accessible name in the browser dev tools accessibility panel — it should read the action, not be blank.
    Roughly how long
    an hour or two
  • A-4.1.2-ARIAseriousWCAG 4.1.2Automated

    ARIA is valid, and hidden content is actually hidden

    ARIA roles and attributes are used correctly, and anything marked hidden from screen readers cannot still be reached with the keyboard.

    What it costs you
    Broken ARIA is worse than none, and a common cause is a carousel or slider that marks off-screen slides aria-hidden while leaving their links and buttons in the tab order — a keyboard or screen reader user lands on a control they cannot see or use. Pages using ARIA average more errors than pages without it, usually because a plugin applied it wrong.
    How it gets fixed
    Fix each invalid role, attribute, or value axe reports — usually by correcting a typo or removing an attribute that does not apply to that element. Separately, find any aria-hidden="true" container that still holds a focusable link, button, or input — typically off-screen carousel slides — and either remove those elements from the tab order (tabindex="-1", or inert) or stop marking the container hidden while it is still reachable. Verify by tabbing through the page: focus should never land inside something marked aria-hidden, and the accessibility panel should show no invalid ARIA.
    Roughly how long
    half a day, more if the ARIA was applied by a third-party plugin

Security / weight 13 / 6 checks

Security

  • S-TLScriticalAutomated (headers)

    The site is served over HTTPS

    The connection is encrypted and the certificate is valid and current.

    What it costs you
    Browsers now label plain HTTP as "Not secure" in the address bar. Visitors see that before they see you.
    How it gets fixed
    Install a valid TLS certificate for the domain — many hosts and platforms provision one automatically, sometimes behind a toggle in site settings — and confirm the site redirects http:// to https:// automatically. If the certificate is expired or invalid, renew or reissue it through the host or certificate provider. Verify by loading the site and checking for a padlock in the address bar with no warning.
    Roughly how long
    an hour, or a support ticket to your host if the certificate needs reissuing
  • S-HSTSmoderateAutomated (headers)

    HTTPS is enforced (HSTS)

    The server tells browsers to refuse the unencrypted version.

    What it costs you
    Without it, the first visit can be intercepted before the redirect happens.
    How it gets fixed
    Add a Strict-Transport-Security response header (for example, max-age=31536000; includeSubDomains) in the server or platform header configuration. On Apache, add `Header always set Strict-Transport-Security "max-age=31536000"` to .htaccess; on nginx, add it in the server block; on a website builder that does not expose custom headers, this cannot be fixed there. Verify by checking the response headers of the live site (browser dev tools Network tab) for strict-transport-security.
    Roughly how long
    a few minutes, on platforms that allow custom headers
  • S-CSPseriousAutomated (headers)

    A content security policy is set

    The site declares which scripts it trusts.

    What it costs you
    This is the main defence against an injected script skimming forms.
    How it gets fixed
    Add a Content-Security-Policy response header that names which sources of scripts, styles, and other resources the page trusts, then test the page thoroughly since an overly strict policy can silently break embedded widgets or third-party scripts. On Apache or nginx this is a header configuration change; on a website builder that does not allow custom headers, this cannot be fixed there. Verify by checking the response headers for content-security-policy and confirming the page still works with the policy in place.
    Roughly how long
    half a day to build a policy that does not break the site
  • S-FRAMEmoderateAutomated (headers)

    The site cannot be framed by others

    X-Frame-Options or frame-ancestors stops someone embedding your site inside theirs.

    What it costs you
    Framing is used to trick visitors into clicking things they cannot see.
    How it gets fixed
    Add either an X-Frame-Options: SAMEORIGIN header or a frame-ancestors directive in the Content-Security-Policy header. On Apache, add `Header set X-Frame-Options SAMEORIGIN` to .htaccess; on a website builder that does not allow custom headers, this cannot be fixed there. Verify by checking the response headers for one of the two.
    Roughly how long
    a few minutes, on platforms that allow custom headers
  • S-SNIFFminorAutomated (headers)

    MIME type sniffing is disabled

    X-Content-Type-Options: nosniff is present.

    What it costs you
    Stops a browser from guessing that an uploaded file is a script.
    How it gets fixed
    Add an X-Content-Type-Options: nosniff response header. On Apache, add `Header set X-Content-Type-Options nosniff` to .htaccess; on nginx, add it in the server block; on a website builder that does not allow custom headers, this cannot be fixed there. Verify by checking the response headers for x-content-type-options set exactly to nosniff.
    Roughly how long
    a few minutes, on platforms that allow custom headers
  • S-STACKseriousAutomated (headers)

    No outdated software is publicly advertised

    The site does not announce an old CMS or plugin version in its headers or markup.

    What it costs you
    Automated bots scan for exactly these version strings. Advertising one is an invitation.
    How it gets fixed
    Remove or suppress the version string the server sends in the X-Powered-By, Server, or X-Generator headers — most platforms have a setting or a small config change to do this (for example, expose_php off in PHP, or removing a plugin that adds an X-Generator header). Verify by checking the response headers again for a version number after the change.
    Roughly how long
    a few minutes to an hour, depending on the platform

Site health / weight 11 / 5 checks

Site health

  • H-LINKSmoderateAutomatedPlanned — not yet scored

    No broken links

    Every link on the page resolves.

    What it costs you
    A dead link on a services page is a lost enquiry and a bad signal to search engines.
    How it gets fixed
    Update or remove each broken link the report lists, pointing it at the correct current page, or delete it if the destination no longer exists. For links to other sites, confirm the destination has actually moved before assuming your own link is at fault. Verify by clicking the link again and confirming it loads instead of an error page.
    Roughly how long
    a few minutes per broken link
  • H-MIXEDseriousAutomated

    No insecure content on a secure page

    An HTTPS page does not load images or scripts over plain HTTP.

    What it costs you
    Mixed content breaks the padlock and can be blocked outright by the browser.
    How it gets fixed
    Change every http:// resource the report lists — usually an image or script src — to https://, or to a protocol-relative or root-relative URL so it always matches the page's own protocol. This is often a single find-and-replace across the theme or a plugin setting. Verify by reloading the page and checking the browser console for no more mixed-content warnings.
    Roughly how long
    an hour or two
  • H-PRIVACYmoderateAutomated

    A privacy policy exists and is reachable

    If the site collects anything through a form, it says what happens to it.

    What it costs you
    Expected by visitors, required by most analytics and advertising terms of service.
    How it gets fixed
    Write a plain-language privacy policy page describing what information the site collects (through contact forms, analytics, and so on) and what happens to it, then add a link to it — the word "privacy" should appear somewhere in that link's URL or this check will miss it even once the page exists. Link it from the site footer so it is reachable from every page. Verify by scrolling to the bottom of the homepage and confirming a working privacy link is there.
    Roughly how long
    an hour to write, a sentence in the page settings to link it
  • H-TITLEmoderateAutomated

    Pages have unique, descriptive titles

    The browser tab and search result say what the page is.

    What it costs you
    The title is the first line of every search result. "Home | Home" wastes it.
    How it gets fixed
    Give each page a specific title in the page's SEO or settings panel — what the page actually is, not "Home" repeated everywhere, and at least a few words long. On a multi-page site, make sure no two pages share the same title. Verify by looking at the browser tab or a search result for the page — it should describe that specific page.
    Roughly how long
    a sentence per page
  • H-VIEWPORTseriousWCAG 1.4.4Automated

    Mobile viewport is configured and zoom is not blocked

    A viewport meta tag exists and does not disable pinch-to-zoom.

    What it costs you
    Blocking zoom makes the page harder to read for anyone who needs to enlarge text — a site-health basics issue that also happens to be a WCAG 1.4.4 requirement, and still common on older templates that copied an outdated "mobile-friendly" meta tag.
    How it gets fixed
    Edit the viewport meta tag in the page template so it does not include user-scalable=no and does not set maximum-scale below 2 — the simplest fix is often to remove those two parameters entirely and leave only width=device-width, initial-scale=1. Verify by loading the page on a phone or in a mobile emulator and confirming you can pinch-zoom in.
    Roughly how long
    a sentence in the page template — a one-line change

Take this to anyone you like.

Every check above names what to change and how to tell when it is fixed. You do not need us to act on any of it, and a report that could not survive being handed to another developer would not be finished. 24 of these 31 checks are running today.