Как мне получить фактическую ширину и высоту HTML-элемента?

avatar
snortasprocket
16 ноября 2008 в 19:15
1214116
16
1010

Предположим, у меня есть <div>, который я хочу центрировать на дисплее браузера (области просмотра). Для этого мне нужно вычислить ширину и высоту элемента <div>.

Что мне использовать? Включите информацию о совместимости браузера.

Источник
Marcelo Lazaroni
5 декабря 2016 в 03:16
11

Имейте в виду, что получение высоты элемента с помощью любого метода всегда оказывает влияние на производительность , поскольку оно заставляет браузер пересчитывать положение всех элементов на странице (перекомпоновка). Поэтому не делайте этого слишком много. Проверьте этот список, чтобы узнать, какие вещи вызывают переформатирование.

Ответы (16)

avatar
Greg
16 ноября 2008 в 19:35
1456

Следует использовать свойства .offsetWidth и .offsetHeight. Обратите внимание, что они принадлежат элементу, а не .style.

var width = document.getElementById('foo').offsetWidth;

Функция .getBoundingClientRect() возвращает размеры и расположение элемента в виде чисел с плавающей запятой после выполнения преобразований CSS.

> console.log(document.getElementById('id').getBoundingClientRect())
DOMRect {
    bottom: 177,
    height: 54.7,
    left: 278.5,​
    right: 909.5,
    top: 122.3,
    width: 631,
    x: 278.5,
    y: 122.3,
}
Dan Fabulich
19 января 2010 в 05:59
189

Остерегаться! offsetHeight / offsetWidth может возвращать 0, если вы недавно внесли определенные изменения DOM в элемент. Возможно, вам придется вызвать этот код в вызове setTimeout после того, как вы изменили элемент.

Cheetah
22 февраля 2012 в 23:22
31

При каких обстоятельствах возвращается 0?

JDandChips
2 ноября 2012 в 08:52
2

Я не могу точно определить причину, по которой offsetWidth возвращает 0 в моем случае, потому что я изначально не писал код, но в событии onload я всегда получаю 0.

MrWhite
16 ноября 2012 в 00:16
49

@JDandChips: offsetWidth будет 0, если элемент display:none, тогда как вычисленное width может все еще иметь положительное значение в этом случае. visibility:hidden не влияет на offsetWidth.

Ky Leggiero
10 ноября 2014 в 18:42
0

clientWidth точнее?

Edurne Pascual
1 декабря 2014 в 14:41
22

@Supuhstar имеют разные значения. offsetWidth возвращает "весь" блок, включая содержимое, отступы и границы; в то время как clientWidth возвращает размер только поля содержимого (поэтому он будет иметь меньшее значение, если элемент имеет ненулевое заполнение и / или границу). (мод отредактирован для ясности)

trysis
4 мая 2015 в 21:28
2

@Supuhstar, иногда они будут такими же, например, когда вы установите box-sizing: border-box, что выполняется с помощью Bootstrap (и я уверен, что другие) автоматически.

ling
9 октября 2016 в 07:03
0

Примечание: в случае значка внутри кнопки Chrome и firefox возвращают разные результаты: github.com/lingtalfi/browsers-behaviours/blob/master/…

Graham P Heath
15 июня 2017 в 18:08
0

Re @DanFabulich: использование requestAnimationFrame вместо setTimeout (вероятно) предпочтительнее в 2017 году.

Yuval A.
28 февраля 2019 в 23:03
1

Согласно developer.mozilla.org/en-US/docs/Web/API/HTMLElement/… Поддержка Chrome и Safari для offsetHeight неизвестна (?), И в нем говорится, что это «экспериментальная функция. «- можно ли это засчитать как кроссбраузерность? Этот комментарий был написан марта 2019 !

Edward
16 ноября 2019 в 18:52
0

И смещение, и ширина клиента отображают 0, несмотря на наличие текста в div, и после щелчка мыши.

transang
18 апреля 2021 в 03:31
0

может ли кто-нибудь привести пример, где offsetHeight возвращает 0? Я пытался создать его, но не смог воспроизвести. codepen.io/tranvansang/pen/wvgxRPL

avatar
fguillen
25 января 2022 в 16:47
0

Это единственное, что помогло мне:

element.clientWidth -
parseFloat(window.getComputedStyle(element, null).getPropertyValue("padding-left")) -
parseFloat(window.getComputedStyle(element, null).getPropertyValue("padding-right"))
avatar
Venryx
30 июня 2021 в 01:03
0

Я создал для этого служебную функцию с высокой гибкостью:

