Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!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">
<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
// 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
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>