Fork me on GitHub

Web Selection Examples

Review of how selection interaction works in different layout models on the web.

Summary

Layout ModelContentHighlight
DOMUserDOMUser
Absolute
Flexbox
Regions *
Multicol *
Grid
Shadow DOM

Notes

We're testing similar selections with different layout models, to confirm that the current behavior matches what user expect. User expectations can be subjective and different layout models may require different selection behaviors.

For each layout model we're showing the DOM tree (using Node::showTreeForThis()) and render tree (using RenderObject::showRenderTreeForThis()).

Each HTML example is performing a selection on load. Check JavaScript console (or copy-and-past) to see the selection's content.

Absolute positions

example

  • Test: Select from content-1 to content-2.
  • Result:
    • Content: It ignores absolute-1. This is right according to DOM tree. This is wrong from the user's point of view.
    • Highlight: Selection highlighting extends from from content-1 to content-2 ignoring absolute-1. This is right according to DOM tree. This is wrong from the user's point of view.
content-1
absolute-1
content-2
BODY    0x1e6017408008
    #text   0x1e601740c188 "\n    "
    DIV 0x1e6017408170
        #text   0x1e601740c1e8 "absolute-1"
    #text   0x1e601740c248 "\n    "
    DIV 0x1e60174081e8
        #text   0x1e601740c2a8 "content-1"
    #text   0x1e601740c308 "\n    "
    DIV 0x1e6017408260
        #text   0x1e601740c368 "content-2"
    #text   0x1e601740c3c8 "\n\n\n"
RenderView 0x398fba004008               #document   0x1e6017404008
  RenderBlock 0x398fba00c008            HTML    0x1e60174080f8
    RenderBody 0x398fba00c108           BODY    0x1e6017408008
      RenderBlock (positioned) 0x398fba00c308   DIV 0x1e60174081e8
        RenderText 0x398fba0100a0       #text   0x1e601740c2a8 "absolute-1"
      RenderBlock (positioned) 0x398fba00c208   DIV 0x1e6017408170
        RenderText 0x398fba010008       #text   0x1e601740c1e8 "content-1"
      RenderBlock (positioned) 0x398fba00c408   DIV 0x1e6017408260
        RenderText 0x398fba010138       #text   0x1e601740c368 "content-2"

Flexbox

example

  • Test: Select from content-1 to content-3.
  • Result:
    • Content: It ignores content2. This is right according to DOM tree. This is wrong from the user's point of view.
    • Highlight: Selection highlighting extends from from content-1 to content-3 ignoring content-2. This is right according to DOM tree. This is wrong from the user's point of view (content-2 should be selected).
content-1
content-2
content-3
BODY    0x1b1b7c808008
    #text   0x1b1b7c80c188 "\n    "
    DIV 0x1b1b7c808170
        #text   0x1b1b7c80c1e8 "\n        "
        DIV 0x1b1b7c8081e8 STYLE=-webkit-order: 1;
            #text   0x1b1b7c80c248 "content-2"
        #text   0x1b1b7c80c2a8 "\n        "
        DIV 0x1b1b7c808260 STYLE=-webkit-order: 0;
            #text   0x1b1b7c80c308 "content-1"
        #text   0x1b1b7c80c368 "\n        "
        DIV 0x1b1b7c8082d8 STYLE=-webkit-order: 2;
            #text   0x1b1b7c80c3c8 "content-3"
        #text   0x1b1b7c80c428 "\n    "
    #text   0x1b1b7c80c488 "\n\n\n\n"
RenderView 0x3963bd804008               #document   0x1b1b7c804008
  RenderBlock 0x3963bd80c008            HTML    0x1b1b7c8080f8
    RenderBody 0x3963bd80c108           BODY    0x1b1b7c808008
      RenderFlexibleBox 0x3963bd810008  DIV 0x1b1b7c808170
        RenderBlock 0x3963bd80c208      DIV 0x1b1b7c8081e8 STYLE=-webkit-order: 1;
          RenderText 0x3963bd814008     #text   0x1b1b7c80c248 "content-2"
        RenderBlock 0x3963bd80c308      DIV 0x1b1b7c808260 STYLE=-webkit-order: 0;
          RenderText 0x3963bd8140a0     #text   0x1b1b7c80c308 "content-1"
        RenderBlock 0x3963bd80c408      DIV 0x1b1b7c8082d8 STYLE=-webkit-order: 2;
          RenderText 0x3963bd814138     #text   0x1b1b7c80c3c8 "content-3"

