Как получить фактическую ширину и высоту HTML-элемента?
Как можно вычислить ширину и высоту элемента <div>
, чтобы правильно его центрировать в отображении браузера (viewport)? Какие браузеры поддерживают каждый из методов?
5 ответ(ов)
Если это будет полезно кому-то, я провел тест с текстовым полем, кнопкой и div, у которых все одинаковые CSS-стили:
width: 200px;
height: 20px;
border: solid 1px #000;
padding: 2px;
Вот HTML-разметка:
<input id="t" type="text" />
<input id="b" type="button" />
<div id="d"></div>
Я проверил это в Chrome, Firefox и IE-Edge, с jQuery и без, с box-sizing: border-box
и без. Тест проводился с <!DOCTYPE html>
.
Результаты:
Firefox Chrome IE-Edge
with w/o with w/o with w/o box-sizing
$("#t").width() 194 200 194 200 194 200
$("#b").width() 194 194 194 194 194 194
$("#d").width() 194 200 194 200 194 200
$("#t").outerWidth() 200 206 200 206 200 206
$("#b").outerWidth() 200 200 200 200 200 200
$("#d").outerWidth() 200 206 200 206 200 206
$("#t").innerWidth() 198 204 198 204 198 204
$("#b").innerWidth() 198 198 198 198 198 198
$("#d").innerWidth() 198 204 198 204 198 204
$("#t").css('width') 200px 200px 200px 200px 200px 200px
$("#b").css('width') 200px 200px 200px 200px 200px 200px
$("#d").css('width') 200px 200px 200px 200px 200px 200px
$("#t").css('border-left-width') 1px 1px 1px 1px 1px 1px
$("#b").css('border-left-width') 1px 1px 1px 1px 1px 1px
$("#d").css('border-left-width') 1px 1px 1px 1px 1px 1px
$("#t").css('padding-left') 2px 2px 2px 2px 2px 2px
$("#b").css('padding-left') 2px 2px 2px 2px 2px 2px
$("#d").css('padding-left') 2px 2px 2px 2px 2px 2px
document.getElementById("t").getBoundingClientRect().width 200 206 200 206 200 206
document.getElementById("b").getBoundingClientRect().width 200 200 200 200 200 200
document.getElementById("d").getBoundingClientRect().width 200 206 200 206 200 206
document.getElementById("t").offsetWidth 200 206 200 206 200 206
document.getElementById("b").offsetWidth 200 200 200 200 200 200
document.getElementById("d").offsetWidth 200 206 200 206 200 206
Как видно, результаты различаются в зависимости от браузера и используемых методов для получения ширины элементов. Это может быть полезно при работе с кроссбраузерной версткой.
Это довольно просто изменить стили элементов, но читать их значения довольно сложно.
JavaScript не может напрямую считывать свойства стиля элемента (elem.style
), полученные из CSS (внутреннего или внешнего), если вы не используете встроенный метод getComputedStyle
в JavaScript.
getComputedStyle(element[, pseudo])
Элемент: Элемент, значение которого вы хотите считать.
pseudo: Псевдо-элемент, если это необходимо, например ::before
. Пустая строка или отсутствие аргумента означает сам элемент.
Результатом является объект с годовыми стилями, наподобие elem.style
, но уже с учетом всех CSS классов.
Например, здесь стиль не видит margin
:
<head>
<style> body { color: red; margin: 5px } </style>
</head>
<body>
<script>
let computedStyle = getComputedStyle(document.body);
// Теперь мы можем считать margin и color из него
alert(computedStyle.marginTop); // 5px
alert(computedStyle.color); // rgb(255, 0, 0)
</script>
</body>
Таким образом, модифицируйте ваш JavaScript код, чтобы включить getComputedStyle
элемента, для которого вы хотите получить ширину/высоту или другое свойство.
window.onload = function() {
var test = document.getElementById("test");
test.addEventListener("click", select);
function select(e) {
var elementID = e.target.id;
var element = document.getElementById(elementID);
let computedStyle = getComputedStyle(element);
var width = computedStyle.width;
console.log(element);
console.log(width);
}
}
Вычисленные и разрешенные значения
Существует два понятия в CSS:
Вычисленное значение стиля — это значение после применения всех правил CSS и наследования CSS, как результат каскада CSS. Это может выглядеть как
height: 1em
илиfont-size: 125%
.Разрешенное значение стиля — это значение, которое в конечном итоге применяется к элементу. Значения, такие как
1em
или125%
, являются относительными. Браузер берет вычисленное значение и делает все единицы фиксированными и абсолютными, например:height: 20px
илиfont-size: 16px
. Для геометрических свойств разрешенные значения могут иметь дробную часть, напримерwidth: 50.5px
.
Долгое время getComputedStyle
использовался для получения вычисленных значений, но оказалось, что разрешенные значения гораздо удобнее, и стандарт изменился. Теперь getComputedStyle
фактически возвращает разрешенное значение свойства.
Обратите внимание:
getComputedStyle
требует полное имя свойства
Вам всегда следует запрашивать конкретное свойство, такое как
paddingLeft
,height
илиwidth
. В противном случае правильный результат не гарантируется.Например, если имеются свойства
paddingLeft/paddingTop
, то что мы должны получить дляgetComputedStyle(elem).padding
? Ничего, или, возможно, «сгенерированное» значение от известных отступов? Здесь нет стандартного правила.
Существуют и другие несоответствия. Например, некоторые браузеры (Chrome) показывают 10px
в приведенном ниже документе, а другие (Firefox) – нет:
<style>
body {
margin: 30px;
height: 900px;
}
</style>
<script>
let style = getComputedStyle(document.body);
alert(style.margin); // пустая строка в Firefox
</script>
Для получения дополнительной информации можно обратиться сюда.
Вам нужно вычислять это только для IE7 и более ранних версий (и только если ваш контент не имеет фиксированного размера). Я рекомендую использовать условные комментарии HTML, чтобы ограничить хак для старых IE, которые не поддерживают CSS2. Для всех остальных браузеров используйте следующий код:
<style type="text/css">
html,body {display:table; height:100%;width:100%;margin:0;padding:0;}
body {display:table-cell; vertical-align:middle;}
div {display:table; margin:0 auto; background:red;}
</style>
<body><div>test<br>test</div></body>
Это идеальное решение. Оно центрирует <div>
любого размера и сжимает его до размеров его содержимого.
Это единственное, что сработало для меня:
element.clientWidth -
parseFloat(window.getComputedStyle(element, null).getPropertyValue("padding-left")) -
parseFloat(window.getComputedStyle(element, null).getPropertyValue("padding-right"))
Этот код вычисляет ширину элемента без учета его горизонтальных отступов.
В качестве ответа на ваш вопрос: использование element.offsetWidth
и element.offsetHeight
, как уже упоминалось в предыдущем посте, действительно может помочь.
Тем не менее, если ваша цель — просто центрировать контент, существует более эффективный способ. Предполагая, что вы используете строгий DOCTYPE XHTML, просто установите для тега body
свойства margin: 0 auto
и укажите необходимую ширину в пикселях. Это позволит контенту автоматически выравниваться по центру страницы.
Эквивалент document.createElement в jQuery?
Как определить, виден ли элемент DOM в текущей области просмотра?
Как выбрать элемент по имени с помощью jQuery?
jQuery: Получение Выбранного Значения Из Выпадающего Списка
Прокрутка до низа div?