惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
Recent Announcements
Recent Announcements
D
DataBreaches.Net
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
Netflix TechBlog - Medium
Microsoft Azure Blog
Microsoft Azure Blog
Microsoft Security Blog
Microsoft Security Blog
B
Blog
U
Unit 42
有赞技术团队
有赞技术团队
博客园 - 聂微东
GbyAI
GbyAI
宝玉的分享
宝玉的分享
F
Full Disclosure
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MyScale Blog
MyScale Blog
Jina AI
Jina AI
Martin Fowler
Martin Fowler
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
D
Docker
P
Proofpoint News Feed
A
About on SuperTechFans
I
InfoQ
博客园 - 【当耐特】
C
Check Point Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog
T
Threat Research - Cisco Blogs
Y
Y Combinator Blog
Project Zero
Project Zero
WordPress大学
WordPress大学
小众软件
小众软件
AWS News Blog
AWS News Blog
博客园 - 司徒正美
T
The Exploit Database - CXSecurity.com
L
LINUX DO - 热门话题
I
Intezer
Engineering at Meta
Engineering at Meta
C
CXSECURITY Database RSS Feed - CXSecurity.com
J
Java Code Geeks
T
Tenable Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Last Week in AI
Last Week in AI
C
CERT Recently Published Vulnerability Notes

AlastairC

AI and Accessibility presentation | AlastairC WCAG 3, increment or overhaul? CSUN 2025 conference notes | AlastairC Cryptocurrency thoughts | AlastairC Why doesn’t AI work for producing accessible code? Accessibility improvements for user-agents | AlastairC WCAG – Priority of Constituencies Overlay comments | AlastairC Accessibility auditing and pushing for more
Focus Appearance thoughts | AlastairC
AlastairC · 2023-02-07 · via AlastairC

This article was based on a previous draft of WCAG 2.2 and is no longer valid. I’m keeping it here for posterity, outlining the good ideas from the previous version, even though it was not thought practical in all cases.

I think it is fair to say that some folks aren’t very happy with the focus-appearance criterion proposed in WCAG 2.2. Hidde thought it adds too much complexity, and Eric didn’t rate it.

I think everyone sees the value of having good focus indicators, so I’m taking the comments as a challenge to provide the easiest possible way of explaining the criterion and how to test it. Eric wants to do a good explanation in an hour, I’m going to aim for 15 minutes.

Below is a video of a presentation on focus appearance, below that is the text equivalent.

You can also view the video on Youtube if the basic video player above doesn’t work well enough.

Focus Visibility Factors

There are three main things that appear to affect the visibility of a focus indicator, with poor examples shown as the middle item of each:

  1. The change of colour (contrast) from the original colour. Without that it can fade from sight.
    Three dark buttons, the centre one has a light grey outline against a white background.
  2. The size and thickness of the change, otherwise it can be too small to discern.
    Three light buttons, the centre one has a thin border on the left side only.
  3. The difference of colour (contrast) from the surrounding colours. Without that it can merge into another area of colour.
    Three dark buttons, the centre one has a thin outline of the same colour, making it a tiny, tiny by larger than the other buttons.

Without capturing each of these factors in the criterion, it would allow invisible (or poorly visible) indicators.

“Safe” indicators

If you just want to be sure you are passing, sod the detail, these are some safe indicators:

That last one doesn’t have ‘adjacent contrast’, but when you’re adding a 2px thick indicator, the button is getting larger by 4px in height and width. That just crosses over the baseline of visibility we were aiming for.

The SC text

The full criterion text is in the draft spec of WCAG 2.2. It is in three parts:

  1. The easy(er) to understand metrics.
  2. The flexible, but harder to understand metrics.
  3. The exceptions.

The easier to understand bullets say the indicator needs to enclose the component, have a change of contrast (at least 3:1), and adjacent contrast.

If you have a component with a light background, a simple dark outline will work. If the component has a dark background, you’ll need to separate it slightly from the component.

A light button with a dark outline, and a dark button with a separated dark outline.

If that’s a reasonable indicator for your site, that’s it, job done.

However, if you wish to use a different form of indicator, you’ll need to read the second part.

Area calculations

The first bullet contains two area calculations, you can use either, the first is:

An area of the focus indicator meets all the following:

  • is at least as large as the area of a 1 CSS pixel thick perimeter of the unfocused component or sub-component

It is asking for an area that is proportional to the component, in this case the perimeter. Imagine a 1px line around it, what area is that?

A light button with a dark outline, the outline has been copied separately, showing the 4 lines separately.

For example, a 25 by 100px button requires an indicator area of 25+25+100+100 = 250px.

Technically we need to take off 4px for the corners as they overlap, so it is 246px. However, if you are relying on 4 pixels you have bigger problems. If it is that close, pick a different indicator!

The second size metric you can use is:

at least as large as a 4 CSS pixel thick line along the shortest side of the minimum bounding box of the unfocused component

This metric is useful for indicators that are quite thick, but not proportional to the length of the control. When the length of the control varies with the text, this type of indicator provides a stable area.

A light button with a thick left border. The border has been copied separately, showing the 4 short lines separately.

With the same example button, a 25 by 100px button requires an indicator area of 25 x 4 = 100px. This allows some buffer for indicators just under the perimeter metric, e.g. an inner outline.

The “minimum bounding box” aspect is useful for non-rectangular shapes which have a larger perimeter, and to simplify testing. If the shape were a star it would have a large perimeter. On the other hand, a circle actually has a smaller perimeter than the bounding box.

A cicular button with a red square drown around it.

For a circle with a diameter of 100px the perimeter = 100 x 3.14 = 314px. That is less than the 4 times shortest side metric, so a circular outline is probably the best approach.

Adjacent contrast OR Thickness

The last bullet of option 2 is slightly different from option 1:

has a contrast ratio of at least 3:1 against adjacent non-focus-indicator colors, or is no thinner than 2 CSS pixels.

This allows for 2px (or thicker) indicators that do not contrast with the component itself. It does not mean that it can lack change of contrast, only adjacent contrast. It allows for this type of indicator:

A dar blue button with a thick green outline.

Testing focus appearance

Easy to assess passes

There are quite a few indicators that you can see immediately when they pass.

Easy to assess fails

There are quite a few indicators that you can see immediately when they don’t pass.

Using the Browser Inspector

You can establish the size/thickness of most indicators by using the code inspector:

  1. Inspect the control
  2. Open the “:hov” selection
  3. Tick “focus”. If nothing changes on the control, try “focus-visible”.
  4. Select the “computed” tab and ensure that “Show All” (Chrome/Edge) or “Browser styles” boxes are ticked.
  5. Filter to “outline”. If that doesn’t work, try “border”, “shadow”, or “background”.

The size in CSS Pixels is reported in the “computed styles”, even if it is defined in other units in the authored CSS.

If the browser default indicator is active (not overridden by the author), you may not find the definitions, or they may not be reported accurately. If it is the default indicator and there is no change of background colour then it passes. If backgrounds have been changed, check the visual output.

Default indicators are:

  • Edge/Chrome default: 1px white outline, AND an inset 2px black outline.
  • Firefox: For buttons/controls – 2px medium blue border with light blue halo.
    For links – 1px blue outline.
  • Safari: 3px blue (#8CB6FA) outline, slightly inset so it often overlaps the border of a control Doesn’t contrast with white (2.1 : 1).

Using a graphical app

If you are not familiar with CSS, you can test it visually. These are Mac based commands, but Windows has equivalents.

  • Use a standard density monitor where 1 device pixel = 1 OS pixel. (Check on Screenresolutiontest.com)
  • Check the browser is at 100% zoom.
  • Screenshot the focus indicator (shift-control-command-4 on MacOS adds it to your paste history as the latest item).
  • Use an image editing tool (e.g. Preview on MacOS, press command-n to open the image from your clipboard).
  • Zoom-in and select an area to measure.

An example of a zoomed in screenshot showing the measurement of thickness of an indicator.

Tricky examples

A couple of tricky examples I came across recently are worth working through. For example, the search input on Gov.uk.

Two search inputs, the second has a yellow outline (on a light background) and the border appears thicker.

The additional yellow doesn’t have a sufficient “change of contrast”. However, the border gets substantially thicker, we can see from the code:

.search__input[type="search"]:focus {
  outline: 3px solid #fd0;     // yellow
  box-shadow: inset 0 0 0 2px; // additional 2px dark "border"
}

Although it lacks ‘adjacent’ contrast, it is 2px thick so passes.

Taking a ‘half and half’ screenshot to compare the focused / non-focused state also helps:

A black line in one half of the screenshot, then a thicker black line with a yellow outer line in the other half.

Another tricky example is using a dashed outline, which Microsoft does on their homepage navigation.

Screenshot from Microsoft.com of the logo with a 1px dashed outline.

I started testing this in Firefox, and a 1 px dashed outline has 50% coverage of the perimeter (3 pixels ‘on’, 3 pixels ‘off’). It is not continuous, so does not pass using the option 1 bullets. The component is 55px tall by 137px wide.

Trying 4 x shortest edge, the minimum area of the indicator needs to be 55 x 4 = 220px.

The size of the indicator is (137 x 2) + (55 x 2) = 384.
Then divide by 2 due to the coverage of “dashed” indicator, so 384 / 2 = 192px.

So that was a fail, in Firefox. Not far off, but not sufficient. However, then checking in Edge (or Chrome), the dashed indicator has ~66% coverage in Edge/Chrome, so just passes!

So if you’re catering to a broad browser base, then a 1px dashed indicator is not a safe one.

A “safe” indicator would be something that passes no matter the shape of the component, such as a solid contrasting outline, or Gov.uk‘s approach of 4px thick underline.

With that type of indicator no calculations are needed, they will reliably pass.