Понимание offsetWidth, clientWidth, scrollWidth и -Height соответственно
На StackOverflow можно встретить множество вопросов о свойствах offsetWidth
, clientWidth
и scrollWidth
(также и о соответствующих -Height
), но ни один из них не предлагает полного объяснения этих значений.
Кроме того, в интернете есть несколько источников, которые предоставляют запутанную или неверную информацию по этой теме.
Можете ли вы предоставить полное объяснение с наглядными примерами? Кроме того, как можно использовать эти значения для расчета ширины полосы прокрутки?
2 ответ(ов)
На MDN есть хорошая статья, которая объясняет теорию, стоящую за этими концепциями: CSS Object Model.
В статье подробно изложены важные концептуальные различия между шириной/высотой boundingClientRect и offsetWidth/offsetHeight.
Для проверки теории вам понадобятся тесты. Именно это я и сделал: GitHub репозиторий с тестами.
Тесты проводились в браузерах Chrome 53, Firefox 49, Safari 9, Edge 13 и IE 11.
Результаты тестов подтвердили, что теория в целом верна. Для тестов я создал три div
, каждый из которых содержал по 10 параграфов lorem ipsum. На них было применено следующее CSS:
.div1 {
width: 500px;
height: 300px;
padding: 10px;
border: 5px solid black;
overflow: auto;
}
.div2 {
width: 500px;
height: 300px;
padding: 10px;
border: 5px solid black;
box-sizing: border-box;
overflow: auto;
}
.div3 {
width: 500px;
height: 300px;
padding: 10px;
border: 5px solid black;
overflow: auto;
transform: scale(0.5);
}
Вот результаты:
div1
offsetWidth
: 530 (все браузеры)offsetHeight
: 330 (все браузеры)bcr.width
: 530 (все браузеры)bcr.height
: 330 (все браузеры)clientWidth
: 505 (Chrome, Firefox, Safari)clientWidth
: 508 (Edge)clientWidth
: 503 (IE)clientHeight
: 320 (все браузеры)scrollWidth
: 505 (Chrome, Safari, Firefox)scrollWidth
: 508 (Edge)scrollWidth
: 503 (IE)scrollHeight
: 916 (Chrome, Safari)scrollHeight
: 954 (Firefox)scrollHeight
: 922 (Edge, IE)
div2
offsetWidth
: 500 (все браузеры)offsetHeight
: 300 (все браузеры)bcr.width
: 500 (все браузеры)bcr.height
: 300 (Chrome, Firefox, Safari)bcr.height
: 299.9999694824219 (Edge, IE)clientWidth
: 475 (Chrome, Firefox, Safari)clientWidth
: 478 (Edge)clientWidth
: 473 (IE)clientHeight
: 290 (все браузеры)scrollWidth
: 475 (Chrome, Safari, Firefox)scrollWidth
: 478 (Edge)scrollWidth
: 473 (IE)scrollHeight
: 916 (Chrome, Safari)scrollHeight
: 954 (Firefox)scrollHeight
: 922 (Edge, IE)
div3
offsetWidth
: 530 (все браузеры)offsetHeight
: 330 (все браузеры)bcr.width
: 265 (все браузеры)bcr.height
: 165 (все браузеры)clientWidth
: 505 (Chrome, Firefox, Safari)clientWidth
: 508 (Edge)clientWidth
: 503 (IE)clientHeight
: 320 (все браузеры)scrollWidth
: 505 (Chrome, Safari, Firefox)scrollWidth
: 508 (Edge)scrollWidth
: 503 (IE)scrollHeight
: 916 (Chrome, Safari)scrollHeight
: 954 (Firefox)scrollHeight
: 922 (Edge, IE)
Таким образом, кроме значения высоты boundingClientRect
(299.9999694824219 вместо ожидаемых 300) в Edge 13 и IE 11, результаты подтверждают правильность теории.
Вот как я определяю эти концепции:
offsetWidth
/offsetHeight
: размеры области границ макета.boundingClientRect
: размеры области границ визуализации.clientWidth
/clientHeight
: размеры видимой части области границ макета (исключая полосы прокрутки).scrollWidth
/scrollHeight
: размеры области границ макета, если бы она не была ограничена полосами прокрутки.
Обратите внимание: ширина стандартной вертикальной полосы прокрутки составляет 12px в Edge 13, 15px в Chrome, Firefox и Safari, и 17px в IE 11 (это было измерено с помощью Photoshop на скриншотах и подтверждено результатами тестов).
Однако в некоторых случаях ваше приложение может не использовать ширину стандартной вертикальной полосы прокрутки.
Таким образом, согласно определениям этих концепций, ширина вертикальной полосы прокрутки должна быть равна (в псевдокоде):
- размер макета:
offsetWidth - clientWidth - (borderLeftWidth + borderRightWidth)
- размер визуализации:
boundingClientRect.width - clientWidth - (borderLeftWidth + borderRightWidth)
Если вам не совсем понятно, что такое макет и что такое визуализация, пожалуйста, прочитайте статью на MDN.
Также, если у вас есть другой браузер (или если вы хотите увидеть результаты тестов сами), вы можете посетить мою тестовую страницу здесь: CodePen.
Похоже, что ваш вопрос касается различных значений scrollWidth
и scrollHeight
, когда у элементов нет скроллбаров.
В ответах, которые вы видели, часто показывают скроллбары, однако scrollWidth
может быть больше, чем clientWidth
, даже если содержимое переполняет элемент без скроллбаров.
Рассмотрим следующий пример: <div style="width:1px">text</div>
.
Здесь clientWidth
будет равен 1
, что обусловлено заданным CSS-стилем. В то же время scrollWidth
составит 24
, так как это связано с фактическим содержимым внутри элемента.
Таким образом, важно понимать, что scrollWidth
и clientWidth
могут выдавать различные значения независимо от наличия или отсутствия скроллбаров, и это связано с тем, как браузеры рассчитывают размеры элементов.
Получить координаты (X,Y) HTML-элемента
Проверка наличия класса у элемента в JavaScript
Как изменить класс элемента с помощью JavaScript?
Перенос строки в HTML с использованием '\n'
Как сделать перенос строки с помощью CSS, не используя <br />?