export type Size = {width: number, height: number};
export enum GetSize_Method {
    /** Includes: content, padding. Excludes: border, margin, scroll-bar (if it has one), "position:absolute" descendants. */
    ClientSize = "ClientSize",
    /** Includes: content, padding, border, margin, scroll-bar (if it has one). Excludes: "position:absolute" descendants. */
    OffsetSize = "OffsetSize",
    /** Includes: content, padding, border, margin, scroll-bar (if it has one), "position:absolute" descendants. Excludes: none. */
    ScrollSize = "ScrollSize",
    /** Same as ScrollSize, except that it's calculated after the element's css transforms are applied. */
    BoundingClientRect = "BoundingClientRect",
    /** Lets you specify the exact list of components you want to include in the size calculation. */
    Custom = "Custom",
}
export type SizeComp = "content" | "padding" | "border" | "margin" | "scrollBar" | "posAbsDescendants";

export function GetSize(el: HTMLElement, method = GetSize_Method.ClientSize, custom_sizeComps?: SizeComp[]) {
    let size: Size;
    if (method == GetSize_Method.ClientSize) {
        size = {width: el.clientWidth, height: el.clientHeight};
    } else if (method == GetSize_Method.OffsetSize) {
        size = {width: el.offsetWidth, height: el.offsetHeight};
    } else if (method == GetSize_Method.ScrollSize) {
        size = {width: el.scrollWidth, height: el.scrollHeight};
    } else if (method == GetSize_Method.BoundingClientRect) {
        const rect = el.getBoundingClientRect();
        size = {width: rect.width, height: rect.height};
    } else if (method == GetSize_Method.Custom) {
        const style = window.getComputedStyle(el, null);
        const styleProp = (name: string)=>parseFloat(style.getPropertyValue(name));

        const padding = {w: styleProp("padding-left") + styleProp("padding-right"), h: styleProp("padding-top") + styleProp("padding-bottom")};
        const base = {w: el.clientWidth - padding.w, h: el.clientHeight - padding.h};
        const border = {w: styleProp("border-left") + styleProp("border-right"), h: styleProp("border-top") + styleProp("border-bottom")};
        const margin = {w: styleProp("margin-left") + styleProp("margin-right"), h: styleProp("margin-top") + styleProp("margin-bottom")};
        const scrollBar = {w: (el.offsetWidth - el.clientWidth) - border.w - margin.w, h: (el.offsetHeight - el.clientHeight) - border.h - margin.h};
        const posAbsDescendants = {w: el.scrollWidth - el.offsetWidth, h: el.scrollHeight - el.offsetHeight};

        const sc = (name: SizeComp, valIfEnabled: number)=>custom_sizeComps.includes(name) ? valIfEnabled : 0;
        size = {
            width: sc("content", base.w) + sc("padding", padding.w) + sc("border", border.w)
                    + sc("margin", margin.w) + sc("scrollBar", scrollBar.w) + sc("posAbsDescendants", posAbsDescendants.w),
            height: sc("content", base.h) + sc("padding", padding.h) + sc("border", border.h)
                    + sc("margin", margin.h) + sc("scrollBar", scrollBar.h) + sc("posAbsDescendants", posAbsDescendants.h),
        };
    }
    return size;
}

Использование:

const el = document.querySelector(".my-element");
console.log("Size:", GetSize(el, "ClientSize"));
console.log("Size:", GetSize(el, "Custom", ["content", "padding", "border"]));
avatar
user1767599
2 ноября 2020 в 17:56
-1

Используйте следующие параметры ширины:

   style={{
      width: "80%",
      paddingLeft: 100,
      paddingRight: 200,
      paddingTop: 30,
      paddingBottom: 30,
      border: "3px solid lightGray",
    }}
Zach Lysobey
7 мая 2021 в 21:08
0

это похоже на атрибут JSX для , установка ширины ?

avatar
Kamil Kiełczewski
19 августа 2020 в 20:39
0

Flex

Если вы хотите отобразить в своем <div> какое-то всплывающее сообщение в центре экрана - тогда вам не нужно читать размер <div>, но вы можете использовать flex

.box {
  width: 50px;
  height: 20px;
  background: red;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  width: 100vw;
  position: fixed; /* remove this in case there is no content under div (and remember to set body margins to 0)*/
}
<div class="container">
  <div class="box">My div</div>
</div>
avatar
Aleksey Mazurenko
31 мая 2018 в 11:52
-3

Вот код для WKWebView , который определяет высоту конкретного элемента Dom (не работает должным образом для всей страницы)

let html = "<body><span id=\"spanEl\" style=\"font-family: '\(taskFont.fontName)'; font-size: \(taskFont.pointSize - 4.0)pt; color: rgb(\(red), \(blue), \(green))\">\(textValue)</span></body>"
webView.navigationDelegate = self
webView.loadHTMLString(taskHTML, baseURL: nil)

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    webView.evaluateJavaScript("document.getElementById(\"spanEl\").getBoundingClientRect().height;") { [weak self] (response, error) in
        if let nValue = response as? NSNumber {

        }
    }
}
Zach Lysobey
30 октября 2018 в 21:19
0

