如何检索HTML元素的实际宽度和高度?


892

假设<div>我希望在浏览器的显示(视口)中居中。为此,我需要计算<div>元素的宽度和高度。

我应该使用什么?请提供有关浏览器兼容性的信息。


9
请记住,通过任何方法获取元素的高度始终会对性能产生影响,因为它会使浏览器重新计算页面中所有元素的位置(重排)。因此,请避免执行过多操作。查看此列表以了解哪种类型的东西会触发重排。
Marcelo Lazaroni's

Answers:


1285

您应该使用.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,
}

174
谨防!如果您最近对元素进行了某些DOM修改,则offsetHeight / offsetWidth可以返回0。修改元素后,可能必须在setTimeout调用中调用此代码。
Dan Fabulich 2010年

37

30
在什么情况下返回0?
猎豹

46
@JDandChips:offsetWidth如果元素为display:none,则为0 ,而width在这种情况下,计算出的值可能仍为正值。visibility:hidden不会影响offsetWidth
MrWhite 2012年

20
@Supuhstar都有不同的含义。offsetWidth返回包含内容,填充和边框的“整个”框;while仅clientWidth返回内容框的大小(因此,只要元素具有任何非零的填充和/或边框,它将具有较小的值)。(为清晰起见,进行了mod编辑)
Edurne Pascual 2014年

200

看一看Element.getBoundingClientRect()

该方法将返回包含一个对象widthheight以及其他一些有用的值:

{
    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转换为纯对象

参考:


8
getboundingClientRect()将返回通过CSS缩放而元件的实际宽度和高度offsetHeightoffsetWidth不会。
路加福音

66

注意此答案写于2008年。当时,对于大多数人来说,最好的跨浏览器解决方案实际上是使用jQuery。我为后代保留答案,如果您使用的是jQuery,这是一种很好的方法。如果您使用的是其他框架或纯JavaScript,那么接受答案可能是解决之道。

在jQuery 1.2.6中,你可以使用的核心一个CSS功能heightwidth(或outerHeightouterWidth,如适用)。

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

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

45

以防万一对任何人有用,我将文本框,按钮和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或不使用iquery的情况下进行尝试,在使用和不使用的情况下进行尝试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

1
只是要清楚...这些浏览器中的任何一个有什么不同之处吗?我找不到任何区别...而且,我还没有投票(尚未),但这并不能真正直接回答问题,尽管可以很容易地对其进行编辑。
Zach Lysobey '16

1
并非旨在回答问题-已被回答。仅提供一些有用的信息,是的,所有主要的最新版本的浏览器都同意这些值-这是一件好事。
格雷厄姆

3
好吧……如果您的意图不是回答问题,那么这实际上并不属于此处(作为“答案”)。我会考虑将其放在一些外部资源(例如GitHub的要点,或博客文章)中,并将其链接到对原始问题或答案之一的评论中。
Zach Lysobey

21
@ZachLysobey每条规则都有例外-这是很酷的,有用的东西。
Dan Nissenbaum

16

根据MDN:确定元素的尺寸

offsetWidthoffsetHeight返回“元素占用的总空间量,包括可见内容的宽度,滚动条(如果有),填充和边框”

clientWidthclientHeight返回“实际显示的内容占用了多少空间,包括填充,但不包括边框,边距或滚动条”

scrollWidthscrollHeight返回“内容的实际大小,无论当前可见多少内容”

因此,这取决于所测量的内容是否期望超出当前可见区域。


5

您只需要为IE7和更早的版本(仅在您的内容没有固定大小的情况下)进行计算即可。我建议使用HTML条件注释,以将hack限制为不支持CSS2的旧IE。对于所有其他浏览器,请使用以下命令:

<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>任何大小,并将其收缩包装到其内容的大小。


3

修改元素样式很容易,但是读取值有点棘手。

除非您在javascript中使用内置的方法调用getComputedStyle,否则JavaScript无法读取任何来自css(内部/外部)的元素样式属性(elem.style)。

getComputedStyle(element [,pseudo])

元素:要读取其值的元素。
伪:伪元素(如果需要),例如:: 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%的值是相对的。浏览器将使用计算出的值并使所有单位固定且为绝对单位,例如: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); // empty string in Firefox
</script>

有关更多信息,请参见https://javascript.info/styles-and-classes


1

正如上一篇文章中所建议的,应该执行element.offsetWidth和element.offsetHeight。

但是,如果只想使内容居中,则有更好的方法。假设您使用xhtml严格DOCTYPE。设置body标签的margin:0,auto属性和所需的宽度(以px为单位)。内容与页面居中对齐。


1
我认为他也想将其垂直居中,除非您能够满足某些特定条件(例如,已知尺寸的内容),否则CSS都是正确的选择
Greg

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>


0

如果需要将其居中在浏览器的显示端口中;您只能使用CSS来实现

yourSelector {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
} 

-2

这是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 {

        }
    }
}

只是要清楚,这是iOS swift代码,对不对?不是JavaScript。我撤消了反对票(b / c,这实际上可能非常有用),但请注意,这不能回答问题,并且可能更适合于另一个特定于iOS的问题。如果还不存在,也许考虑问一个并自我回答。
Zach Lysobey

-3

如果offsetWidth返回0,则可以获取元素的样式width属性,并在其中搜索数字。“ 100px”-> 100

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.