registered-property-computation.html (8246B)
1 <!DOCTYPE html> 2 <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#calculation-of-computed-values" /> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script src="./resources/utils.js"></script> 6 7 <style> 8 #divWithFontSizeSet, #parentDiv { 9 font-size: 10px; 10 line-height: 20px; 11 color: blue; 12 } 13 </style> 14 15 <div id=divWithFontSizeSet></div> 16 <div id=parentDiv> 17 <div id=divWithFontSizeInherited></div> 18 </div> 19 <div id="ref"></div> 20 21 <script> 22 23 // Generate a property and temporarily set its value. Then call 'fn' with 24 // the name of the generated property. 25 function with_custom_property(element, reg, value, fn) { 26 if (element.id.length == 0) 27 throw 'The specified element must have an ID'; 28 29 let name = generate_property(reg); 30 31 // Because we want to include the parsing step, insert a stylesheet 32 // node with textContent. 33 let node = document.createElement('style'); 34 node.textContent = `#${element.id} { ${name}:${value}; }`; 35 document.body.append(node); 36 37 try { 38 fn(name); 39 } finally { 40 node.remove(); 41 } 42 } 43 44 function assert_computed_value(element, syntax, value, expected) { 45 with_custom_property(element, syntax, value, (name) => { 46 let actual = getComputedStyle(element).getPropertyValue(name); 47 assert_equals(actual, expected); 48 }); 49 } 50 51 // Computes an absolute reference value for some length. 52 // 53 // E.g. to figure out how many pixels '10vh' is, do length_ref('10vh'). 54 function length_ref(value, refnode = ref) { 55 try { 56 // The reference property 'min-height' is chosen arbitrarily, but 57 // avoid properties with "resolved value is used value"-behavior 58 // [1], as it may affect rounding, and custom properties do not 59 // have this behavior. 60 // 61 // [1] https://drafts.csswg.org/cssom/#resolved-values 62 const ref_property = 'min-height'; 63 refnode.style = `${ref_property}: ${value}`; 64 return getComputedStyle(refnode).getPropertyValue(ref_property); 65 } finally { 66 refnode.style = ''; 67 } 68 } 69 70 function test_computed_value(syntax, value, expected) { 71 test(function() { 72 assert_computed_value(divWithFontSizeSet, syntax, value, expected); 73 }, `${syntax} values are computed correctly [${value}]`); 74 } 75 76 test(function(){ 77 const element = divWithFontSizeSet; 78 with_custom_property(element, '<length>', '14em', (name) => { 79 assert_computed_value(element, '<length>', `var(${name})`, '140px'); 80 }); 81 }, '<length> values computed are correctly via var()-reference'); 82 83 test(function(){ 84 const element = divWithFontSizeInherited; 85 with_custom_property(element, '<length>', '14em', (name) => { 86 assert_computed_value(element, '<length>', `var(${name})`, '140px'); 87 }); 88 }, '<length> values computed are correctly via var()-reference when font-size is inherited'); 89 90 test(function(){ 91 const element = divWithFontSizeInherited; 92 assert_computed_value(element, '<length>', '14em', '140px'); 93 }, '<length> values are computed correctly when font-size is inherited [14em]'); 94 95 test(function(){ 96 const element = divWithFontSizeInherited; 97 assert_computed_value(element, '<length>', 'calc(14em + 10px)', '150px'); 98 }, '<length> values are computed correctly when font-size is inherited [calc(14em + 10px)]'); 99 100 test_computed_value('<length>', '12px', '12px'); 101 test_computed_value('<length>', '13vw', length_ref('13vw')); 102 test_computed_value('<length>', '14em', '140px'); 103 test_computed_value('<length>', '15vmin', length_ref('15vmin')); 104 test_computed_value('<length>', 'calc(16px - 7em + 10vh)', length_ref('calc(10vh - 54px)')); 105 106 test_computed_value('<length>', '1in', '96px'); 107 test_computed_value('<length>', '2.54cm', '96px'); 108 test_computed_value('<length>', '25.4mm', '96px'); 109 test_computed_value('<length>', '6pc', '96px'); 110 test_computed_value('<length>', '72pt', '96px'); 111 112 test_computed_value('<length>', '10lh', '200px'); 113 114 test_computed_value('<length-percentage>', '17em', '170px'); 115 test_computed_value('<length-percentage>', '18%', '18%'); 116 test_computed_value('<length-percentage>', 'calc(19em - 2%)', 'calc(-2% + 190px)'); 117 118 test_computed_value('<length>#', '10px, 3em', '10px, 30px'); 119 test_computed_value('<length>#', '4em ,9px', '40px, 9px'); 120 test_computed_value('<length>#', '8em', '80px'); 121 122 test_computed_value('<length-percentage>#', '3% , 10vmax , 22px', ['3%', length_ref('10vmax'), '22px'].join(', ')); 123 test_computed_value('<length-percentage>#', 'calc(50% + 1em), 4px', 'calc(50% + 10px), 4px'); 124 test_computed_value('<length-percentage>#', 'calc(13% + 37px)', 'calc(13% + 37px)'); 125 126 test_computed_value('<length>+', '10px 3em', '10px 30px'); 127 test_computed_value('<length>+', '4em 9px', '40px 9px'); 128 129 test_computed_value('<length-percentage>+', '3% 10vmax 22px', ['3%', length_ref('10vmax'), '22px'].join(' ')); 130 test_computed_value('<length-percentage>+', 'calc(50% + 1em) 4px', 'calc(50% + 10px) 4px'); 131 132 test_computed_value('<transform-function>', 'translateX(2px)', 'translateX(2px)'); 133 test_computed_value('<transform-function>', 'translateX(10em)', 'translateX(100px)'); 134 test_computed_value('<transform-function>', 'translateX(calc(11em + 10%))', 'translateX(calc(10% + 110px))'); 135 test_computed_value('<transform-function>+', 'translateX(10%) scale(2)', 'translateX(10%) scale(2)'); 136 137 test_computed_value('<integer>', '15', '15'); 138 test_computed_value('<integer>', 'calc(15 + 15)', '30'); 139 test_computed_value('<integer>', 'calc(2.4)', '2'); 140 test_computed_value('<integer>', 'calc(2.6)', '3'); 141 test_computed_value('<integer>', 'calc(2.6 + 3.1)', '6'); 142 143 test_computed_value('<integer>+', '15 calc(2.4) calc(2.6)', '15 2 3'); 144 145 test_computed_value('<number>', '15', '15'); 146 test_computed_value('<number>', 'calc(15 + 15)', '30'); 147 test_computed_value('<number>', 'calc(24 / 10)', '2.4'); 148 149 test_computed_value('<number>+', '15 calc(15 + 15) calc(24 / 10)', '15 30 2.4'); 150 151 test_computed_value('<color>', '#ff0000', 'rgb(255, 0, 0)'); 152 test_computed_value('<color>', '#000f00', 'rgb(0, 15, 0)'); 153 test_computed_value('<color>', '#00000a', 'rgb(0, 0, 10)'); 154 test_computed_value('<color>', '#badbee', 'rgb(186, 219, 238)'); 155 test_computed_value('<color>', '#badbee33', 'rgba(186, 219, 238, 0.2)'); 156 test_computed_value('<color>', 'tomato', 'rgb(255, 99, 71)'); 157 test_computed_value('<color>', 'plum', 'rgb(221, 160, 221)'); 158 test_computed_value('<color>', 'currentcolor', 'rgb(0, 0, 255)'); 159 test_computed_value('<color>', 'color-mix(in srgb, black, white)', 'color(srgb 0.5 0.5 0.5)'); 160 test_computed_value('<color>', 'color-mix(in srgb, currentcolor, red)', 'color(srgb 0.5 0 0.5)'); 161 test_computed_value('<color>', 'color-mix(in srgb, currentcolor, #ffffff 70%)', 'color(srgb 0.7 0.7 1)'); 162 test_computed_value('<color>', 'color-mix(in srgb, currentcolor 20%, #ffffff 20%)', 'color(srgb 0.5 0.5 1 / 0.4)'); 163 test_computed_value('<color>', 'light-dark(currentcolor, red)', 'rgb(0, 0, 255)'); 164 test_computed_value('<color>', 'light-dark(lime, red)', 'rgb(0, 255, 0)'); 165 test_computed_value('<color>', 'color(from lime srgb g g g)', 'color(srgb 1 1 1)'); 166 test_computed_value('<color>', 'color(from currentcolor srgb b g r)', 'color(srgb 1 0 0)'); 167 test_computed_value('<color>', 'color(srgb 1 1 1 / calc(NaN))', 'color(srgb 1 1 1 / 0)'); 168 169 // Custom ident values that look like color keywords should not be converted. 170 test_computed_value('*', 'tomato', 'tomato'); 171 test_computed_value('tomato | plum', 'plum', 'plum'); 172 test_computed_value('tomato | plum | <color>', 'plum', 'plum'); 173 174 test_computed_value('*', '-50grad', '-50grad'); 175 test_computed_value('<angle>', '180deg', '180deg'); 176 test_computed_value('<angle>', '400grad', '360deg'); 177 test_computed_value('<angle>', 'calc(360deg + 400grad)', '720deg'); 178 179 test_computed_value('*', '50s', '50s'); 180 test_computed_value('<time>', '1s', '1s'); 181 test_computed_value('<time>', '1000ms', '1s'); 182 test_computed_value('<time>', 'calc(1000ms + 1s)', '2s'); 183 184 test_computed_value('*', '50dpi', '50dpi'); 185 test_computed_value('<resolution>', '1dppx', '1dppx'); 186 test_computed_value('<resolution>', '96dpi', '1dppx'); 187 test_computed_value('<resolution>', 'calc(1dppx + 96dpi)', '2dppx'); 188 189 test_computed_value('*', 'url(why)', 'url(why)'); 190 191 </script>