Regions

example

  • Test: Select from content-1 to content-2.
  • Result:
    • Content: It ignores source-1. This is right according to DOM tree. This is wrong from the user's point of view.
    • Highlight: Selection highlighting extends from from content-1 to content-2 including source-1 (which is not actually selected but highlighted due to gaps filling). This is wrong according to DOM tree (source-1 shouldn't be highlighted due to gaps filling). This is wrong from the user's point of view (source-1 should be actually selected).
content-1
source-1
content-2
BODY    0x3a2254208008
    #text   0x3a225420c188 "\n    "
    DIV 0x3a2254208170
        #text   0x3a225420c1e8 "source-1"
    #text   0x3a225420c248 "\n    "
    DIV 0x3a22542081e8
        #text   0x3a225420c2a8 "content-1"
    #text   0x3a225420c308 "\n    "
    DIV 0x3a2254208260
    #text   0x3a225420c368 "\n    "
    DIV 0x3a22542082d8
        #text   0x3a225420c3c8 "content-2"
    #text   0x3a225420c428 "\n\n\n"
RenderView 0x261b3e004008               #document   0x3a2254204008
  RenderBlock 0x261b3e00c008            HTML    0x3a22542080f8
    RenderBody 0x261b3e00c108           BODY    0x3a2254208008
      RenderBlock 0x261b3e00c308        DIV 0x3a22542081e8
        RenderText 0x261b3e0140a0       #text   0x3a225420c2a8 "content-1"
      RenderBlock 0x261b3e00c408        DIV 0x3a2254208260
        RenderNamedFlowFragment 0x261b3e018008
      RenderBlock 0x261b3e00c508        DIV 0x3a22542082d8
        RenderText 0x261b3e014138       #text   0x3a225420c3c8 "content-2"
  RenderNamedFlowThread 0x261b3e010008
    RenderBlock 0x261b3e00c208          DIV 0x3a2254208170
      RenderText 0x261b3e014008         #text   0x3a225420c1e8 "source-1"

Multicol

example

  • Test: Select from content-1 to content-2.
  • Result:
    • Content: It includes span-content. This is right according to DOM tree. This is wrong from the user's point of view.
    • Highlight: Selection highlighting extends from from content-1 to content-2 ignoring span-content. This is wrong according to DOM tree (span-content should be highlighted). This is right from the user's point of view (span-content is ignored).
content-1
span-content
content-2
BODY    0x1bab9f0
    #text   0x1a501e0 "\n    "
    DIV 0x1baba90
        #text   0x1a4f370 "\n        "
        DIV 0x1a4f3d0
            #text   0x1a4f4b0 "content-1"
        #text   0x1a4f540 "\n        "
        DIV 0x1a50310
            #text   0x1a503c0 "span-content"
        #text   0x1a7ff80 "\n        "
        DIV 0x1a7ffe0
            #text   0x1a80050 "content-2"
        #text   0x1a800e0 "\n    "
    #text   0x1a80140 "\n\n\n"
RenderView 0x1933e10
  RenderBlock 0x1a811b0                 HTML    0x1baa3a0
    RenderBody 0x1a81620                BODY    0x1bab9f0
      RenderBlock 0x1a82b90             DIV 0x1baba90
        RenderMultiColumnFlowThread 0x1a83c50 Rs:0x1a81940 Re:0x1a81e30
          RenderBlock 0x1a83000 Rs:0x1a81940 Re:0x1a81e30   DIV 0x1a4f3d0
            RenderText 0x1a83120        #text   0x1a4f4b0 "content-1"
          RenderMultiColumnSpannerPlaceholder 0x1a81c00 Rs:0x1a81940 Re:0x1a81e30
          RenderBlock 0x1a83510 Rs:0x1a81e30 Re:0x1a81e30   DIV 0x1a7ffe0
            RenderText 0x1a83660        #text   0x1a80050 "content-2"
        RenderMultiColumnSet 0x1a81940
        RenderBlock 0x1a83200           DIV 0x1a50310
          RenderText 0x1a834a0          #text   0x1a503c0 "span-content"
        RenderMultiColumnSet 0x1a81e30

Grid

example

  • Test: Select from content-1 to content-3.
  • Result:
    • Content: It ignores content-2. This is right according to DOM tree. This is wrong from the user's point of view.
    • Highlight: Selection highlighting extends from from content-1 to content-3 ignoring content-2. This is right according to DOM tree. This is wrong from the user's point of view.
content-1
content-2
content-3
BODY    0x48198e10008
    #text   0x48198e20188 "\n    "
    DIV 0x48198e10170
        #text   0x48198e201e8 "\n        "
        DIV 0x48198e101e8
            #text   0x48198e20248 "content-2"
        #text   0x48198e202a8 "\n        "
        DIV 0x48198e10260
            #text   0x48198e20308 "content-1"
        #text   0x48198e20368 "\n        "
        DIV 0x48198e102d8
            #text   0x48198e203c8 "content-3"
        #text   0x48198e20428 "\n    "
    #text   0x48198e20488 "\n\n\n"
RenderView 0x3d1520204008               #document   0x48198e04008
  RenderBlock 0x3d1520214008            HTML    0x48198e100f8
    RenderBody 0x3d1520214108           BODY    0x48198e10008
      RenderGrid 0x3d1520218008         DIV 0x48198e10170
        RenderBlock 0x3d1520214208      DIV 0x48198e101e8
          RenderText 0x3d1520228008     #text   0x48198e20248 "content-2"
        RenderBlock 0x3d1520214308      DIV 0x48198e10260
          RenderText 0x3d15202280a0     #text   0x48198e20308 "content-1"
        RenderBlock 0x3d1520214408      DIV 0x48198e102d8
          RenderText 0x3d1520228138     #text   0x48198e203c8 "content-3"

Shadow DOM

example

  • Test: Select from content-1 to content-2.
  • Result:
    • Content: It ignores shadow-1. This is right according to the original DOM tree. This is wrong from the user's point of view.
    • Highlight: Selection highlighting extends from from content-1 to content-2 including shadow-1. This is wrong according to the original DOM tree. This is right from the user's point of view.
content-1
shadow-1
content-2
BODY   0x20d27f4141a8
    #text   0x20d27f420160 "\n    "
    DIV 0x20d27f414230 ID="content-1"
        #text   0x20d27f4201d0 "content-1"
    #text   0x20d27f420240 "\n    "
    DIV 0x20d27f4142b8 ID="shadow-1"
        #document-fragment  0x20d27f440010
            #text   0x20d27f420470 "shadow-1"
    #text   0x20d27f4202b0 "\n    "
    DIV 0x20d27f414340 ID="content-2"
        #text   0x20d27f420320 "content-2"
    #text   0x20d27f420390 "\n    "
    SCRIPT  0x20d27f4300a8
        #text   0x20d27f420400 "\n        var shadow = document.getElementById("shadow-1");\n        var shadowRoot = shadow.createShadowRoot();\n        shadowRoot.appendChild(document.createTextNode("shadow-1"));\n\n        select("content-1", "content-2");\n    "
RenderView 0x2afd16004010                  #document   0x20d27f404010
  RenderBlock 0x2afd16020010            HTML    0x20d27f414098
    RenderBody 0x2afd16020110           BODY    0x20d27f4141a8
      RenderBlock 0x2afd16020210        DIV 0x20d27f414230 ID="content-1"
       RenderText 0x2afd16024010        #text   0x20d27f4201d0 "content-1"
      RenderBlock 0x2afd16020310        DIV 0x20d27f4142b8 ID="shadow-1"
        RenderText 0x2afd160240a8       #text   0x20d27f420470 "shadow-1"
      RenderBlock 0x2afd16020410        DIV 0x20d27f414340 ID="content-2"
        RenderText 0x2afd16024140       #text   0x20d27f420320 "content-2"