Skip to content

Correct numbers and formulae for focus area calculations #4366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

patrickhlauke
Copy link
Member

@patrickhlauke patrickhlauke commented Apr 27, 2025

Closes #4275

EDIT: the re-running of the numbers and formulae in this PR was based on my (mis)understanding that we're talking about an outline (the use of the word "outline" at the start of that section primed me for that assumption). as @dbjorge points out, this may not be the correct assumption (but the hidden assumptions on the existing formulae are not made clear, leading to confusion for the reader)

Apart from the numbers in the first example being wrong, the actual formulae were wrong as well.

For the rectangle, the simplest calculation is "the larger rectangle (with the extra 2px outline on all sides) minus the base control size"

For the circle, you can't just take the circumference and multiply it by 2. You have to do the same calculation - a circle whose radius is 2px larger, minus the base control circle.

For the rectangle with rounded edges, the calculation comes out very complex - in short, it's 4 rectangles (2 times a rectangle with width minus 2r, multiplied by 2 height; 2 times a rectangle with height minus 2r, multiplied by 2 width) and then a full circle 2px outline using the previous formula (4 quarters of a circle on each corner)

Bonus: corrected two typos - "accommodation" and "Albania"

@patrickhlauke patrickhlauke added Understanding Non-Normative Informative language in the specification or supporting materials labels Apr 27, 2025
@patrickhlauke
Copy link
Member Author

if someone could triple-check my maths, that'd be lovely

Copy link

netlify bot commented Apr 27, 2025

Deploy Preview for wcag2 ready!

Name Link
🔨 Latest commit d602795
🔍 Latest deploy log https://app.netlify.com/sites/wcag2/deploys/68108548d51ed80008ec2936
😎 Deploy Preview https://deploy-preview-4366--wcag2.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Closes #4275

Apart from the numbers in the first example being wrong, the actual formulae were wrong as well.

For the rectangle, the simplest calculation is "the larger rectangle (with the extra 2px outline on all sides) minus the base control size"

For the circle, you can't just take the circumference and multiply it by 2. You have to do the same calculation - a circle whose radius is 2px larger, minus the base control circle.

For the rectangle with rounded edges, the calculation comes out very complex - in short, it's 4 rectangles (2 times a rectangle with width minus 2r, multiplied by 2 height; 2 times a rectangle with height minus 2r, multiplied by 2 width) and then a full circle using the previous formula (4 quarters of a circle on each corner)

Bonus: corrected two typos - "accommodation" and "Albania"
@patrickhlauke patrickhlauke force-pushed the patrickhlauke-issue4275 branch from 5407ce4 to 75d4085 Compare April 27, 2025 20:39
Copy link
Contributor

@dbjorge dbjorge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neither this change nor the existing calculations are actually consistent with the guidance further up in the same document on L131, which says:

The smallest possible 2 CSS pixel thick indicator that is still a "perimeter" is a solid line that appears inside the component against the component's outer edge, for example by using a CSS border property.

This guidance would mean that the true minimum would be calculated by using the difference in area between "the unfocused component" and "a shape 2px smaller than the unfocused component".

Unfortunately, I can't find a written record of our discussions about this (either in the mailing list or GitHub history), but my recollection is that:

  • There was broad agreement that we wanted border: 2px solid to be a sufficient technique
  • There was pushback against making the Example next to the normative perimeter definition any more complicated than necessary, so we intentionally accepted having the example formulae be slight overestimations of the "true" minimums for the sake of simplicity (for what it's worth, I think this isn't a very compelling argument given the relative luminance definition just a page later in the document)
  • The understanding document reflects the Example from the perimeter definition in the actual WCAG document. Like the example near the definition, we preferred trying to keep the formulae simple to understand, so we intentionally omitted the steps to derive them from the understanding document.