для ясности, это код iOS swift, верно? Не JavaScript. Я отказываюсь от отрицательного голоса (кстати, это может быть очень полезно), но обратите внимание, что это не ответ на вопрос и, вероятно, будет более подходящим для другого, специфичного для iOS, вопроса. Если его еще нет, возможно, подумайте о том, чтобы спросить его и ответить самостоятельно.

avatar
Lekens
27 апреля 2018 в 11:58
4

Стили элементов изменить легко, но сложно прочитать значение.

JavaScript не может прочитать какое-либо свойство стиля элемента (elem.style) из css (внутреннего / внешнего), если вы не используете встроенный вызов метода getComputedStyle в javascript.

getComputedStyle (элемент [, псевдо])

Элемент: Элемент, для которого нужно прочитать значение.
псевдо: Псевдоэлемент, если требуется, например :: before. Пустая строка или отсутствие аргумента означает сам элемент.

Результатом является объект со свойствами стиля, такими как elem.style, но теперь по отношению ко всем классам css.

Например, здесь стиль не видит поля:

<head>
  <style> body { color: red; margin: 5px } </style>
</head>
<body>

  <script>
    let computedStyle = getComputedStyle(document.body);

    // now we can read the margin and the color from it

    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%, являются относительными. Браузер принимает вычисленные value и делает все единицы фиксированными и абсолютными, например: высота: 20 пикселей или размер шрифта: 16 пикселей. Для свойств геометрии разрешенные значения может иметь плавающую точку, например, ширина: 50,5 пикселей.

Давным-давно getComputedStyle был создан для получения вычисленных значений, но оказалось, что разрешенные значения намного удобнее, и стандарт изменился.
Итак, в настоящее время getComputedStyle фактически возвращает разрешенное значение свойства.

Обратите внимание:

getComputedStyle требует полного имени свойства

Вы всегда должны спрашивать именно ту недвижимость, которую хотите, например paddingLeft или высота или ширина. В противном случае правильный результат не гарантируется.

Например, если есть свойства paddingLeft / paddingTop, то что мы должны получить для getComputedStyle (elem) .padding? Ничего или может быть, «сгенерированное» значение из известных отступов? Нет стандарта Правь здесь.

Есть другие несоответствия. Например, некоторые браузеры (Chrome) показывают 10 пикселей в приведенном ниже документе, а некоторые из них (Firefox) - нет:

<style>
  body {
    margin: 30px;
    height: 900px;
  }
</style>
<script>
  let style = getComputedStyle(document.body);
  alert(style.margin); // empty string in Firefox
</script>

для получения дополнительной информации https://javascript.info/styles-and-classes

avatar
HarlemSquirrel
1 марта 2018 в 20:38
24

Согласно MDN: Определение размеров элементов

offsetWidth и offsetHeight возвращают «общий объем пространства, занимаемого элементом, включая ширину видимого содержимого, полосы прокрутки (если есть), отступы и границу»

clientWidth и clientHeight возвращают «сколько места занимает фактическое отображаемое содержимое, включая отступы, но не включая границу, поля или полосы прокрутки»

scrollWidth и scrollHeight возвращают «фактический размер содержимого, независимо от того, какая его часть в настоящее время видна»

Таким образом, это зависит от того, будет ли измеренный контент находиться вне текущей видимой области.

CrandellWS
28 августа 2020 в 23:38
0

спасибо: вот статья об этом javascripttutorial.net/javascript-dom/javascript-width-height

avatar
Graham
19 февраля 2016 в 12:52
50

На всякий случай, если это кому-то пригодится, я поместил текстовое поле, кнопку и div с одним и тем же css:

width:200px;
height:20px;
border:solid 1px #000;
padding:2px;

<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
Zach Lysobey
11 марта 2016 в 19:35
1

Просто чтобы прояснить ... делают ли какие-либо из этих браузеров что-нибудь иначе, чем другие? Я не могу найти никаких различий ... Кроме того, я не голосую против (пока), но это действительно не дает прямого ответа на вопрос, хотя его можно легко отредактировать для этого.

Graham
14 марта 2016 в 11:13
3

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

Zach Lysobey
14 марта 2016 в 19:50
4

Что ж ... если ваше намерение , а не , чтобы ответить на вопрос, тогда это действительно не относится к этому (как «ответ»). Я бы подумал о том, чтобы разместить это на каком-то внешнем ресурсе (возможно, в GitHub или в сообщении в блоге) и связать его в комментарии к исходному Вопросу или одному из ответов.

Dan Nissenbaum
12 сентября 2016 в 09:28
22

