content-visibility-068.html (3051B)
1 <!doctype HTML> 2 <html> 3 <meta charset="utf8"> 4 <title>Content Visibility: off-screen focus</title> 5 <link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> 6 <link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility"> 7 <meta name="assert" content="content-visibility auto element remains non-skipped when elements in its subtree have focus."> 8 9 <script src="/resources/testharness.js"></script> 10 <script src="/resources/testharnessreport.js"></script> 11 12 <style> 13 body, html { 14 padding: 0; 15 margin: 0; 16 } 17 18 .spacer { 19 height: 3000px; 20 background: lightblue; 21 } 22 #container { 23 background: lightgreen; 24 contain-intrinsic-size: 50px 100px; 25 content-visibility: auto; 26 } 27 #focusable { 28 width: 10px; 29 height: 10px; 30 } 31 </style> 32 33 <div id=end tabindex=1></div> 34 <div class=spacer></div> 35 <div id=container> 36 <div id=focusable tabindex=0></div> 37 </div> 38 <div class=spacer></div> 39 40 <script> 41 async_test((t) => { 42 // Initially container should be 3000px offscreen with contained height 100px. 43 function step1() { 44 const r = container.getBoundingClientRect(); 45 t.step(() => { 46 assert_equals(r.y, 3000, "step1 offset"); 47 assert_equals(r.height, 100, "step1 height"); 48 }); 49 50 focusable.focus(); 51 step_timeout(step2, 0); 52 } 53 // After focusing the subtree, the container should be somewhere closer than 54 // 3000px (scrolled into view) and the height should be 10px, since it no 55 // longer has containment. 56 function step2() { 57 const r = container.getBoundingClientRect(); 58 t.step(() => { 59 assert_less_than(r.y, 3000, "step2 offset"); 60 assert_equals(r.height, 10, "step2 height"); 61 }); 62 document.scrollingElement.scrollTop = 0; 63 requestAnimationFrame(step3); 64 } 65 // After scrolling the document back to the top, the container should be back 66 // at 3000px but because its subtree is still focused, it should have height 67 // 10px. 68 function step3() { 69 const r = container.getBoundingClientRect(); 70 t.step(() => { 71 assert_equals(r.y, 3000, "step3 offset"); 72 assert_equals(r.height, 10, "step3 height"); 73 }); 74 requestAnimationFrame(step4); 75 } 76 // This is a repeat of step3, to ensure that this is a stable state. 77 function step4() { 78 const r = container.getBoundingClientRect(); 79 t.step(() => { 80 assert_equals(r.y, 3000, "step4 offset"); 81 assert_equals(r.height, 10, "step4 height"); 82 }); 83 84 // We don't use `blur()` here because in Gecko this leaves the selection 85 // on _focusable_ which means that its content is still relevant. Focusing 86 // another element will move both focus and selection. 87 end.focus(); 88 requestAnimationFrame(step5); 89 } 90 // After blurring the focused element, we keep the last rendered size, see 91 // https://github.com/w3c/csswg-drafts/issues/8407. 92 function step5() { 93 const r = container.getBoundingClientRect(); 94 t.step(() => { 95 assert_equals(r.y, 3000, "step5 offset"); 96 assert_equals(r.height, 10, "step5 height"); 97 }); 98 t.done(); 99 } 100 step1(); 101 }); 102 </script> 103 </html>