The formulae in the original text (and the example near the perimeter definition) would be correct for a 2px perimeter whose "centerline" straddles the unfocused component shape (ie, what you'd get if you used border: 1px solid; outline: 1px solid CSS). This was chosen because, in that arrangement, both the rectangle and circle calculations end up with terms that cancel out to match the simple-looking formula in the current document.

For the rectangle, that looks like:

$$A=(w+2)(h+2) - (w-2)(h-2)$$ $$A=(wl + 2w + 2h + 4) - (wl - 2w - 2h + 4)$$ $$A=wl + 2w + 2h + 4 - wl + 2w + 2h - 4$$ $$A=4w + 4h$$

For the circle:

$$A=𝜋(r+1)^2 - 𝜋(r-1)^2$$ $$A=𝜋(r^2+2r+1) - 𝜋(r^2-2r+1)$$ $$A=𝜋(r^2+2r+1-r^2+2r-1)$$ $$A=𝜋(2r + 2r)$$ $$A=4𝜋r$$

If we did decide we wanted to accept more complicated formulae as a tradeoff to be more accurate with the notion of accepting border: 2px solid, then I think the actual updates you'd want would be more like:

Rectangle:
$$A=wh - (w-4)(h-4)$$
Circle:
$$A=𝜋(r+2)^2 - 𝜋r^2$$

For the rounded rectangle, the 4 rounded corners together are equivalent to a circle of radius border-radius (just cut up into 4 segments and translated), plus 2 horizontal straight lines of width $w-2r$ and height 2px, plus 2 vertical straight lines of width 2px and height $h-2r$:

$$A=2(2)(h-2r) + 2(w-2r)(2) + 𝜋((r+2)^2 - r^2)$$ $$A=4(w+h-4r) + 𝜋((r+2)^2 - r^2)$$

If we decided "a 2px CSS border is an unacceptable technique, but a 2px CSS outline would be ok", then I'd agree with your proposed updates, but I don't think we'd really want border: 2px solid to fail.

@dbjorge
Copy link
Contributor

dbjorge commented Apr 29, 2025

In terms of "what minimum definition of perimeter does the normative language demand", that comes down to our interpretation of the definition of Perimeter:

perimeter
continuous line forming the boundary of a shape not including shared pixels, or the minimum bounding box, whichever is shortest.

...where I think it's ambiguous what exactly "the boundary" means and whether "not including shared pixels" is meant to refer to "a shape"/"the boundary of a shape" (ie, not including any parts of the shape that are occluded by other shapes") or the "continuous line" (ie, the line shouldn't share any pixels with the shape).

Short of making a normative change, I think the ambiguity means we'd be allowed to clarify a suggested interpretation in the understanding docs. I think the interpretation that allows border: 2px solid as sufficient is reasonable, is our original intent, and is the least likely to cause a surprise gotcha compatibility issue for existing components, so that's the interpretation I'd vote we go with.

I'm neutral on whether we stick with the simpler example formula or not, so long as we continue to say that border: solid 2px is sufficient. (rather, I have a slight preference for using the more accurate formulae, but it's not a hill I care to spend energy fighting on)

@patrickhlauke
Copy link
Member Author

Neither this change nor the existing calculations are actually consistent with the guidance further up in the same document on L131, which says:

The smallest possible 2 CSS pixel thick indicator that is still a "perimeter" is a solid line that appears inside the component against the component's outer edge, for example by using a CSS border property.

Ah, apologies, I managed to miss this. I was struggling at first to understand where the current calculations for the rectangle were coming from, and because the "Other indicator shapes" section start off by talking about "outline", it didn't make any sense. Indeed, the calculation for rectangle that's there right now would suggest a 2px thing that straddles the rectangle (1px in, 1px out), but it's not explained clearly.

This guidance would mean that the true minimum would be calculated by using the difference in area between "the unfocused component" and "a shape 2px smaller than the unfocused component".

I'd be up for changing it to that (my change here assumed outline, due to the use of the word "outline" in that section).

Unfortunately, I can't find a written record of our discussions about this (either in the mailing list or GitHub history), but my recollection is that:

  • There was broad agreement that we wanted border: 2px solid to be a sufficient technique

