5

Понимание offsetWidth, clientWidth, scrollWidth и -Height соответственно

16

На StackOverflow можно встретить множество вопросов о свойствах offsetWidth, clientWidth и scrollWidth (также и о соответствующих -Height), но ни один из них не предлагает полного объяснения этих значений.

Кроме того, в интернете есть несколько источников, которые предоставляют запутанную или неверную информацию по этой теме.

Можете ли вы предоставить полное объяснение с наглядными примерами? Кроме того, как можно использовать эти значения для расчета ширины полосы прокрутки?

2 ответ(ов)

0

На 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.

0

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

В ответах, которые вы видели, часто показывают скроллбары, однако scrollWidth может быть больше, чем clientWidth, даже если содержимое переполняет элемент без скроллбаров.

Рассмотрим следующий пример: <div style="width:1px">text</div>.

Здесь clientWidth будет равен 1, что обусловлено заданным CSS-стилем. В то же время scrollWidth составит 24, так как это связано с фактическим содержимым внутри элемента.

Таким образом, важно понимать, что scrollWidth и clientWidth могут выдавать различные значения независимо от наличия или отсутствия скроллбаров, и это связано с тем, как браузеры рассчитывают размеры элементов.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь