diff --git a/images/reading-flow-order-example.svg b/images/reading-flow-order-example.svg new file mode 100644 index 00000000000..7452d12fc80 --- /dev/null +++ b/images/reading-flow-order-example.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source b/source index 1024b55dd73..963b170153c 100644 --- a/source +++ b/source @@ -3236,6 +3236,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
The following features are defined in CSS Flexible Box Layout: @@ -79781,9 +79785,10 @@ dictionary ToggleEventInit : EventInit {
A node is a focus navigation scope owner if it is a Document
, a
- shadow host, a slot, or an element in the shadow host, a slot, an element in the popover showing state which also has a popover
- invoker set.
Each focus navigation scope owner has a focus navigation scope, which is a list of elements. Its contents are determined as follows:
@@ -79807,6 +79812,12 @@ dictionary ToggleEventInit : EventInit {If element is in the popover showing state and has a popover invoker set, then return element.
If element's parent is a reading-flow-ordered scope owner, then + return element's parent.
If element's parent is a reading flow item, then return + element's parent.
Return element's parent's associated focus navigation owner.
The order of elements within a focus navigation scope does not impact any of the algorithms in this specification. Ordering only becomes important for the - tabindex-ordered focus navigation scope and flattened tabindex-ordered focus - navigation scope concepts defined below.
+ tabindex-ordered focus navigation scope, flattened tabindex-ordered focus + navigation scope, and reading-flow-ordered focus navigation scope concepts + defined below.A tabindex-ordered focus navigation scope is a list of focusable areas and focus navigation @@ -79836,11 +79848,25 @@ dictionary ToggleEventInit : EventInit { is a negative integer.
-The order within a tabindex-ordered focus navigation scope is determined by each - element's tabindex value, as described in the section below.
+By default, the order within a tabindex-ordered focus navigation scope is + determined by each element's tabindex value. This ordering criteria is sometimes + overridden, as is the case with reading-flow-ordered focus navigation scopes.
+ +The tabindex value rules do not give a precise ordering, as they are + composed mostly of "should" statements and relative orderings.
-The rules there do not give a precise ordering, as they are composed mostly of - "should" statements and relative orderings.
+Every reading-flow-ordered scope owner's tabindex-ordered focus navigation + scope is specifically a reading-flow-ordered focus navigation scope. The order + within a reading-flow-ordered focus navigation scope is determined by the + reading flow order algorithm; the use of tabindex value only determines + an item's focusability, but does not affect order within the scope.
+ +The tabindex-ordered focus navigation scope of a reading flow + item — and any other focus navigation scope owner for that matter — is not + specifically a reading-flow-ordered focus navigation scope; it is a normal + tabindex-ordered focus navigation scope whose order is determined by tabindex + value as usual.
A flattened tabindex-ordered focus navigation scope is a list of focusable areas. Every focus navigation scope owner @@ -80000,7 +80026,8 @@ dictionary ToggleEventInit : EventInit { regardless.
-The user agent must allow the element to be considered as a focusable area and @@ -80013,7 +80040,7 @@ dictionary ToggleEventInit : EventInit { shadow-including tree order.
The user agent must allow the element to be considered as a focusable area and @@ -80067,6 +80094,289 @@ dictionary ToggleEventInit : EventInit { +
A reading-flow-ordered scope owner is either: CSSDISPLAY
+ +a reading flow container; or
an element delegating its rendering to its children whose CSS parent + box is a reading flow container.
A reading flow item is an element whose parent element is a + reading-flow-ordered scope owner.
+ +The reading flow order of a reading-flow-ordered focus navigation scope + scope is the ordered list of elements constructed as follows:
+ +Let output be « ».
Let owner be the focus navigation scope owner of + scope.
Assert: owner is a reading-flow-ordered scope + owner.
Let container be the reading flow container associated with + owner.
Let items be container's rendering-defined sibling reading + flow.
Assert: items is a list of reading flow items.
For each item of items:
+ +While item is not container:
+ +If scope contains item:
+ +If output does not contain + item, then append item to + output.
+ +Different items can share the same ancestor in + scope; only add it to output the first time it is encountered.
+Break.
Set item to the parent element of item within the flat + tree.
items can include descendants of
+ container that are not in scope. For example, when a direct child of
+ container has display: contents
:
The display: contents
child will be in scope, but not
+ in items.
The display: contents
's own children will not be in scope (their
+ associated focus navigation owner is their parent), but can be in
+ items.
This step includes in output the first inclusive ancestor of each + item that is also in scope. The result is that output is just + scope, but in reading flow order, as established by items.
+For each child of owner element's + children, in tree order:
+ +If scope contains child and + output does not contain child, then + append child to output.
Return output.
The following example shows how to get the flattened tabindex-ordered focus navigation
+ scope for wrapper
.
<!DOCTYPE html>
+<html lang="en">
+<head>
+ <style>
+ .wrapper { display: grid; reading-flow: grid-order; }
+ </style>
+</head>
+<body>
+ <div class="wrapper">
+ <div id="A" tabindex="0" style="order: 1">A
+ <div id="B" tabindex="1">B</div>
+ </div>
+ <div id="DC" tabindex="0" style="display: contents">
+ <div id="C" tabindex="0" style="order: 3">C
+ <div id="D" tabindex="0">D</div>
+ <div id="E" tabindex="2">E</div>
+ </div>
+ <div id="F" tabindex="0" style="order: 2">F</div>
+ </div>
+ <div id="PA" style="position: absolute; left: 100px;" tabindex="0">
+ <div id="G" tabindex="0">G</div>
+ </div>
+ <div id="H" tabindex="0" style="order: 4">H</div>
+ </div>
+</body>
+</html>
+
+
+
+ In this example, wrapper
is a reading-flow-ordered scope
+ owner, and thus has a reading-flow-ordered focus navigation scope. Its
+ reading flow order is computed as follows:
First, we get wrapper
's rendering-defined sibling reading
+ flow items as « A
, F
, C
, H
».
Next, we loop through items:
+ +A
is in scope, so it's added to
+ output.
F
is not in scope; its associated focus navigation
+ owner is DC
.
Set item to F
's parent element within the
+ flat tree, which is DC
.
DC
's is in scope, so it's added to
+ output.
C
is not in scope; it's associated focus
+ navigation owner is also DC
.
Set item to C
's parent element within the
+ flat tree, which is DC
.
DC
is in scope, but it's already in
+ output, so we do nothing.
H
is in scope, so it's added to
+ output.
output is now « A
, DC
, H
».
Finally, we loop through the children of wrapper
in tree order.
The only child that's in scope but not already in output is
+ PA
; it gets added to output.
output is now « A
, DC
, H
, PA
».
Notice that DC
is also a reading-flow-ordered scope owner;
+ the reading flow order of its reading-flow-ordered focus navigation
+ scope is computed as follows:
First, we compute DC
's reading flow container as
+ wrapper
.
Then, we again get wrapper
's rendering-defined sibling
+ reading flow items as « A
, F
,
+ C
, H
».
Next, we loop through items:
+ +A
is not in scope; its associated focus navigation
+ owner is wrapper
, not DC
.
Set item to be A
's parent element within the
+ flat tree, which is wrapper
.
While loop ends because item is container.
F
is in scope so it's added to
+ output.
C
is in scope so it's added to
+ output.
H
is not in scope; its associated focus navigation
+ owner is wrapper
, not DC
.
Set item to be H
's parent element within the
+ flat tree, which is wrapper
.
While loop ends because item is container.
output is now « F
, C
+ ».
Finally, we loop through the children of wrapper
in tree order:
There are no children that are not already in + output, so we add nothing to output.
Each of A
, C
, F
, PA
, and H
are reading
+ flow items, and the focus navigation scope owner of a tabindex-ordered
+ focus navigation scope that does not follow the reading flow order. For
+ example, the tabindex-ordered focus navigation scope of C
is
+ « E
, D
», because E
has a
+ higher positive tabindex value than D
.
Finally, when computing the flattened tabindex-ordered focus navigation scope of
+ wrapper
, the two reading-flow-ordered focus navigation scopes we computed above, along with every
+ ordinary tabindex-ordered focus navigation scope previously mentioned, are all
+ recursively composed to form the following: « A
, B
,
+ DC
, F
, C
, E
, D
, H
, PA
, G
».
Document
.
+ As a reading-flow-ordered focus navigation scope is a + tabindex-ordered focus navigation scope, it is flattened in reading flow + order into a flattened tabindex-ordered focus navigation scope.
+If a focusable area is omitted from the sequential focus navigation
order of its Document
, then it is unreachable via sequential focus
navigation.
If candidate is a navigable container with a non-null content - navigable, then:
+ navigable:Let recursive candidate be the result of running the sequential