Anecdotally, I seem to remember this conversation as well and agreeing with it.

  • There was pushback against making the Example next to the normative perimeter definition any more complicated than necessary, so we intentionally accepted having the example formulae be slight overestimations of the "true" minimums for the sake of simplicity (for what it's worth, I think this isn't a very compelling argument given the relative luminance definition just a page later in the document)

If there is some fudging of the numbers, then it should be clearly spelled out, as otherwise people like the original poster of the issue, and people like me who then come in and look at the formulae, will be confused about the inaccuracy - particularly as the numbers here are usually quite small and used as a minimum threshold that people will desperately try to reach for baseline compliance.

Admittedly, I think I've then chased a rabbit down a wrong hole when I was looking at the formulae, under assumption we're talking outline.

So, probably the first thing for the group to discuss and try to agree on: do we want to allow a 2px border as the minimum, and if so are we ok with then following through and explicitly changing the formulae and values here to reflect that (as currently there seem to be some fudges/assumptions built into these that aren't clear, like the straddling)

@brothercake
Copy link

brothercake commented Apr 29, 2025

I'd inferred that the math fudges were intentional to make the formulae easier to use. Consider a non-rectangular shape like a 5-pointed star. The current formula allows for the perimeter to be calculated as (20 * L) (where "L" is the length of one side). An accurate formula would have to calculate all the triangle and irregular polygon intersections of the perimeter lines, which is a lot more complicated.

And yes, even by the simple formula, a 2px border is too small. But since the difference is nominal, I also presumed that this was an intentional fudge.

I don't think this should be changed to use accurate perimeter calculations, they're just too complicated.

Changing the normative requirement to "An area equal to a 2px border" would be more internally consistent, and would be backwardly compatible with existing conformance. However the formula for that isn't quite as simple.

So overall, my view is that it doesn't change, but documentation describes where the fudges are, and why.

I wouldn't describe this in terms of straddling though, I think that would muddy the water in a different way. I would just say that "perimeter" is used to mean "outline minus shared pixels" / "outline where radius is the component circle" (we can't correctly define a mathematical perimeter in terms of straddling, because perimeters have zero width, so the definition would have to be specific to this context).

There doesn't have to be a geometric explanation for the simplified formula, I think it's perfectly fine to say that it's intentionally inaccurate for the sake of simplicity.

@patrickhlauke patrickhlauke marked this pull request as draft May 2, 2025 16:00
@patrickhlauke
Copy link
Member Author

changing to Draft, as we first need to agree with the fundamental "is a border ok?"

@kfranqueiro
Copy link
Contributor

Recap from May 2 backlog call:

There are (at least) 3 options for what to do with these calculations:

  1. "Change our mind" from what's currently in the text in the understanding doc, and declare border as not sufficient (Dan -1)
    • In this case, the calculations in this PR would be correct, but this would imply significant text changes in perimeter definition and understanding doc
  2. Keep border as sufficient, update formulas in understanding doc and perimeter definition to be more accurate (Dan +1)
    • Requires a similar set of updates to what's in this PR
  3. Leave as-is: Understanding says border is sufficient, but keep simplified formulas because ease of understanding is more important than strict accuracy
    1. clarify the simplification in the Understanding document
    2. or, make no change

@ljoakley
Copy link
Contributor

ljoakley commented May 9, 2025

Recap from May 2 backlog call:

There are (at least) 3 options for what to do with these calculations:

1. "Change our mind" from what's currently in the text in the understanding doc, and declare border as not sufficient (Dan -1)
   
   * In this case, the calculations in this PR would be correct, but this would imply significant text changes in perimeter definition and understanding doc

2. Keep border as sufficient, update formulas in understanding doc and perimeter definition to be more accurate (Dan +1)
   
   * Requires a similar set of updates to what's in this PR

3. Leave as-is: Understanding says border is sufficient, but keep simplified formulas because ease of understanding is more important than strict accuracy
   
   1. clarify the simplification in the Understanding document
   2. or, make no change

I would like to combine both and 2 and 3, update the formulas as Dan commented during the meeting and simplify the understanding to not include the formulas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Non-Normative Informative language in the specification or supporting materials Understanding
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Calculations for criterion 2.4.13
5 participants