content-visibility-layout-containment-001.html (5838B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>content-visibility and layout containment</title> 4 <link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility"> 5 <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1765615"> 6 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 <script src="/common/rendering-utils.js"></script> 10 <meta name="assert" content="content-visibility: auto and elements skipping their content change the used value of the contain property to turn on layout containment."> 11 <style> 12 /* Selectors for content-visibility */ 13 #spacer_for_far_to_viewport { 14 height: 300vh; 15 } 16 .content_visibility { 17 /* Dynamic modification of content-visibility may change whether style 18 containment is applied, which in turn may cause drastic invalidations 19 (e.g. rebuilding counters). Make the test more robust by forcing 20 style containment to always apply. */ 21 contain: style; 22 } 23 #visible .content_visibility { 24 content-visibility: visible; 25 } 26 #hidden .content_visibility { 27 content-visibility: hidden; 28 } 29 #auto_far .content_visibility { 30 content-visibility: auto; 31 } 32 #auto_close .content_visibility { 33 content-visibility: auto; 34 } 35 #visible_to_hidden .content_visibility { 36 content-visibility: visible; 37 } 38 #hidden_to_visible .content_visibility { 39 content-visibility: hidden; 40 } 41 #visible_to_auto .content_visibility { 42 content-visibility: visible; 43 } 44 #auto_to_visible .content_visibility { 45 content-visibility: auto; 46 } 47 48 /* Selectors for testing baseline */ 49 .flex { 50 display: inline-flex; 51 align-items: baseline; 52 } 53 .rect { 54 background: black; 55 width: 50px; 56 height: 100px; 57 } 58 </style> 59 <body> 60 <div id="log"></div> 61 62 <div id="visible"> 63 <div class="flex"> 64 <div class="rect"></div> 65 <div class="content_visibility rect">X</div> 66 </div> 67 </div> 68 69 <div id="hidden"> 70 <div class="flex"> 71 <div class="rect"></div> 72 <div class="content_visibility rect">X</div> 73 </div> 74 </div> 75 76 <div id="auto_close"> 77 <div class="flex"> 78 <div class="rect"></div> 79 <div class="content_visibility rect">X</div> 80 </div> 81 </div> 82 83 <div id="visible_to_hidden"> 84 <div class="flex"> 85 <div class="rect"></div> 86 <div class="content_visibility rect">X</div> 87 </div> 88 </div> 89 90 <div id="hidden_to_visible"> 91 <div class="flex"> 92 <div class="rect"></div> 93 <div class="content_visibility rect">X</div> 94 </div> 95 </div> 96 97 <div id="visible_to_auto"> 98 <div class="flex"> 99 <div class="rect"></div> 100 <div class="content_visibility rect">X</div> 101 </div> 102 </div> 103 104 <div id="auto_to_visible"> 105 <div class="flex"> 106 <div class="rect"></div> 107 <div class="content_visibility rect">X</div> 108 </div> 109 </div> 110 111 <div id="spacer_for_far_to_viewport"></div> 112 113 <div id="auto_far"> 114 <div class="flex"> 115 <div class="rect"></div> 116 <div class="content_visibility rect">X</div> 117 </div> 118 </div> 119 120 <script> 121 function layoutContainmentApplied(id) { 122 let container = document.getElementById(id); 123 let content_visibility = container.getElementsByClassName("content_visibility")[0]; 124 125 // To verify layout containment, we test baseline suppression. 126 // See contain-layout-dynamic-001.html for more details. 127 let item1 = content_visibility; 128 let item2 = item1.previousElementSibling; 129 return Math.abs(item1.getBoundingClientRect().top - item2.getBoundingClientRect().top) <= 1; 130 } 131 132 function setContentVisibility(id, value) { 133 let container = document.getElementById(id); 134 let content_visibility = container.getElementsByClassName("content_visibility")[0]; 135 content_visibility.style.contentVisibility = value; 136 } 137 138 promise_test(async () => { 139 await document.fonts.ready; 140 assert_false(layoutContainmentApplied("visible")); 141 }, "content-visibility: visible"); 142 143 promise_test(async () => { 144 await document.fonts.ready; 145 assert_true(layoutContainmentApplied("hidden")); 146 }, "content-visibility: hidden"); 147 148 promise_test(async () => { 149 await document.fonts.ready; 150 await waitForAtLeastOneFrame(); 151 assert_true(layoutContainmentApplied("auto_far")); 152 }, "content-visibility: auto (far from viewport)"); 153 154 promise_test(async () => { 155 await document.fonts.ready; 156 await waitForAtLeastOneFrame(); 157 assert_true(layoutContainmentApplied("auto_close")); 158 }, "content-visibility: auto (close from viewport)"); 159 160 promise_test(async () => { 161 await document.fonts.ready; 162 setContentVisibility("visible_to_hidden", "hidden"); 163 assert_true(layoutContainmentApplied("visible_to_hidden")); 164 }, "switching content-visibility from visible to hidden"); 165 166 promise_test(async () => { 167 await document.fonts.ready; 168 setContentVisibility("hidden_to_visible", "visible"); 169 assert_false(layoutContainmentApplied("hidden_to_visible")); 170 }, "switching content-visibility from hidden to visible"); 171 172 promise_test(async () => { 173 await document.fonts.ready; 174 setContentVisibility("visible_to_auto", "auto"); 175 await waitForAtLeastOneFrame(); 176 assert_true(layoutContainmentApplied("visible_to_auto")); 177 }, "switching content-visibility from visible to auto"); 178 179 promise_test(async () => { 180 await document.fonts.ready; 181 setContentVisibility("auto_to_visible", "visible"); 182 assert_false(layoutContainmentApplied("auto_to_visible")); 183 }, "switching content-visibility from auto to visible"); 184 </script> 185 </body>