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 child concept
  • The root and shadow-including root concepts
  • The inclusive ancestor, + ancestor, descendant, shadow-including ancestor, shadow-including descendant, @@ -3818,6 +3819,9 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • inline formatting context
  • replaced element
  • CSS box
  • +
  • CSS parent box
  • +
  • reading flow container
  • +
  • rendering-defined sibling reading flow
  • 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.

    + invoker set, a reading-flow-ordered scope owner, or a reading flow + item.

    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.

  • @@ -79816,8 +79827,9 @@ dictionary ToggleEventInit : EventInit {

    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.

    -
    If the value is a zero
    +
    If the value is either a zero, or
    +
    If the value is greater than zero and the element is a reading flow item

    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.

    -
    If the value is greater than zero
    +
    If the value is greater than zero and the element is not a reading flow item

    The user agent must allow the element to be considered as a focusable area and @@ -80067,6 +80094,289 @@ dictionary ToggleEventInit : EventInit { +

    + +

    Reading flow

    + +

    A reading-flow-ordered scope owner is either: CSSDISPLAY

    + + + +

    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:

    + +
      +
    1. Let output be « ».

    2. + +
    3. Let owner be the focus navigation scope owner of + scope.

    4. + +
    5. Assert: owner is a reading-flow-ordered scope + owner.

    6. + +
    7. Let container be the reading flow container associated with + owner.

    8. + +
    9. Let items be container's rendering-defined sibling reading + flow.

    10. + +
    11. Assert: items is a list of reading flow items.

    12. + +
    13. +

      For each item of items:

      + +
        +
      1. +

        While item is not container:

        + +
          +
        1. +

          If scope contains item:

          + +
            +
          1. +

            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.

            +
          2. + +
          3. Break.

          4. +
          +
        2. + +
        3. Set item to the parent element of item within the flat + tree.

        4. +
        +
      2. +
      + +
      +

      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.

      +
      +
    14. + +
    15. +

      For each child of owner element's + children, in tree order:

      + +
        +
      1. If scope contains child and + output does not contain child, then + append child to output.

      2. +
      +
    16. + +
    17. Return output.

    18. +
    + +
    + +
    +

    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:

    + + + +

    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:

    + + + +

    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 ».

    +
    +

    Processing model

    @@ -80528,6 +80838,10 @@ dictionary ToggleEventInit : EventInit { scope, the ordering is not necessarily related to the tree order of the 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.

    @@ -80693,7 +81007,7 @@ dictionary ToggleEventInit : EventInit {
  • If candidate is a navigable container with a non-null content - navigable, then:

    + navigable:

    1. Let recursive candidate be the result of running the sequential