вернуться к уроку

Расширить элемент

важность: 4

В <body> есть элемент <div> с заданной шириной width.

Задача – написать код, который «распахнёт» <div> по ширине на всю страницу.

Исходный документ (<div> содержит текст и прокрутку):

P.S. Пользоваться следует исключительно средствами JS, CSS в этой задаче менять нельзя. Также ваш код должен быть универсален и не ломаться, если цифры в CSS станут другими.

P.P.S. При расширении элемент <div> не должен вылезти за границу <body>.

Открыть песочницу для задачи.

Решение через width: auto

Вначале рассмотрим решение через «умную» установку CSS-свойства.

Они могут быть разными. Самое простое выглядит так:

elem.style.width = 'auto';

Такой способ работает, так как <div> по умолчанию распахивается на всю ширину.

Конечно, такое решение не будет работать для элементов, которые сами по себе не растягиваются, например в случае со <span> или при наличии position: absolute.

Обратим внимание, такой вариант был бы неверен:

elem.style.width = '100%';

По умолчанию в CSS ширина width – это то, что внутри padding, а проценты отсчитываются от ширины родителя. То есть, ставя ширину в 100%, мы говорим: «внутренняя область должна занимать 100% ширины родителя». А в элементе есть ещё padding, которые в итоге вылезут наружу.

Можно бы поменять блочную модель, указав box-sizing через свойство elem.style.boxSizing, но такое изменение потенциально может затронуть много других свойств, поэтому нежелательно.

Точное вычисление

Альтернатива – вычислить ширину родителя через clientWidth.

Доступную внутреннюю ширину родителя можно получить, вычитая из clientWidth размеры paddingLeft/paddingRight, и затем присвоить её элементу:

var bodyClientWidth = document.body.clientWidth;

var style = getComputedStyle(elem);

var bodyInnerWidth = bodyClientWidth - parseInt(style.paddingLeft) - parseInt(style.paddingRight);

elem.style.width = bodyInnerWidth + 'px';

Такое решение будет работать всегда, вне зависимости от типа элемента. Конечно, при изменении размеров окна браузера ширина не адаптируется к новому размеру автоматически, как с width:auto. Это недостаток. Его, конечно, тоже можно обойти при помощи событий (изучим далее), но как общий рецепт – если CSS может решить задачу – лучше использовать CSS.

Открыть решение в песочнице.