marker-supported-properties-in-animation.html (9274B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>CSS Pseudo-Elements Test: Supported properties in ::marker animations</title> 4 <link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo"> 5 <link rel="help" href="https://drafts.csswg.org/css-animations-1/#keyframes"> 6 <link rel="help" href="https://drafts.csswg.org/css-transitions-1/#transitions"> 7 <link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> 8 <meta name="assert" content="This test checks ::marker supports animations and transitions, but only for the properties that apply to ::marker." /> 9 <style id="style"></style> 10 <script src="/resources/testharness.js"></script> 11 <script src="/resources/testharnessreport.js"></script> 12 <div id="log"></div> 13 <ul> 14 <li id="target">target</li> 15 </ul> 16 <script> 17 const interpolationTests = [ 18 // ::marker supports all font properties. 19 { 20 property: "font", 21 from: "oblique normal 100 ultra-condensed 5px / 20px serif", 22 to: "italic small-caps 900 ultra-expanded 25px / 50px Ahem", 23 midPoint: ["italic small-caps 500 expanded 15px / 35px Ahem", "italic small-caps 500 expanded 15px/35px Ahem"], 24 }, 25 { 26 property: "font-family", 27 from: "serif", 28 to: "Ahem", 29 midPoint: "Ahem", 30 }, 31 { 32 property: "font-feature-settings", 33 from: "'c2sc'", 34 to: "'smcp'", 35 midPoint: "\"smcp\"", 36 }, 37 { 38 property: "font-kerning", 39 from: "normal", 40 to: "none", 41 midPoint: "none", 42 }, 43 { 44 property: "font-size", 45 from: "5px", 46 to: "25px", 47 midPoint: "15px", 48 }, 49 { 50 property: "font-size-adjust", 51 from: "1", 52 to: "3", 53 midPoint: "2", 54 }, 55 { 56 property: "font-stretch", 57 from: "ultra-condensed", 58 to: "ultra-expanded", 59 midPoint: ["expanded", "125%"], 60 }, 61 { 62 property: "font-style", 63 from: "oblique", 64 to: "italic", 65 midPoint: "italic", 66 }, 67 { 68 property: "font-synthesis", 69 from: "weight", 70 to: "none", 71 midPoint: "none", 72 }, 73 { 74 property: "font-synthesis-small-caps", 75 from: "auto", 76 to: "none", 77 midPoint: "none", 78 }, 79 { 80 property: "font-synthesis-style", 81 from: "auto", 82 to: "none", 83 midPoint: "none", 84 }, 85 { 86 property: "font-synthesis-weight", 87 from: "auto", 88 to: "none", 89 midPoint: "none", 90 }, 91 { 92 property: "font-variant", 93 from: "unicase", 94 to: "small-caps", 95 midPoint: "small-caps", 96 }, 97 { 98 property: "font-variant-caps", 99 from: "unicase", 100 to: "small-caps", 101 midPoint: "small-caps", 102 }, 103 { 104 property: "font-variant-east-asian", 105 from: "proportional-width", 106 to: "full-width", 107 midPoint: "full-width", 108 }, 109 { 110 property: "font-variant-ligatures", 111 from: "no-historical-ligatures", 112 to: "historical-ligatures", 113 midPoint: "historical-ligatures", 114 }, 115 { 116 property: "font-variant-numeric", 117 from: "ordinal", 118 to: "slashed-zero", 119 midPoint: "slashed-zero", 120 }, 121 { 122 property: "font-variant-position", 123 from: "super", 124 to: "sub", 125 midPoint: "sub", 126 }, 127 { 128 property: "font-weight", 129 from: "100", 130 to: "900", 131 midPoint: "500", 132 }, 133 134 // `line-height` is not a font property but is a longhand of `font`, and is also supported. 135 { 136 property: "line-height", 137 from: "20px", 138 to: "50px", 139 midPoint: "35px", 140 }, 141 142 // ::marker supports `white-space` 143 { 144 property: "white-space", 145 from: "pre-line", 146 to: "nowrap", 147 midPoint: "nowrap", 148 }, 149 150 // ::marker supports `color` 151 { 152 property: "color", 153 from: "rgb(0, 100, 200)", 154 to: "rgb(100, 200, 0)", 155 midPoint: "rgb(50, 150, 100)", 156 }, 157 158 // ::marker supports `text-combine-upright`, `unicode-bidi` and `direction`, 159 // but they are not animatable. 160 { 161 property: "text-combine-upright", 162 from: "all", 163 to: "all", 164 midPoint: null, 165 }, 166 { 167 property: "unicode-bidi", 168 from: "embed", 169 to: "plaintext", 170 midPoint: null, 171 }, 172 { 173 property: "direction", 174 from: "rtl", 175 to: "rtl", 176 midPoint: null, 177 }, 178 179 // ::marker supports `content` 180 { 181 property: "content", 182 from: "'foo'", 183 to: "'bar'", 184 midPoint: "\"bar\"", 185 }, 186 187 // ::marker supports text properties. 188 { 189 property: "hyphens", 190 from: "manual", 191 to: "none", 192 midPoint: "none", 193 }, 194 { 195 property: "letter-spacing", 196 from: "0px", 197 to: "20px", 198 midPoint: "10px", 199 }, 200 { 201 property: "line-break", 202 from: "strict", 203 to: "anywhere", 204 midPoint: "anywhere", 205 }, 206 { 207 property: "overflow-wrap", 208 from: "break-word", 209 to: "anywhere", 210 midPoint: "anywhere", 211 }, 212 { 213 property: "tab-size", 214 from: "0px", 215 to: "20px", 216 midPoint: "10px", 217 }, 218 { 219 property: "text-transform", 220 from: "lowercase", 221 to: "uppercase", 222 midPoint: "uppercase", 223 }, 224 { 225 property: "word-break", 226 from: "break-all", 227 to: "break-word", 228 midPoint: "break-word", 229 }, 230 { 231 property: "word-spacing", 232 from: "0px", 233 to: "20px", 234 midPoint: "10px", 235 }, 236 237 // ::marker supports inherited text decoration properties. 238 { 239 property: "text-decoration-skip-ink", 240 from: "auto", 241 to: "none", 242 midPoint: "none", 243 }, 244 { 245 property: "text-emphasis", 246 from: "dot rgb(0, 200, 0)", 247 to: "triangle rgb(100, 0, 200)", 248 midPoint: "triangle rgb(50, 100, 100)", 249 }, 250 { 251 property: "text-emphasis-color", 252 from: "rgb(0, 200, 0)", 253 to: "rgb(100, 0, 200)", 254 midPoint: "rgb(50, 100, 100)", 255 }, 256 { 257 property: "text-emphasis-position", 258 from: "over right", 259 to: "under left", 260 midPoint: "under left", 261 }, 262 { 263 property: "text-emphasis-style", 264 from: "filled dot", 265 to: "filled triangle", 266 midPoint: "triangle", 267 }, 268 { 269 property: "text-shadow", 270 from: "rgb(0, 200, 0) 1px 2px 3px", 271 to: "rgb(100, 0, 200) 3px 2px 1px", 272 midPoint: "rgb(50, 100, 100) 2px 2px 2px", 273 }, 274 275 // ::marker supports `cursor`. 276 { 277 property: "cursor", 278 from: "auto", 279 to: "move", 280 midPoint: "move", 281 }, 282 283 // ::marker does NOT support layout properties 284 { 285 property: "display", 286 from: "flex", 287 to: "none", 288 midPoint: ["block", "inline", "inline-block"], 289 }, 290 { 291 property: "position", 292 from: "fixed", 293 to: "absolute", 294 midPoint: "static", 295 }, 296 { 297 property: "float", 298 from: "left", 299 to: "right", 300 midPoint: "none", 301 }, 302 303 // ::marker does NOT support list properties despite being affected by them, 304 // they apply to the list item instead. 305 { 306 property: "list-style", 307 from: "inside url('foo') square", 308 to: "inside url('bar') decimal", 309 midPoint: "outside none disc", 310 }, 311 { 312 property: "list-style-image", 313 from: "url('foo')", 314 to: "url('bar')", 315 midPoint: "none", 316 }, 317 { 318 property: "list-style-position", 319 from: "inside", 320 to: "inside", 321 midPoint: "outside", 322 }, 323 { 324 property: "list-style-type", 325 from: "square", 326 to: "decimal", 327 midPoint: "disc", 328 }, 329 ]; 330 331 const target = document.getElementById("target"); 332 const styleElement = document.getElementById("style"); 333 const markerStyle = getComputedStyle(target, "::marker"); 334 335 function check({property, from, to, midPoint}) { 336 assert_true(property in markerStyle, property + " doesn't seem to be supported in the computed style"); 337 assert_true(CSS.supports(property, from), `'${from}' is a supported value for ${property}.`); 338 assert_true(CSS.supports(property, to), `'${to}' is a supported value for ${property}.`); 339 const computed = markerStyle.getPropertyValue(property); 340 if (Array.isArray(midPoint)) { 341 assert_in_array(computed, midPoint); 342 } else { 343 assert_equals(computed, midPoint); 344 } 345 } 346 347 function testAnimations(interpolationTests) { 348 styleElement.textContent = ` 349 ::marker { 350 animation: anim 2s -1s paused linear; 351 } 352 @keyframes anim { 353 from {} 354 to {} 355 } 356 `; 357 const keyframes = styleElement.sheet.cssRules[1]; 358 const fromStyle = keyframes.cssRules[0].style; 359 const toStyle = keyframes.cssRules[1].style; 360 for (let {property, from, to, midPoint} of interpolationTests) { 361 fromStyle.cssText = ""; 362 toStyle.cssText = ""; 363 if (midPoint == null) { 364 midPoint = markerStyle.getPropertyValue(property); 365 } 366 fromStyle.setProperty(property, from); 367 toStyle.setProperty(property, to); 368 test(() => { 369 check({property, from, to, midPoint}); 370 }, `Animation of ${property} in ::marker`); 371 } 372 } 373 374 function testTransitions(interpolationTests) { 375 styleElement.textContent = ` 376 .transition::marker { 377 transition: all 2s -1s linear; 378 } 379 .from::marker {} 380 .to::marker {} 381 `; 382 const fromStyle = styleElement.sheet.cssRules[1].style; 383 const toStyle = styleElement.sheet.cssRules[2].style; 384 for (let {property, from, to, midPoint} of interpolationTests) { 385 fromStyle.cssText = ""; 386 toStyle.cssText = ""; 387 if (midPoint == null) { 388 midPoint = to; 389 } 390 fromStyle.setProperty(property, from); 391 toStyle.setProperty(property, to); 392 target.className = "from"; 393 markerStyle.width; 394 target.classList.add("transition"); 395 markerStyle.width; 396 target.classList.add("to"); 397 test(() => { 398 check({property, from, to, midPoint}); 399 }, `Transition of ${property} in ::marker`); 400 } 401 } 402 403 testAnimations(interpolationTests); 404 testTransitions(interpolationTests); 405 </script>