@ZachLysobey Из каждого правила есть исключения - это крутая и полезная вещь.

avatar
Zach Lysobey
18 сентября 2015 в 18:37
226

Взгляните на Element.getBoundingClientRect().

Этот метод вернет объект, содержащий width, height и некоторые другие полезные значения:

{
    width: 960,
    height: 71,
    top: 603,
    bottom: 674,
    left: 360,
    right: 1320
}

Например:

var element = document.getElementById('foo');
var positionInfo = element.getBoundingClientRect();
var height = positionInfo.height;
var width = positionInfo.width;

Я считаю, что у этого нет проблем, которые возникают у .offsetWidth и .offsetHeight, где они иногда возвращают 0 (как обсуждается в комментариях здесь)

Другое отличие: getBoundingClientRect() может возвращать дробные пиксели, где .offsetWidth и .offsetHeight округляются до ближайшего целого числа.

Примечание IE8 : getBoundingClientRect не возвращает высоту и ширину в IE8 и ниже. *

Если вы должны поддерживать IE8, используйте .offsetWidth и .offsetHeight:

var height = element.offsetHeight;
var width = element.offsetWidth;

Стоит отметить, что объект, возвращаемый этим методом, на самом деле не является нормальным объектом . Его свойства не перечислимые (поэтому, например, Object.keys не работает из коробки.)

Подробнее об этом здесь: Как лучше всего преобразовать ClientRect / DomRect в простой объект

Ссылка:

Luke
5 марта 2016 в 01:16
12

getboundingClientRect () вернет фактическую ширину и высоту элементов, масштабированных с помощью css, тогда как offsetHeight и offsetWidth - нет.

avatar
Arko
4 марта 2015 в 14:12
-4

Если offsetWidth возвращает 0, вы можете получить свойство ширины стиля элемента и выполнить поиск по нему. "100px" -> 100

/\d*/.exec(MyElement.style.width)

avatar
sanecin
1 марта 2012 в 00:21
1

... кажется, CSS помогает разместить div в центре ...

<style>
 .monitor {
 position:fixed;/* ... absolute possible if on :root */
 top:0;bottom:0;right:0;left:0;
 visibility:hidden;
 }
 .wrapper {
 width:200px;/* this is size range */
 height:100px;
 position:absolute;
 left:50%;top:50%;
 visibility:hidden;
 }

 .content {
 position:absolute;
 width: 100%;height:100%;
 left:-50%;top:-50%;
 visibility:visible;
 }

</style>

 <div class="monitor">
  <div class="wrapper">
   <div class="content">

 ... so you hav div 200px*100px on center ...

  </div>
 </div>
</div>
avatar
mohammad
25 марта 2009 в 11:24
1

также вы можете использовать этот код:

var divID = document.getElementById("divid");

var h = divID.style.pixelHeight;
BrainSlugs83
19 августа 2011 в 20:00
1

Хм, работает в Chrome и IE9, похоже, не работает в Firefox. Это работает только для определенных типов документов?

HolgerJeromin
15 апреля 2019 в 13:15
2

pixelHeight был изобретением Internet Explorer, которое больше не должно использоваться coderhelper.com/q/17405066/2194590

avatar
Kornel
16 ноября 2008 в 20:57
6

Вам нужно только рассчитать его для 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> любого размера и сжимает его до размеров своего содержимого.

avatar
questzen
16 ноября 2008 в 19:50
2

element.offsetWidth и element.offsetHeight должны работать, как было предложено в предыдущем посте.

Однако, если вы просто хотите центрировать контент, есть лучший способ сделать это. Предполагая, что вы используете xhtml strict DOCTYPE. установите маржу: 0, свойство auto и требуемую ширину в пикселях для тега body. Контент выравнивается по центру страницы.

Greg
16 ноября 2008 в 19:53
1

Я думаю, что он тоже хочет центрировать его по вертикали, что является проблемой с CSS, если вы не можете соответствовать каким-то конкретным критериям (например, контент известного размера).

avatar
tvanfosson
16 ноября 2008 в 19:29
72

ПРИМЕЧАНИЕ : этот ответ был написан в 2008 году. В то время лучшим кроссбраузерным решением для большинства людей действительно было использование jQuery. Я оставляю ответ здесь для потомков, и, если вы используете jQuery, это хороший способ сделать это. Если вы используете какой-то другой фреймворк или чистый JavaScript, возможно, вам подойдет принятый ответ.

Начиная с jQuery 1.2.6, вы можете использовать одну из основных функций CSS, height и width (или outerHeight и outerWidth, в зависимости от ситуации).

var height = $("#myDiv").height();
var width = $("#myDiv").width();

var docHeight = $(document).height();
var docWidth = $(document).width();