PageSourceSearch

https://securoxen.io/assets/contrast-is-a-security-feature-DK0uyMn6.js

js securoxen.io collected 2026-10-02 01:59:29 UTC 3,310 bytes, 1 lines download raw bytes

1import{j as e}from"./index-0qbe4j-K.js";import{P as r}from"./prose-CP3GO64z.js";import{L as t}from"./react-vendor-CuqwDvgQ.js";function a(){return e.jsxs(r,{children:[e.jsx("p",{children:"A warning nobody reads is not a warning. Accessibility usually gets argued as a legal or moral obligation, both true - but there is a narrower argument that lands with people who build security UI: the control only works if the user perceives it."}),e.jsx("h3",{children:"The numbers, briefly"}),e.jsxs("p",{children:["WCAG measures contrast as a ratio between 1:1 and 21:1. AA asks for ",e.jsx("strong",{children:"4.5:1"})," ","for normal text and ",e.jsx("strong",{children:"3:1"}),' for large text; AAA asks for 7:1 and 4.5:1. "Large" is defined in points rather than pixels, which trips people up: 18pt regular or 14pt bold - roughly 24px and 18.7px at a default browser setting.']}),e.jsxs("p",{children:['Mid-grey on white - the default look of "secondary text" in most design systems - lands around 3.5:1. That passes for a heading and fails for the 14px line under it, which is exactly where warnings tend to live. Check a pair with the'," ",e.jsx(t,{to:"/tools/contrast-checker",children:"Contrast Checker"})," rather than guessing."]}),e.jsx("h3",{children:"Where this stops being cosmetic"}),e.jsx("p",{children:"Security interfaces put their most important text in their least readable style. The pattern repeats everywhere:"}),e.jsxs("ul",{children:[e.jsx("li",{children:"Certificate and permission warnings set in small grey helper text."}),e.jsx("li",{children:'The signer or origin of a request rendered lighter than the "Approve" button.'}),e.jsx("li",{children:"Error states that rely on red alone, which a red-green colourblind user cannot see."}),e.jsx("li",{children:"Disabled controls indistinguishable from enabled ones, so users click and hope."})]}),e.jsx("p",{children:"Each of these makes a user more likely to approve something they did not understand. That is a security outcome produced by a styling decision."}),e.jsx("h3",{children:"Colour alone is never the signal"}),e.jsx("p",{children:"Around one in twelve men has some form of colour vision deficiency. If pass and fail are distinguished only by green and red, a meaningful fraction of your users see two identical badges."}),e.jsx("p",{children:'Pair colour with a shape, an icon, or a word. "Failed" next to a red dot survives both colourblindness and a monochrome screenshot pasted into a ticket.'}),e.jsx("h3",{children:"Dark mode is a second design, not a filter"}),e.jsx("p",{children:"Inverting a palette does not preserve contrast ratios. A colour that passed comfortably on white frequently fails on a dark background, and pure white text on pure black overshoots - it produces halation that makes long text genuinely harder to read."}),e.jsx("p",{children:"Measure both themes. A theme is not done because it looks plausible in a screenshot."}),e.jsx("h3",{children:"The uncomfortable version"}),e.jsx("p",{children:"Every security warning is a request for the user's attention, and users have been trained by a decade of unreadable, unactionable dialogs to spend as little of it as possible. Making the warning legible is the cheapest available intervention, and it is usually a two-line change."})]})}export{a as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.