| <!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> |
| |
| // Generate a property and temporarily set its value. Then call 'fn' with |
| // the name of the generated property. |
| function with_custom_property(element, reg, value, fn) { |
| if (element.id.length == 0) |
| throw 'The specified element must have an ID'; |
| |
| 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 = `#${element.id} { ${name}:${value}; }`; |
| document.body.append(node); |
| |
| try { |
| fn(name); |
| } finally { |
| node.remove(); |
| } |
| } |
| |
| function assert_computed_value(element, syntax, value, expected) { |
| with_custom_property(element, 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 = ''; |
| } |
| } |
| |
| function test_computed_value(syntax, value, expected) { |
| test(function() { |
| assert_computed_value(divWithFontSizeSet, syntax, value, expected); |
| }, `${syntax} values are computed correctly [${value}]`); |
| } |
| |
| test(function(){ |
| const element = divWithFontSizeSet; |
| with_custom_property(element, '<length>', '14em', (name) => { |
| assert_computed_value(element, '<length>', `var(${name})`, '140px'); |
| }); |
| }, '<length> values computed are correctly via var()-reference'); |
| |
| test(function(){ |
| const element = divWithFontSizeInherited; |
| with_custom_property(element, '<length>', '14em', (name) => { |
| assert_computed_value(element, '<length>', `var(${name})`, '140px'); |
| }); |
| }, '<length> values computed are correctly via var()-reference when font-size is inherited'); |
| |
| test(function(){ |
| const element = divWithFontSizeInherited; |
| assert_computed_value(element, '<length>', '14em', '140px'); |
| }, '<length> values are computed correctly when font-size is inherited [14em]'); |
| |
| test(function(){ |
| const element = divWithFontSizeInherited; |
| assert_computed_value(element, '<length>', 'calc(14em + 10px)', '150px'); |
| }, '<length> values are computed correctly when font-size is inherited [calc(14em + 10px)]'); |
| |
| test_computed_value('<length>', '12px', '12px'); |
| test_computed_value('<length>', '13vw', length_ref('13vw')); |
| test_computed_value('<length>', '14em', '140px'); |
| test_computed_value('<length>', '15vmin', length_ref('15vmin')); |
| test_computed_value('<length>', 'calc(16px - 7em + 10vh)', length_ref('calc(10vh - 54px)')); |
| |
| test_computed_value('<length-percentage>', '17em', '170px'); |
| test_computed_value('<length-percentage>', '18%', '18%'); |
| test_computed_value('<length-percentage>', 'calc(19em - 2%)', 'calc(-2% + 190px)'); |
| |
| test_computed_value('<length>#', '10px, 3em', '10px, 30px'); |
| test_computed_value('<length>#', '4em ,9px', '40px, 9px'); |
| test_computed_value('<length>#', '8em', '80px'); |
| |
| test_computed_value('<length-percentage>#', '3% , 10vmax , 22px', ['3%', length_ref('10vmax'), '22px'].join(', ')); |
| test_computed_value('<length-percentage>#', 'calc(50% + 1em), 4px', 'calc(50% + 10px), 4px'); |
| test_computed_value('<length-percentage>#', 'calc(13% + 37px)', 'calc(13% + 37px)'); |
| |
| test_computed_value('<length>+', '10px 3em', '10px 30px'); |
| test_computed_value('<length>+', '4em 9px', '40px 9px'); |
| |
| test_computed_value('<length-percentage>+', '3% 10vmax 22px', ['3%', length_ref('10vmax'), '22px'].join(' ')); |
| test_computed_value('<length-percentage>+', 'calc(50% + 1em) 4px', 'calc(50% + 10px) 4px'); |
| |
| test_computed_value('<transform-function>', 'translateX(2px)', 'translateX(2px)'); |
| test_computed_value('<transform-function>', 'translateX(10em)', 'translateX(100px)'); |
| test_computed_value('<transform-function>', 'translateX(calc(11em + 10%))', 'translateX(calc(10% + 110px))'); |
| test_computed_value('<transform-function>+', 'translateX(10%) scale(2)', 'translateX(10%) scale(2)'); |
| |
| test_computed_value('<integer>', '15', '15'); |
| test_computed_value('<integer>', 'calc(15 + 15)', '30'); |
| test_computed_value('<integer>', 'calc(2.4)', '2'); |
| test_computed_value('<integer>', 'calc(2.6)', '3'); |
| test_computed_value('<integer>', 'calc(2.6 + 3.1)', '6'); |
| |
| test_computed_value('<integer>+', '15 calc(2.4) calc(2.6)', '15 2 3'); |
| |
| test_computed_value('<color>', '#ff0000', 'rgb(255, 0, 0)'); |
| test_computed_value('<color>', '#000f00', 'rgb(0, 15, 0)'); |
| test_computed_value('<color>', '#00000a', 'rgb(0, 0, 10)'); |
| test_computed_value('<color>', '#badbee', 'rgb(186, 219, 238)'); |
| test_computed_value('<color>', '#badbee33', 'rgba(186, 219, 238, 0.2)'); |
| test_computed_value('<color>', 'tomato', 'rgb(255, 99, 71)'); |
| test_computed_value('<color>', 'plum', 'rgb(221, 160, 221)'); |
| test_computed_value('<color>', 'currentcolor', 'currentcolor'); |
| |
| // Custom ident values that look like color keywords should not be converted. |
| test_computed_value('*', 'tomato', 'tomato'); |
| test_computed_value('tomato | plum', 'plum', 'plum'); |
| test_computed_value('tomato | plum | <color>', 'plum', 'plum'); |
| |
| test_computed_value('*', '-50grad', '-50grad'); |
| test_computed_value('<angle>', '180deg', '180deg'); |
| test_computed_value('<angle>', '400grad', '360deg'); |
| test_computed_value('<angle>', 'calc(360deg + 400grad)', '720deg'); |
| |
| test_computed_value('*', '50s', '50s'); |
| test_computed_value('<time>', '1s', '1s'); |
| test_computed_value('<time>', '1000ms', '1s'); |
| test_computed_value('<time>', 'calc(1000ms + 1s)', '2s'); |
| |
| test_computed_value('*', '50dpi', '50dpi'); |
| test_computed_value('<resolution>', '1dppx', '1dppx'); |
| test_computed_value('<resolution>', '96dpi', '1dppx'); |
| test_computed_value('<resolution>', 'calc(1dppx + 96dpi)', '2dppx'); |
| |
| </script> |