I am working on an application that compares the rendered DOM in different browsers in order to find differences. I See it as an alternative to making a screenshot comparison. Also, this can be done programmatically with lot less false positives (at least that's what I thought).
I compute the actual position of the elements via element.getBoundingClientRect() as suggested here: retrieve the position x y of an html element.
I tried it on Firefox and Chrome and generated a JSON DOM structure from that. Now I am really confused about what I got. I know that browsers handle pixel values differently on the sub-pixel level, but it's not like Chrome always has rounded numbers and Firefox always has fractions. It almost always looks like that:
Firefox
{
"name": "SPAN",
"style": {
"display": "block",
"top": "1390.5",
"left": "824.61669921875",
"width": "123.38333129882812",
"height": "27"
}
}
Chrome
{
"name": "SPAN",
"style": {
"display": "block",
"top": "1390",
"left": "824.640625",
"width": "123.359375",
"height": "27"
}
}
The top value in chrome is always an integer whereas in firefox it is always the same value but either .5 or .25 higher.
Height is either exactly 1 or .5 higher than in chrome.
All other values are sometimes fractions in both of the browsers. If they are fractions, they are never equal (firefox always has the higher value). If they are integers, they are the same.
I would have never expected something like this. Especially the weird thing about top and height values. I would have though that the rendering just differs and this results in (irregular!!) different pixel values.
So my question: if I do this comparison, can I derive any rules from that? Does anyone know the rounding rules of firefox? Or will I have to make a tolerant comparison where I check whether the values are more than 1 unit apart from each other?
Update:
If you quickly want to check this yourself, just go to http://example.com/ (as this has a quite tiny DOM) and enterdocument.getElementsByTagName("body")[0].getBoundingClientRect()
in the javascript console on firefox and chrome. Y, height and top values are insanely long float values in firefox, whereas in they are shorter and strangely rounded in chrome.
The returned value of ClientRect() is TextRectangle, see here: https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMClientRect
All coordinates are relative to the viewport and size of it differs in various browsers. Browser real screen estate (viewport minus tabs, toolbars, ui etc.), different algorithms for sub-pixel rendering, font rendering, size of white space around inline-block elements which depends on defult font size - these are all factors that impact viewport dimensions and there are probably more. More so, these factors vary very often with every new browser version (plus users can alter settings), so any rules derived from comparison of calculated values would probably have limited value if any.
As for handling sub-pixel values I would suggest always using Math.floor to prevent any unwanted layout breakage or adjust design to be more flexible regarding browser variations.