| <!DOCTYPE html> |
| <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#calculation-of-computed-values" /> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="./resources/utils.js"></script> |
| |
| <style> |
| #divWithFontSizeSet, #parentDiv { |
| font-size: 10px; |
| } |
| </style> |
| |
| <div id=divWithFontSizeSet></div> |
| <div id=parentDiv> |
| <div id=divWithFontSizeInherited></div> |
| </div> |
| <div id="ref"></div> |
| |
| <script> |
| |
| for (let element of [divWithFontSizeSet, divWithFontSizeInherited]) { |
| let id = element.id; |
| |
| // Generate a property and temporarily set its value. Then call 'fn' with |
| // the name of the generated property. |
| function with_custom_property(reg, value, fn) { |
| let name = generate_property(reg); |
| |
| // Because we want to include the parsing step, insert a stylesheet |
| // node with textContent. |
| let node = document.createElement('style'); |
| node.textContent = `#${id} { ${name}:${value}; }`; |
| document.body.append(node); |
| |
| try { |
| fn(name); |
| } finally { |
| node.remove(); |
| } |
| } |
| |
| function assert_computed_value(syntax, value, expected) { |
| with_custom_property(syntax, value, (name) => { |
| let actual = getComputedStyle(element).getPropertyValue(name); |
| assert_equals(actual, expected); |
| }); |
| } |
| |
| // Computes an absolute reference value for some length. |
| // |
| // E.g. to figure out how many pixels '10vh' is, do length_ref('10vh'). |
| function length_ref(value, refnode = ref) { |
| try { |
| // The reference property 'min-height' is chosen arbitrarily, but |
| // avoid properties with "resolved value is used value"-behavior |
| // [1], as it may affect rounding, and custom properties do not |
| // have this behavior. |
| // |
| // [1] https://drafts.csswg.org/cssom/#resolved-values |
| const ref_property = 'min-height'; |
| refnode.style = `${ref_property}: ${value}`; |
| return getComputedStyle(refnode).getPropertyValue(ref_property); |
| } finally { |
| refnode.style = ''; |
| } |
| } |
| |
| test(function() { |
| assert_computed_value('<length>', '12px', '12px'); |
| assert_computed_value('<length>', '13vw', length_ref('13vw')); |
| assert_computed_value('<length>', '14em', '140px'); |
| assert_computed_value('<length>', '15vmin', length_ref('15vmin')); |
| assert_computed_value('<length>', 'calc(16px - 7em + 10vh)', length_ref('calc(10vh - 54px)')); |
| with_custom_property('<length>', '14em', (name) => { |
| assert_computed_value('<length>', `var(${name})`, '140px'); |
| }); |
| }, "<length> values are computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('<length-percentage>', '17em', '170px'); |
| assert_computed_value('<length-percentage>', '18%', '18%'); |
| assert_computed_value('<length-percentage>', 'calc(19em - 2%)', 'calc(190px + -2%)'); |
| }, "<length-percentage> values are computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('<length>#', '10px, 3em', '10px, 30px'); |
| assert_computed_value('<length>#', '10px, 3em', '10px, 30px'); |
| assert_computed_value('<length>#', '4em ,9px', '40px, 9px'); |
| assert_computed_value('<length>#', '8em', '80px'); |
| }, "<length># values are computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('<length-percentage>#', '3% , 10vmax , 22px', ['3%', length_ref('10vmax'), '22px'].join(', ')); |
| assert_computed_value('<length-percentage>#', 'calc(50% + 1em), 4px', 'calc(10px + 50%), 4px'); |
| assert_computed_value('<length-percentage>#', 'calc(13% + 37px)', 'calc(37px + 13%)'); |
| }, "<length-percentage># values are computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('<length>+', '10px 3em', '10px 30px'); |
| assert_computed_value('<length>+', '4em 9px', '40px 9px'); |
| }, "<length>+ values are computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('<length-percentage>+', '3% 10vmax 22px', ['3%', length_ref('10vmax'), '22px'].join(' ')); |
| assert_computed_value('<length-percentage>+', 'calc(50% + 1em) 4px', 'calc(10px + 50%) 4px'); |
| }, "<length-percentage>+ values are computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('<transform-function>', 'translateX(2px)', 'translateX(2px)'); |
| assert_computed_value('<transform-function>', 'translateX(10em)', 'translateX(100px)'); |
| assert_computed_value('<transform-function>', 'translateX(calc(11em + 10%))', 'translateX(calc(110px + 10%))'); |
| assert_computed_value('<transform-function>+', 'translateX(10%) scale(2)', 'translateX(10%) scale(2)'); |
| }, "<transform-function> values are computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('<integer>', '15', '15'); |
| assert_computed_value('<integer>', 'calc(15 + 15)', '30'); |
| assert_computed_value('<integer>', 'calc(2.4)', '2'); |
| assert_computed_value('<integer>', 'calc(2.6)', '3'); |
| assert_computed_value('<integer>', 'calc(2.6 + 3.1)', '6'); |
| }, "<integer> values are computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('<integer>+', '15 calc(2.4) calc(2.6)', '15 2 3'); |
| }, "<integer>+ values are computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('<color>', '#ff0000', 'rgb(255, 0, 0)'); |
| assert_computed_value('<color>', '#000f00', 'rgb(0, 15, 0)'); |
| assert_computed_value('<color>', '#00000a', 'rgb(0, 0, 10)'); |
| assert_computed_value('<color>', '#badbee', 'rgb(186, 219, 238)'); |
| assert_computed_value('<color>', '#badbee33', 'rgba(186, 219, 238, 0.2)'); |
| assert_computed_value('<color>', 'tomato', 'rgb(255, 99, 71)'); |
| assert_computed_value('<color>', 'plum', 'rgb(221, 160, 221)'); |
| assert_computed_value('<color>', 'currentcolor', 'currentcolor'); |
| }, "<color> values are computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('*', 'tomato', 'tomato'); |
| assert_computed_value('tomato | plum', 'plum', 'plum'); |
| assert_computed_value('tomato | plum | <color>', 'plum', 'plum'); |
| }, "ident values that look like color keywords are not converted to colors" + id); |
| |
| test(function() { |
| assert_computed_value('*', '-50grad', '-50grad'); |
| assert_computed_value('<angle>', '180deg', '180deg'); |
| assert_computed_value('<angle>', '400grad', '360deg'); |
| assert_computed_value('<angle>', 'calc(360deg + 400grad)', '720deg'); |
| }, "<angle> values computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('*', '50s', '50s'); |
| assert_computed_value('<time>', '1s', '1s'); |
| assert_computed_value('<time>', '1000ms', '1s'); |
| assert_computed_value('<time>', 'calc(1000ms + 1s)', '2s'); |
| }, "<time> values computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('*', '50dpi', '50dpi'); |
| assert_computed_value('<resolution>', '1dppx', '1dppx'); |
| assert_computed_value('<resolution>', '96dpi', '1dppx'); |
| }, "<resolution> values computed correctly for " + id); |
| |
| test(function() { |
| assert_computed_value('<resolution>', 'calc(1dppx + 96dpi)', '2dppx'); |
| }, "<resolution> values with calc() computed correctly for " + id); |
| } |
| </script> |