Почему document.body.offsetHeight + document.body.bottomMargin не равно document.documentElement.offsetHeight

Я пытаюсь настроить высоту iFrame и не могу понять, почему

document.body.offsetHeight + document.body.bottomMargin 

не соответствует

document.documentElement.offsetHeight

когда все остальные поля установлены на ноль, а нижнее поле имеет значение ниже 16 пикселей.

Как только нижнее поле будет больше 16 пикселей, эти два значения равны друг другу в FireFox и находятся в пределах 1 пикселя в Chrome.

Странно, что эта проблема не влияет на вычисление ширины.

Ответ 1

После долгих копаний я придумал это, чтобы решить проблему.

function getIFrameHeight(){
    function getComputedBodyStyle(prop) {
        return parseInt(
            document.defaultView.getComputedStyle(document.body, null),
            10
        );
    }

    return document.body.offsetHeight +
        getComputedBodyStyle('marginTop') +
        getComputedBodyStyle('marginBottom');
}

и расширенную версию для IE8 и ниже.

function getIFrameHeight(){
    function getComputedBodyStyle(prop) {
        function getPixelValue(value) {
            var PIXEL = /^\d+(px)?$/i;

            if (PIXEL.test(value)) {
                return parseInt(value,base);
            }

            var 
                style = el.style.left,
                runtimeStyle = el.runtimeStyle.left;

            el.runtimeStyle.left = el.currentStyle.left;
            el.style.left = value || 0;
            value = el.style.pixelLeft;
            el.style.left = style;
            el.runtimeStyle.left = runtimeStyle;

            return value;
        }

        var 
            el = document.body,
            retVal = 0;

        if (document.defaultView && document.defaultView.getComputedStyle) {
            retVal =  document.defaultView.getComputedStyle(el, null)[prop];
        } else {//IE8 & below
            retVal =  getPixelValue(el.currentStyle[prop]);
        } 

        return parseInt(retVal,10);
    }

    return document.body.offsetHeight +
        getComputedBodyStyle('marginTop') +
        getComputedBodyStyle('marginBottom');
}