众所周知,盒子模型的宽度 = width + paddingLeft + paddingRight + boderLeftWidth + borderRightWidth;但如果元素存在滚动条,又将该如何计算呢?
看下demo:
<style type="text/css"> * { margin: 0; padding: 0; }
.n0 { background: #f5f5f5; margin: 30px;
float: right;
} .n1 { width: 100px; height: 100px; padding: 50px; border: 10px solid #f00; margin: 100px; background: #0ff; overflow: auto; } .n2 { height: 500px; /* 500px;*/ background: #555; } </style> <div class="n0"> <div class="n1" id="n1"> <div class="n2"></div> </div> </div>
从图中可以清楚的看到,滚动条在右padding和右margin之间,但所占据空间会从width中扣除。很庆幸,这个样式在目前主流浏览器中均表现一致(IE6+, chrome , firefox);
但是,还是别掉以轻心,既然css表现一致,那再看看js获取的宽度
<script type="text/javascript"> function getStyle(el, prop) { if (el.currentStyle) { return el.currentStyle[prop]; } else { return getComputedStyle(el)[prop]; } } window.onload = function() { var n1 = document.getElementById('n1'); console.log('offsetWidth', n1.offsetWidth); console.log('width', getStyle(n1, 'width')); } </script>
我怀着忐忑不安的心等待着各浏览器的测试结果
浏览器 | width | offsetWidth |
IE6 | 100 | 220 |
IE8 | 100 | 220 |
IE10 | 100 | 220 |
firefox | 100 | 220 |
chrome | 83 | 220 |
chrome跟我们开了一个玩笑,是的,chrome自以为是的减去了滚动条的宽度。
不过,既然offsetWidth的值一致,我们还是有办法的,继续测试
window.onload = function() { var n1 = document.getElementById('n1'); console.log('offsetWidth', n1.offsetWidth); console.log('width', getStyle(n1, 'width')); var w = n1.offsetWidth - parseInt(getStyle(n1, 'borderLeftWidth'),10) - parseInt(getStyle(n1, 'borderRightWidth'),10) - parseInt(getStyle(n1, 'paddingLeft'),10) - parseInt(getStyle(n1, 'paddingRight'),10); console.log('width', w); } </script>
得出由offsetWidth - borderLeftWidth - borderRightWidth - paddingLeft - paddingRight 获得的值在各浏览器表现一致
问题终于解决了,不得不说前端的兼容搞死人