{"id":118,"date":"2026-09-24T15:04:59","date_gmt":"2026-09-24T15:04:59","guid":{"rendered":"https:\/\/66colorful.com\/blog\/?p=118"},"modified":"2026-09-24T18:46:29","modified_gmt":"2026-09-24T18:46:29","slug":"two-color-focus-indicator-css","status":"publish","type":"post","link":"https:\/\/66colorful.com\/blog\/two-color-focus-indicator-css\/","title":{"rendered":"Two Color Focus Indicator CSS for Mixed UI"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A single brand-blue outline can look tidy in a component library and still disappear on a dark card, pale panel, gradient hero or image tile. That is why I treat <strong>two color focus indicator CSS<\/strong> as a practical default for interfaces with mixed surfaces, not as a decorative flourish.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The core idea is simple: pair a light ring band with a dark ring band, test the pair, then test the actual component context. <a href=\"https:\/\/www.w3.org\/WAI\/WCAG21\/Techniques\/css\/C40\" title=\"https:\/\/www.w3.org\/WAI\/WCAG21\/Techniques\/css\/C40\" target=\"_blank\" rel=\"noopener\">W3C Technique C40<\/a> says that when the two indicator colors have at least a 9:1 contrast ratio with each other, at least one is guaranteed to reach 3:1 contrast against any single solid background, as long as the whole indicator sits on that one solid color. That makes a two-color ring a strong baseline for keyboard focus visibility, but images, gradients and overlapping UI still need direct checking.<\/p>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table of Contents<\/h2><nav><ul><li class=\"\"><a href=\"#why-two-color-focus-indicator-css-works-on-solid-surfaces-1\">Why two color focus indicator CSS works on solid surfaces<\/a><\/li><li class=\"\"><a href=\"#translate-wcag-contrast-language-into-a-focus-ring-workflow-2\">Translate WCAG contrast language into a focus-ring workflow<\/a><\/li><li class=\"\"><a href=\"#where-two-color-focus-indicator-css-stops-being-automatic-3\">Where two color focus indicator CSS stops being automatic<\/a><\/li><li class=\"\"><a href=\"#write-the-css-without-erasing-keyboard-focus-4\">Write the CSS without erasing keyboard focus<\/a><\/li><li class=\"\"><a href=\"#turn-accessible-focus-rings-into-design-tokens-5\">Turn accessible focus rings into design tokens<\/a><\/li><li class=\"\"><a href=\"#qa-checklist-before-shipping-two-color-focus-indicator-css-6\">QA checklist before shipping two color focus indicator CSS<\/a><\/li><li class=\"\"><a href=\"#frequently-asked-questions\">Frequently asked questions<\/a><\/li><li class=\"\"><a href=\"#next-steps\">Next steps<\/a><\/li><li class=\"\"><a href=\"#sources\">Sources and further reading<\/a><\/li><\/ul><\/nav><\/div>\n\n\n<div class=\"wp-block-image post_content_image\">\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ab71ea6d8489&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ab71ea6d8489\" class=\"aligncenter size-full wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"675\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-1-115-1-9aa22a3f188e58c9.jpg\" alt=\"Suggested palette: #FFFFFF, #111827, #2563EB, #F3F4F6\" class=\"wp-image-122\" srcset=\"https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-1-115-1-9aa22a3f188e58c9.jpg 1200w, https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-1-115-1-9aa22a3f188e58c9-300x169.jpg 300w, https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-1-115-1-9aa22a3f188e58c9-1024x576.jpg 1024w, https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-1-115-1-9aa22a3f188e58c9-768x432.jpg 768w, https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-1-115-1-9aa22a3f188e58c9-800x450.jpg 800w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Suggested palette with exact sRGB hex swatches.<\/figcaption><\/figure>\n<\/div>\n\n\n<h2 id=\"why-two-color-focus-indicator-css-works-on-solid-surfaces-1\" class=\"wp-block-heading\">Why two color focus indicator CSS works on solid surfaces<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">W3C Technique C40, updated 12 January 2026, describes a two-color focus indicator built from a light and dark band. Its useful rule is mathematical rather than stylistic: if the two ring colors contrast with each other at 9:1 or higher, at least one ring color will contrast at 3:1 against any one solid background color.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In practice, a pair like <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/ffffff\" title=\"View the #FFFFFF color page\" style=\"--cf-chip-color:#ffffff;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#FFFFFF<\/span><\/a> and <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/111827\" title=\"View the #111827 color page\" style=\"--cf-chip-color:#111827;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#111827<\/span><\/a> is easy to reason about after you verify the contrast. A brand-friendly pair can also work, but do not assume it works because it looks bold in a design file. Start by checking the two ring colors against each other in <a href=\"https:\/\/66colorful.com\/tools\/compare-colors\" title=\"Compare Colors\">Compare Colors<\/a> or the <a href=\"https:\/\/66colorful.com\/tools\/contrast-checker\" title=\"Contrast Checker\">Contrast Checker<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This technique is informative guidance, not the only valid way to satisfy WCAG. I use it because it gives designers and front-end developers a repeatable starting point before component-by-component testing begins.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Try this palette:<\/strong> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/ffffff\" title=\"View the #FFFFFF color page\" style=\"--cf-chip-color:#ffffff;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#FFFFFF<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/111827\" title=\"View the #111827 color page\" style=\"--cf-chip-color:#111827;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#111827<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/2563eb\" title=\"View the #2563EB color page\" style=\"--cf-chip-color:#2563eb;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#2563EB<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/f3f4f6\" title=\"View the #F3F4F6 color page\" style=\"--cf-chip-color:#f3f4f6;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#F3F4F6<\/span><\/a> <\/p>\n\n\n<div class=\"wp-block-image post_content_image\">\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ab71ea6d8c64&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ab71ea6d8c64\" class=\"aligncenter size-full wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1080\" height=\"1080\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-2-115-2-8df171b54d834386.jpg\" alt=\"WCAG focus contrast workflow for custom focus indicators\" class=\"wp-image-125\" srcset=\"https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-2-115-2-8df171b54d834386.jpg 1080w, https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-2-115-2-8df171b54d834386-300x300.jpg 300w, https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-2-115-2-8df171b54d834386-1024x1024.jpg 1024w, https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-2-115-2-8df171b54d834386-150x150.jpg 150w, https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-2-115-2-8df171b54d834386-768x768.jpg 768w\" sizes=\"auto, (max-width: 1080px) 100vw, 1080px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">AI-generated conceptual illustration.<\/figcaption><\/figure>\n<\/div>\n\n\n<h2 id=\"translate-wcag-contrast-language-into-a-focus-ring-workflow-2\" class=\"wp-block-heading\">Translate WCAG contrast language into a focus-ring workflow<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">WCAG 2.2 is a W3C Recommendation dated 12 December 2024, with the change log noting original WCAG 2.2 publication on 05 October 2023. For custom focus styles, three success criteria matter in day-to-day color decisions.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Focus Visible, SC 2.4.7, Level AA:<\/strong> keyboard focus must be visibly indicated.<\/li>\n\n\n\n<li><strong>Non-text Contrast, SC 1.4.11, Level AA:<\/strong> the visual information required to identify UI components and states needs at least 3:1 contrast against adjacent colors, with the WCAG exceptions for inactive or unmodified user-agent components.<\/li>\n\n\n\n<li><strong>Focus Appearance, SC 2.4.13, Level AAA:<\/strong> the visible focus indicator has an area at least as large as a 2 CSS pixel thick perimeter of the unfocused component, and at least 3:1 contrast between the same pixels in focused and unfocused states.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/www.w3.org\/WAI\/WCAG22\/Understanding\/focus-appearance\" title=\"https:\/\/www.w3.org\/WAI\/WCAG22\/Understanding\/focus-appearance\" target=\"_blank\" rel=\"noopener\">Understanding Focus Appearance<\/a> page, updated 10 August 2026, makes the relationship practical: focus indicators communicate state, so they relate to both Focus Appearance and Non-text Contrast. I test two things separately. First, does the focused state visibly change from the unfocused state? Second, does the ring contrast with the colors touching it?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use the <a href=\"https:\/\/66colorful.com\/tools\/focus-indicator-checker\" title=\"Focus Indicator Contrast Checker\">Focus Indicator Contrast Checker<\/a> to test the focused\/unfocused state change, adjacent background contrast and ring width together.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Try this palette:<\/strong> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/0f172a\" title=\"View the #0F172A color page\" style=\"--cf-chip-color:#0f172a;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#0F172A<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/ffffff\" title=\"View the #FFFFFF color page\" style=\"--cf-chip-color:#ffffff;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#FFFFFF<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/f59e0b\" title=\"View the #F59E0B color page\" style=\"--cf-chip-color:#f59e0b;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#F59E0B<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/e0f2fe\" title=\"View the #E0F2FE color page\" style=\"--cf-chip-color:#e0f2fe;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#E0F2FE<\/span><\/a> <\/p>\n\n\n<div class=\"wp-block-image post_content_image\">\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ab71ea6d93d1&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ab71ea6d93d1\" class=\"aligncenter size-full wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"900\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-3-115-3-d6f98c3884307cf1.jpg\" alt=\"Suggested palette: #0B1120, #F8FAFC, #16A34A, #DB2777, #7C3AED\" class=\"wp-image-127\" srcset=\"https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-3-115-3-d6f98c3884307cf1.jpg 1200w, https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-3-115-3-d6f98c3884307cf1-300x225.jpg 300w, https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-3-115-3-d6f98c3884307cf1-1024x768.jpg 1024w, https:\/\/66colorful.com\/blog\/wp-content\/uploads\/2026\/09\/two-color-focus-indicator-css-image-3-115-3-d6f98c3884307cf1-768x576.jpg 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Suggested palette with exact sRGB hex swatches.<\/figcaption><\/figure>\n<\/div>\n\n\n<h2 id=\"where-two-color-focus-indicator-css-stops-being-automatic-3\" class=\"wp-block-heading\">Where two color focus indicator CSS stops being automatic<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The C40 guarantee applies only when the entire indicator is drawn over one solid background color. That sentence matters. A photo card, mesh gradient, video thumbnail, frosted panel, shadowed card edge or clipped container can put different pixels behind different parts of the same ring.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For mixed backgrounds, pick representative worst-case swatches and test them instead of relying on the 9:1 pair alone. A pale ring can disappear over a bright part of a photograph while the dark ring still works, or the reverse can happen over a shadow. If the ring straddles a card edge, test the outside page surface and the inside component surface.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I map the risky surfaces first: white cards, dark cards, brand panels, alert tints, gradients, image cards, dark mode, high-contrast themes and disabled-looking states. Then I run ring tokens through the <a href=\"https:\/\/66colorful.com\/tools\/contrast-grid\" title=\"Contrast Grid\">Contrast Grid<\/a> and broader color systems through the <a href=\"https:\/\/66colorful.com\/tools\/palette-accessibility-matrix\" title=\"Palette Accessibility Matrix\">Palette Accessibility Matrix<\/a>. If an image drives the palette, the <a href=\"https:\/\/66colorful.com\/tools\/palette-from-image\" title=\"Palette From Image\">Palette From Image<\/a> tool can help you extract swatches to test.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Try this palette:<\/strong> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/0b1120\" title=\"View the #0B1120 color page\" style=\"--cf-chip-color:#0b1120;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#0B1120<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/f8fafc\" title=\"View the #F8FAFC color page\" style=\"--cf-chip-color:#f8fafc;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#F8FAFC<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/16a34a\" title=\"View the #16A34A color page\" style=\"--cf-chip-color:#16a34a;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#16A34A<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/db2777\" title=\"View the #DB2777 color page\" style=\"--cf-chip-color:#db2777;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#DB2777<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/7c3aed\" title=\"View the #7C3AED color page\" style=\"--cf-chip-color:#7c3aed;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#7C3AED<\/span><\/a> <\/p>\n\n\n\n<h2 id=\"write-the-css-without-erasing-keyboard-focus-4\" class=\"wp-block-heading\">Write the CSS without erasing keyboard focus<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">MDN guidance in the research notes that <code>:focus-visible<\/code> follows browser logic for when focus should be visibly indicated, especially for keyboard navigation. It also warns that <code>outline: 0<\/code> or <code>outline: none<\/code> removes the browser default focus style, so never remove it unless you replace it with an obvious visible indicator.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is a compact two-band pattern. The offset is set to zero so the 2px outline and the visible outer part of the 4px spread shadow act like adjacent bands. The raw hex values are examples for code only, not universal tokens. Test your own values before shipping.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"css\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">:root {\n  --focus-ring-inner: #ffffff;\n  --focus-ring-outer: #111827;\n  --focus-ring-offset: 0px;\n  --focus-ring-width: 2px;\n}\n\n:where(a, button, input, select, textarea, &#091;tabindex&#093;):focus-visible {\n  outline: var(--focus-ring-width) solid var(--focus-ring-inner);\n  outline-offset: var(--focus-ring-offset);\n  box-shadow: 0 0 0 calc(var(--focus-ring-width) * 2) var(--focus-ring-outer);\n}\n\n@supports not selector(:focus-visible) {\n  :where(a, button, input, select, textarea, &#091;tabindex&#093;):focus {\n    outline: var(--focus-ring-width) solid var(--focus-ring-inner);\n    outline-offset: var(--focus-ring-offset);\n    box-shadow: 0 0 0 calc(var(--focus-ring-width) * 2) var(--focus-ring-outer);\n  }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For layered effects, keep accessibility separate from decoration. The <a href=\"https:\/\/66colorful.com\/tools\/css-shadow-generator\" title=\"CSS Box Shadow Generator\">CSS Box Shadow Generator<\/a> can help you shape the outer band, but a soft decorative shadow is not automatically a valid focus indicator.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Try this palette:<\/strong> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/ffffff\" title=\"View the #FFFFFF color page\" style=\"--cf-chip-color:#ffffff;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#FFFFFF<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/111827\" title=\"View the #111827 color page\" style=\"--cf-chip-color:#111827;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#111827<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/3b82f6\" title=\"View the #3B82F6 color page\" style=\"--cf-chip-color:#3b82f6;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#3B82F6<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/e5e7eb\" title=\"View the #E5E7EB color page\" style=\"--cf-chip-color:#e5e7eb;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#E5E7EB<\/span><\/a> <\/p>\n\n\n\n<h2 id=\"turn-accessible-focus-rings-into-design-tokens-5\" class=\"wp-block-heading\">Turn accessible focus rings into design tokens<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A focus ring should not be a one-off rule pasted into each component. Store it as semantic tokens so buttons, links, menu items, cards and form fields stay consistent across themes.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Base values:<\/strong> keep precise light and dark ring colors, such as <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/ffffff\" title=\"View the #FFFFFF color page\" style=\"--cf-chip-color:#ffffff;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#FFFFFF<\/span><\/a> and <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/111827\" title=\"View the #111827 color page\" style=\"--cf-chip-color:#111827;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#111827<\/span><\/a>, after testing.<\/li>\n\n\n\n<li><strong>Semantic aliases:<\/strong> use names like <code>--focus-ring-light<\/code>, <code>--focus-ring-dark<\/code>, <code>--focus-ring-width<\/code> and <code>--focus-ring-offset<\/code>.<\/li>\n\n\n\n<li><strong>Theme overrides:<\/strong> define exceptions for inverse themes, image cards, compact controls and containers with <code>overflow: hidden<\/code>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/66colorful.com\/tools\/css-variable-theme-generator\" title=\"CSS Variable Theme Generator\">CSS Variable Theme Generator<\/a> is useful once you have validated values and want to export them into a broader token system. If you need to audit text and icon colors on the same components, pair that work with the <a href=\"https:\/\/66colorful.com\/tools\/contrast-ratio-checker\" title=\"Contrast Ratio Checker\">Contrast Ratio Checker<\/a> so focus accessibility is not isolated from overall color accessibility.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Try this palette:<\/strong> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/111827\" title=\"View the #111827 color page\" style=\"--cf-chip-color:#111827;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#111827<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/ffffff\" title=\"View the #FFFFFF color page\" style=\"--cf-chip-color:#ffffff;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#FFFFFF<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/10b981\" title=\"View the #10B981 color page\" style=\"--cf-chip-color:#10b981;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#10B981<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/f97316\" title=\"View the #F97316 color page\" style=\"--cf-chip-color:#f97316;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#F97316<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/cbd5e1\" title=\"View the #CBD5E1 color page\" style=\"--cf-chip-color:#cbd5e1;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#CBD5E1<\/span><\/a> <\/p>\n\n\n\n<h2 id=\"qa-checklist-before-shipping-two-color-focus-indicator-css-6\" class=\"wp-block-heading\">QA checklist before shipping two color focus indicator CSS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before release, test the keyboard path, not only the color pair. Tab through every interactive element in source order, including links inside cards, icon buttons, menus, form controls, dialogs and skipped or hidden states. A ring that passes contrast but gets clipped by a parent container still fails the person trying to use it.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Check focused and unfocused state contrast for the component.<\/li>\n\n\n\n<li>Check ring contrast against adjacent page and component colors.<\/li>\n\n\n\n<li>Repeat in light mode, dark mode, brand panels, alert surfaces, gradients and image cards.<\/li>\n\n\n\n<li>Look for clipping caused by <code>overflow: hidden<\/code>, tight containers or negative margins.<\/li>\n\n\n\n<li>Keep browser or user-agent focus behavior intact when possible, especially for users who rely on system preferences.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Custom focus styles are responsible for meeting the contrast expectation. Unmodified browser default focus indicators can be treated differently under the guidance, but once you style the indicator yourself, test it like any other critical UI state.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Try this palette:<\/strong> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/020617\" title=\"View the #020617 color page\" style=\"--cf-chip-color:#020617;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#020617<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/f8fafc\" title=\"View the #F8FAFC color page\" style=\"--cf-chip-color:#f8fafc;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#F8FAFC<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/22c55e\" title=\"View the #22C55E color page\" style=\"--cf-chip-color:#22c55e;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#22C55E<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/ef4444\" title=\"View the #EF4444 color page\" style=\"--cf-chip-color:#ef4444;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#EF4444<\/span><\/a> <a class=\"cf-color-chip cf-color-chip--link\" rel=\"nofollow\" href=\"https:\/\/66colorful.com\/color\/60a5fa\" title=\"View the #60A5FA color page\" style=\"--cf-chip-color:#60a5fa;\"><span class=\"cf-color-chip__swatch\" aria-hidden=\"true\"><\/span><span class=\"cf-color-chip__label\">#60A5FA<\/span><\/a> <\/p>\n\n\n\n<h2 id=\"frequently-asked-questions\" class=\"wp-block-heading\">Frequently asked questions<\/h2>\n\n\n\n<h3 id=\"faq-1\" class=\"wp-block-heading\">What is a two-color focus ring?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A two-color focus ring uses two visible bands, usually one light and one dark, around a focused component. The goal is to keep at least one band visible when the component appears on different solid backgrounds.<\/p>\n\n\n\n<h3 id=\"faq-2\" class=\"wp-block-heading\">Why does W3C Technique C40 mention a 9:1 contrast ratio?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Technique C40 says that if the two indicator colors contrast with each other at 9:1 or higher, at least one of those colors is guaranteed to reach 3:1 contrast against any single solid background behind the whole indicator.<\/p>\n\n\n\n<h3 id=\"faq-3\" class=\"wp-block-heading\">Does a two-color ring automatically pass on images and gradients?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. The C40 guarantee applies to one solid background behind the whole ring. Images, gradients, glass effects, video thumbnails and overlapping surfaces need direct testing against the actual or representative adjacent pixels.<\/p>\n\n\n\n<h3 id=\"faq-4\" class=\"wp-block-heading\">Should I use :focus or :focus-visible?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use :focus-visible for the primary custom style because it follows browser logic for when visible focus is expected, especially keyboard navigation. Add a :focus fallback inside @supports not selector(:focus-visible) if you need older-browser support.<\/p>\n\n\n\n<h3 id=\"faq-5\" class=\"wp-block-heading\">Is WCAG 2.4.13 required for every WCAG AA project?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">WCAG 2.4.13 Focus Appearance is Level AAA in WCAG 2.2. WCAG 1.4.11 Non-text Contrast is Level AA. Do not treat the full Level AAA focus appearance area requirement as mandatory for AA unless the project has adopted it.<\/p>\n\n\n\n<h3 id=\"faq-6\" class=\"wp-block-heading\">Can I remove the browser outline?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Only remove or override the default outline if you provide a clearly visible replacement. Setting outline: none without a tested alternative can leave keyboard users without a usable focus indicator.<\/p>\n\n\n\n<h3 id=\"faq-7\" class=\"wp-block-heading\">What focus-ring width should I start with?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A practical starting point is a 2 CSS pixel inner band plus a visible 2 CSS pixel outer band. Test the actual component because size, offset, adjacent colors and clipping all affect whether the indicator is usable.<\/p>\n\n\n\n<h2 id=\"next-steps\" class=\"wp-block-heading\">Next steps<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Two color focus indicator CSS<\/strong> gives you a resilient starting point for mixed interfaces because a strongly contrasting light and dark pair can cover many solid backgrounds. The important word is starting. WCAG-related focus testing still depends on the component, the adjacent colors, the focus-state change and the surface behind the ring.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">My recommended workflow is simple: inventory surfaces, choose a light and dark focus pair, verify the pair, implement with <code>:focus-visible<\/code>, test real components, then store the result as design tokens. That keeps accessible focus rings visible where they matter most: in the actual product, under the user\u2019s keyboard.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For standards context, I would keep <a href=\"https:\/\/www.w3.org\/WAI\/WCAG21\/Techniques\/css\/C40\" title=\"https:\/\/www.w3.org\/WAI\/WCAG21\/Techniques\/css\/C40\" target=\"_blank\" rel=\"noopener\">W3C Technique C40<\/a>, <a href=\"https:\/\/www.w3.org\/WAI\/WCAG22\/Understanding\/non-text-contrast\" title=\"https:\/\/www.w3.org\/WAI\/WCAG22\/Understanding\/non-text-contrast\" target=\"_blank\" rel=\"noopener\">Understanding Non-text Contrast<\/a>, <a href=\"https:\/\/www.w3.org\/WAI\/WCAG22\/Understanding\/focus-appearance\" title=\"https:\/\/www.w3.org\/WAI\/WCAG22\/Understanding\/focus-appearance\" target=\"_blank\" rel=\"noopener\">Understanding Focus Appearance<\/a> and the <a href=\"https:\/\/www.w3.org\/TR\/wcag\/\" title=\"https:\/\/www.w3.org\/TR\/wcag\/\" target=\"_blank\" rel=\"noopener\">WCAG Recommendation<\/a> close to the implementation notes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related tools &amp; resources on 66Colorful:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/66colorful.com\/tools\/focus-indicator-checker\">Focus Indicator Checker<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/66colorful.com\/tools\/compare-colors\">Compare Colors<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/66colorful.com\/tools\/contrast-grid\">Contrast Grid<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/66colorful.com\/tools\/palette-accessibility-matrix\">Palette Accessibility Matrix<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/66colorful.com\/blog\/designing-for-color-blindness\/\">Designing For Color Blindness<\/a><\/li>\n<\/ul>\n\n\n\n<h2 id=\"sources\" class=\"wp-block-heading\">Sources and further reading<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.w3.org\/WAI\/WCAG21\/Techniques\/css\/C40\" target=\"_blank\" rel=\"noopener\">https:\/\/www.w3.org\/WAI\/WCAG21\/Techniques\/css\/C40<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.w3.org\/WAI\/WCAG22\/Understanding\/focus-appearance\" target=\"_blank\" rel=\"noopener\">https:\/\/www.w3.org\/WAI\/WCAG22\/Understanding\/focus-appearance<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.w3.org\/TR\/wcag\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.w3.org\/TR\/wcag\/<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.w3.org\/WAI\/WCAG22\/Understanding\/non-text-contrast\" target=\"_blank\" rel=\"noopener\">https:\/\/www.w3.org\/WAI\/WCAG22\/Understanding\/non-text-contrast<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>A practical workflow for choosing and testing two-color focus rings that stay visible on cards, gradients, image tiles and themed surfaces.<\/p>\n","protected":false},"author":1,"featured_media":121,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[31,71,70,8,68,69],"class_list":["post-118","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-accessibility","tag-accessibility","tag-color-contrast","tag-css","tag-design-tokens","tag-focus-indicators","tag-wcag"],"_links":{"self":[{"href":"https:\/\/66colorful.com\/blog\/wp-json\/wp\/v2\/posts\/118","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/66colorful.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/66colorful.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/66colorful.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/66colorful.com\/blog\/wp-json\/wp\/v2\/comments?post=118"}],"version-history":[{"count":8,"href":"https:\/\/66colorful.com\/blog\/wp-json\/wp\/v2\/posts\/118\/revisions"}],"predecessor-version":[{"id":155,"href":"https:\/\/66colorful.com\/blog\/wp-json\/wp\/v2\/posts\/118\/revisions\/155"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/66colorful.com\/blog\/wp-json\/wp\/v2\/media\/121"}],"wp:attachment":[{"href":"https:\/\/66colorful.com\/blog\/wp-json\/wp\/v2\/media?parent=118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/66colorful.com\/blog\/wp-json\/wp\/v2\/categories?post=118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/66colorful.com\/blog\/wp-json\/wp\/v2\/tags?post=118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}