| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>CSS Values and Units Test: Checks viewport units against CSS 2.1 properties and the CSSOM</title> |
| <meta charset="UTF-8"> |
| <meta name="assert" content="Testing what happens when one applies and rereads viewport unit lengths to CSS 2.1 properties that accept length values" /> |
| <link rel="author" title="Christian Schaefer" href="mailto:schaepp@gmx.de"> |
| <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <style> |
| #div { |
| position: relative; |
| width: 50vw; |
| height: 10vw; |
| background: green; |
| border: 0 green solid; |
| font-size: 4vw; |
| } |
| |
| #table td { |
| border: 1px solid green; |
| } |
| </style> |
| </head> |
| <body> |
| <div id="log"></div> |
| |
| <p> |
| Checks viewport units. Also re-check with zoom in/out. |
| </p> |
| |
| <div id="div"> |
| Test the Web Forward! |
| </div> |
| |
| <table id="table"> |
| <tbody> |
| <tr> |
| <td id="td">Test</td> |
| <td>T</td> |
| <td>W</td> |
| <td>F</td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <script> |
| |
| /* Boilerplate code */ |
| |
| var camelize = function (str) { |
| return str.replace(/\-(\w)/g, function(str, letter){ |
| return letter.toUpperCase(); |
| }); |
| }; |
| |
| var retrieveComputedStyle = function(element,property){ |
| var result = |
| document |
| .defaultView |
| .getComputedStyle(element,null) |
| .getPropertyValue(property); |
| |
| // If there are multiple values, cut down to the first |
| result = result.split(' ')[0]; |
| |
| if(window.console) console.log('Retrieving ' + property + ' property. Result: ' + result); |
| |
| return result; |
| } |
| |
| var testit = function(element,vunit,property,expectedResult){ |
| |
| element.style[camelize(property)] = '0px'; |
| element.style[camelize(property)] = lengthAmount + vunit; |
| |
| if(window.console) console.log(element.nodeName.toLowerCase() + '.style.' + camelize(property) + ' = ' + lengthAmount + vunit); |
| |
| var result = retrieveComputedStyle(element,property); |
| |
| // Test against WebKit's getComputedStyle bug, where it does not return absolute values |
| // As required here: http://www.w3.org/TR/1998/REC-CSS2-19980512/cascade.html#computed-value |
| // If it returns a pixel value, but this value is 0px then it is considered a fail, too. |
| var px_result = result.search(/^[-\d\.]+px$/) !== -1 && result !== '0px' ? 'non-zero px-based value' : result; |
| |
| // If browser returns pixel value, we compare against our expected pixel value |
| if(px_result === 'non-zero px-based value'){ |
| test(function(){ |
| assert_equals(Math.round(parseFloat(result.replace(/[^-\d\.]+/g,''))),expectedResult); |
| },vunit + ' length applied to ' + property); |
| } |
| // If not, we compare against the value we set initially |
| else { |
| test(function(){ |
| assert_equals(result,lengthAmount + vunit); |
| },vunit + ' length applied to ' + property); |
| } |
| |
| // Does the browser have a bug in getComputedStyle or not? |
| test(function(){ |
| assert_equals(px_result,'non-zero px-based value'); |
| },vunit + ' length applied to ' + property + ': getComputedStyle returns a non-zero px-based value'); |
| |
| element.style[camelize(property)] = ''; |
| } |
| |
| var lengthAmount = 10; |
| var layoutViewportWidth = document.documentElement.clientWidth; |
| var layoutViewportHeight = document.documentElement.clientHeight; |
| |
| var viewportUnits = [ |
| { |
| ident: 'vw', |
| expectedResult: Math.round(layoutViewportWidth * (lengthAmount / 100)) |
| } |
| ,{ |
| ident: 'vh', |
| expectedResult: Math.round(layoutViewportHeight * (lengthAmount / 100)) |
| } |
| ,{ |
| ident: 'vmin', |
| expectedResult: layoutViewportWidth < layoutViewportHeight ? Math.round(layoutViewportWidth * (lengthAmount / 100)) : Math.round(layoutViewportHeight * (lengthAmount / 100)) |
| } |
| ,{ |
| ident: 'vmax', |
| expectedResult: layoutViewportWidth > layoutViewportHeight ? Math.round(layoutViewportWidth * (lengthAmount / 100)) : Math.round(layoutViewportHeight * (lengthAmount / 100)) |
| } |
| ] |
| |
| // List of length accepting properties and which element they map to |
| // http://www.w3.org/TR/CSS21/propidx.html |
| var lengthAcceptingProperties = [ |
| { |
| name: 'width', |
| element: 'div' |
| } |
| ,{ |
| name: 'height', |
| element: 'div' |
| } |
| ,{ |
| name: 'min-width', |
| element: 'div' |
| } |
| ,{ |
| name: 'min-height', |
| element: 'div' |
| } |
| ,{ |
| name: 'max-width', |
| element: 'div' |
| } |
| ,{ |
| name: 'max-height', |
| element: 'div' |
| } |
| ,{ |
| name: 'margin-top', |
| element: 'div' |
| } |
| ,{ |
| name: 'padding-top', |
| element: 'div' |
| } |
| ,{ |
| name: 'border-top-width', |
| element: 'div' |
| } |
| ,{ |
| name: 'font-size', |
| element: 'div' |
| } |
| ,{ |
| name: 'line-height', |
| element: 'div' |
| } |
| ,{ |
| name: 'border-spacing', |
| element: 'table' |
| } |
| ,{ |
| name: 'top', |
| element: 'div' |
| } |
| ,{ |
| name: 'right', |
| element: 'div' |
| } |
| ,{ |
| name: 'bottom', |
| element: 'div' |
| } |
| ,{ |
| name: 'left', |
| element: 'div' |
| } |
| ,{ |
| name: 'letter-spacing', |
| element: 'div' |
| } |
| ,{ |
| name: 'text-indent', |
| element: 'div' |
| } |
| ,{ |
| name: 'vertical-align', |
| element: 'td' |
| } |
| ,{ |
| name: 'word-spacing', |
| element: 'div' |
| } |
| ]; |
| |
| var div = document.getElementById('div'); |
| var table = document.getElementById('table'); |
| var td = document.getElementById('td'); |
| |
| for(unitEntry in viewportUnits){ |
| for(propertyEntry in lengthAcceptingProperties){ |
| |
| var vunit = viewportUnits[unitEntry].ident; |
| var expectedResult = viewportUnits[unitEntry].expectedResult; |
| var property = lengthAcceptingProperties[propertyEntry].name; |
| var element = window[lengthAcceptingProperties[propertyEntry].element]; |
| |
| testit(element,vunit,property,expectedResult); |
| } |
| } |
| |
| </script> |
| </body> |
| </html> |