Skip to content
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

Add target size enhanced rule #1919

Draft
wants to merge 46 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
1f3a63a
Add target size enhanced rule
WilcoFiers Sep 8, 2022
cfef38b
Rework a bit normative parts
Jym77 Aug 10, 2023
9a82752
Merge branch 'develop' into target-size-enhanced
Jym77 Aug 17, 2023
9ceba73
Merge branch 'develop' into target-size-enhanced
Jym77 Sep 14, 2023
c48767d
Refine rule a bit
Jym77 Sep 14, 2023
218bd99
Polish draft a bit
Jym77 Sep 15, 2023
62d2c9d
more work
Jym77 Sep 28, 2023
fa487ad
Merge branch 'develop' into target-size-enhanced
Jym77 Oct 5, 2023
90c4107
Attempt to write barebone defs
Jym77 Oct 5, 2023
67184e0
Some more notes
Jym77 Oct 13, 2023
b081edd
Text spacing rewrite (#1923)
Jym77 Oct 13, 2023
3f188b2
"Meta viewport allows for zoom" (b4f0c3): Explicit meaning of 'has' (…
Jym77 Oct 13, 2023
39748a1
Map Empty-heading rule to ARIA instead of WCAG (#2120)
WilcoFiers Oct 13, 2023
58463aa
Deprecate 4.1.1 rules (#2117)
WilcoFiers Oct 13, 2023
01a9d63
Fix markup issue in Iframe has name rule (#2116)
WilcoFiers Oct 13, 2023
dad2491
Stop linking to proposed rules (#2108)
WilcoFiers Oct 13, 2023
bb06ca3
Fix image-button accessibility support editorial oversight (#2106)
WilcoFiers Oct 13, 2023
a87ffeb
"Iframe not with interactive element" [akn7bn]: handle inert iframe (…
Jym77 Oct 16, 2023
1ea2503
Add much more examples
Jym77 Oct 26, 2023
23dc14b
Add much more examples
Jym77 Oct 26, 2023
c79f2f5
Merge branch 'develop' into target-size-enhanced
Jym77 Nov 9, 2023
e415158
Add more examples
Jym77 Nov 9, 2023
56bfa49
Merge branch 'develop' into target-size-enhanced
Jym77 Nov 23, 2023
4dffd15
Revert definition of clickable area
Jym77 Nov 23, 2023
38046c7
Clean up
Jym77 Nov 23, 2023
21f7cca
Merge branch 'develop' into target-size-enhanced
Jym77 Dec 14, 2023
5c492fb
Improve definition
Jym77 Dec 14, 2023
13e6ab8
Do not use aria-labelledby on raw div
Jym77 Dec 14, 2023
a37d2d9
Add definitions of implicit and explicit labels
Jym77 Dec 14, 2023
1351979
Add definition of shape-shifted element
Jym77 Dec 14, 2023
089d7aa
Clean up
Jym77 Dec 14, 2023
f5eb6d0
Remove example numbering until solidification
Jym77 Dec 14, 2023
f05a6ae
Merge branch 'develop' into target-size-enhanced
Jym77 Dec 21, 2023
3bf353f
Revert unrelated typo fix
Jym77 Dec 21, 2023
6618579
Write definitions
Jym77 Dec 21, 2023
421c5bf
Typos
Jym77 Dec 21, 2023
af064f2
Revert unrelated typo fix
Jym77 Dec 21, 2023
b4fe1de
Remove unrelated typo fix
Jym77 Dec 21, 2023
b65434a
Merge branch 'develop' into target-size-enhanced
Jym77 Jan 25, 2024
5faa824
Merge branch 'develop' into target-size-enhanced
Jan 26, 2024
7dc621c
Merge branch 'develop' into target-size-enhanced
Jym77 Feb 15, 2024
f92d3bb
Update rule and definition
Jym77 Feb 15, 2024
37a794a
Merge branch 'develop' into target-size-enhanced
Jym77 Feb 29, 2024
301f1f4
Clean up examples
Jym77 Feb 29, 2024
8719b7a
Move UA controlled exception from Applicability to Expectation
Jym77 Mar 1, 2024
cb8149c
Typo in link
Jym77 Mar 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
731 changes: 731 additions & 0 deletions _rules/target-size-enhanced-gi8qkf.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions pages/examples/programmatic-label.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ The `div` element is not [labelable][]. Therefore, it is not a [labeled control]
<div id="bond">My name is Bond. James Bond.</div>
```

## aria-labelledby on div
## aria-labelledby on aside

The `span` element is referenced by the `aria-labelledby` attribute on the `div` element. Therefore, the `span` element is a programmatic label of the `div` element. Note that the `aria-labelledby` attribute works on any element, not just on the [labelable][] elements.
The `span` element is referenced by the `aria-labelledby` attribute on the `aside` element. Therefore, the `span` element is a programmatic label of the `div` element. Note that the `aria-labelledby` attribute works on any element, not just on the [labelable][] elements.

```html
<span id="label_fname">Full name:</span>
<div aria-labelledby="label_fname">My name is Bond. James Bond.</div>
<aside aria-labelledby="label_fname">My name is Bond. James Bond.</aside>
```

[programmatic label]: /glossary/#programmatic-label
Expand Down
37 changes: 37 additions & 0 deletions pages/glossary/can-be-targeted-by-pointer-event.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: Can be target by a pointer event
key: can-be-targeted-by-pointer-event
unambiguous: true
objective: true
input_aspects:
- CSS styling
- DOM tree
---

An element _can be targeted by pointer events_ when all the following conditions are true:

- the element is a [semantic `widget`][semantic role]; and
- the element is [focusable][]; and
- the element's [border box][] intersects the viewport; and
- the element's [border box][] is not entirely covered by the [border boxes][] of elements with greater `z-index` and `pointer-events: auto` CSS properties.
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure exactly what you mean 🤔

Is it about elements "behind" the modal being blocked by it when it's opened (even if they are visible)?
I think that this is covered because in that case, their "clickable area" would be empty (the blocked elements are never topmost target, until the modal is closed and stops blocking them).


#### Background

This definition tries to capture which HTML elements can actually react to pointer events. It is not possible to have an exact definition of these for two main reasons:

- Sometimes, the element that handles the event is not the element that appear to react to it, but an ancestor (or descendant) capturing the event during propagation or bubbling. In the most extreme case, the `body` element of a page could be the only one with an event handler, acting differently depending on where the event actually occurred. In such a case, a button would be perceived by users as something that can be targeted by a pointer event, while technically it is the `body` element which is targeted.
- It is not possible to query the list of event listeners on a given elements. Some User Agents offer way to monitor events fired at a given element, but none offer a way to query for event listeners. Additionally, an event listener might ultimately do nothing and thus, for users, the corresponding element wouldn't look like it can be targeted by pointer events (since it effectively wouldn't react to them).

As a consequence, this definition has these two known limitations:

- Not all HTML elements that can actually be targeted by a pointer event match this definition. For example, an author may build custom buttons without giving them an appropriate role or making them [focusable][]; or content overflowing the [border box][] is clickable. Elements that can actually be targeted by pointer events but do not match this definition likely fail either [Success Criterion 4.1.2 Name, Role, Value][sc412] or [Success Criterion 2.1.1 Keyboard][sc211].
- Not all HTML elements that match this definition can actually be targeted by a pointer event. For example, when the actual clickable area does not cover the full [border box][] and is entirely covered by other elements, or when the element has an event handler that does nothing. Elements that match this definition but cannot actually be targeted by pointer events likely fail [Success Criterion 2.5.6 Concurrent Input Mechanisms][sc256].

[border box]: https://www.w3.org/TR/css-box-3/#border-box 'CSS definition of Border Box'
[clickable area]: #clickable-area 'Definition of Clickable Area'
[focusable]: #focusable 'Definition of Focusable'
[sc211]: https://www.w3.org/TR/WCAG22/#keyboard 'Success Criterion 2.1.1 Keyboard'
[sc256]: https://www.w3.org/TR/WCAG22/#concurrent-input-mechanisms 'Success Criterion 2.5.6 Concurrent Input Mechanisms'
[sc412]: https://www.w3.org/TR/WCAG22/#name-role-value 'Success Criterion 4.1.2 Name, Role, Value'
[semantic role]: #semantic-role 'Definition of Semantic Role'
[visible]: #visible ' Definition of Visible'
17 changes: 17 additions & 0 deletions pages/glossary/clickable-area.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: Clickable area
key: clickable-area
unambiguous: true
objective: false
input_aspects:
- CSS styling
- DOM tree
---

The _directly clickable area_ of an element is the set of all viewport coordinates for which the element is the [topmost event target][]

The _clickable area_ of an element is the union of its _directly clickable area_ and that of its [implicit][implicit label] or [explicit label][].

[explicit label]: #programmatic-label:explicit 'Definition of Explicit Label'
[implicit label]: #programmatic-label:implicit 'Definition of Implicit Label'
[topmost event target]: https://w3c.github.io/uievents/#topmost-event-target 'CSS definition of Topmost Event Target'
4 changes: 4 additions & 0 deletions pages/glossary/programmatic-label.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,9 @@ For more details, see [examples of programmatic label][].

**Note**: a given element may have more than one programmatic label.

The [labeled control][] L of an element T is its <dfn id="programmatic-label:explicit">explicit label</dfn> if L has a `for` attribute referencing T's `id` attribute.

The [labeled control][] L of an element T is its <dfn id="programmatic-label:implicit">implicit label</dfn> if L has a no `for` attribute and is an ancestor of T in the DOM tree. Note that explicit labels take precedence over implicit label, and that [labeled controls][labelled control] do not cross shadow boundaries nor content documents.

[labeled control]: https://html.spec.whatwg.org/multipage/forms.html#labeled-control 'Definition of labeled control'
[examples of programmatic label]: https://act-rules.github.io/pages/examples/programmatic-label/
35 changes: 35 additions & 0 deletions pages/glossary/shape-shifted-element.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: Shape-Shifted Element
key: shape-shifted-element
unambiguous: true
objective: true
input_aspects:
- CSS styling
- DOM tree
---

An element is _shape-shifted_ if it has an [inclusive ancestor][] in the [flat tree][] with any of its [shape-shifting properties][] whose [computed value][] is different from the [initial value][] of that property.

> comment: shape-shifting an ancestor can shape-shifting the element, e.g. with `transform` or clipping. OTOH, this might be very trigger happy in considering everything inside a modal shape shifted just because the modal has rounded corners…

The <dfn id="shape-shifted-element:properties">Shape-Shifting Properties</dfn> are the following CSS properties:

- `border-radius` and the associated longhands;
- `transform`;
- `rotate`;
- `clip`;
- `clip-path`;

#### Background

Shape-shifted elements have an actual area on screen that can be very different from a rectangle aligned with the screen edges, and therefore hard to precisely compute. Rules looking at this area ignore shape-shifted elements for the sake of simplicity.

Not all shape-shifting properties significantly change the shape of an element. For example, a rotation of 180°, a `transform` property defining only the `translate` function, or a `clip-path` along a rectangular shape would not really alter the shape. This definition ignores these for the sake of simplicity.

Other CSS properties may alter the area covered by an element, for examples `height` or `width`. These properties, however, do not alter the _shape_ (rectangle aligned with the edges) and tend to keep the covered area and the CSS box model in harmony. Therefore, this definition doesn't include them.

[inclusive ancestor]: https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor 'DOM Definition of Inclusive Ancestor'
[computed value]: https://www.w3.org/TR/css-cascade-5/#computed-value 'CSS definition of computed value'
[flat tree]: https://drafts.csswg.org/css-scoping/#flat-tree 'CSS Definition of flat tree'
[initial value]: https://www.w3.org/TR/css-cascade-5/#initial-value 'CSS definition of initial value'
[shape-shifting properties]: #shape-shifted-element:properties
20 changes: 20 additions & 0 deletions pages/glossary/user-agent-controlled-component.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: User-Agent Controlled Component
key: user-agent-controlled-component
unambiguous: true
objective: true
input_aspects:
- CSS styling
- DOM tree
---

A _User-Agent Controlled Component_ is an [HTML element][namespace element] for which all the following are true:

- the element has an [implicit role][] which is a [semantic `widget`][semantic role]; and
- none of the following CSS properties of the element have a [cascaded value][] with "Author" [origin][]: `height`, `width`, `font-size`, `line-height`.

[cascaded value]: https://www.w3.org/TR/css-cascade-5/#cascade-value 'CSS definition of computed value'
[implicit role]: #implicit-role 'Definition of Implicit Role'
[origin]: https://drafts.csswg.org/css-cascade-5/#cascading-origins 'CSS definition of Cascading Origin'
[namespaced element]: #namespaced-element 'Definition of Namespaced Element'
[semantic role]: #semantic-role 'Definition of Semantic Role'
31 changes: 31 additions & 0 deletions test-assets/target-size/highlight-rect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Create an element with class "highlight" around a node.
* The node needs to be non-static to allow for z-index lower than
* the highlighted element, otherwise the .highlight element will prevent
* click events to reach the node.
*
* An optional set of classes can also be added to the highlighted element,
* these are mostly intended to be either ['good'] (default) or ['bad'] to set
* the color and style of the highlighting border.
*/
function highlightRect(node, classes = ['good']) {
// Get the bounding client rect of the node
const range = document.createRange()
range.setStart(node, 0)
// Take the length of text nodes, if it exists, otherwise (element), take
// all child nodes
range.setEnd(node, node?.length ?? node.childNodes.length)
const rect = range.getBoundingClientRect()

// Create a div sized to that rect
// See https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects#javascript
const div = document.createElement('div')
div.classList.add('highlight', ...classes)
div.style.top = `${rect.top}px`
div.style.left = `${rect.left}px`
div.style.width = `${rect.width - 2}px`
div.style.height = `${rect.height - 2}px`
document.body.appendChild(div)

return div
}
16 changes: 16 additions & 0 deletions test-assets/target-size/highlight.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.highlight {
position: absolute;
z-index: 0;
}

.good {
border: green solid 1px;
}
.bad {
border: red dashed 1px;
}

.highlightable {
position: relative;
z-index: 5;
}
Binary file added test-assets/target-size/map-background.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading