Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clientWidth and clientHeight report zero while getBoundingClientRect is correct

In MDN's description of Element.clientWidth it says.

Note: I've since updated MDN according to @potatopeelings answer.

The Element.clientWidth property is the inner width of an element in pixels. It includes padding but not the vertical scrollbar (if present, if rendered), border or margin.

This property will round the value to an integer. If you need a fractional value, use element.getBoundingClientRect().

From this I understand that other than rounding clientWidth should be the same as getBoundingClientRect().width.

However I see that for many elements (where display is inline?) the clientWidth (and height) are zero, while the values returned by getBoundingClientRect seem correct.

Searching on stackoverflow brings some answers saying that this happens before the document is in a ready state but I see this all the time, not just when the page is loading.

This behaviour is consistent for all browsers I checked, where is it specified that this should be the behaviour?

Sample:

function str(name, width, height) {
  return name + ': (' + width + ', ' + height + ')';
}

function test() {
  var s = document.getElementById('s');
  var rect = s.getBoundingClientRect();
  document.getElementById('out').innerHTML =
    str('client', s.clientWidth, s.clientHeight) + '<br/>' +
    str('bounding', rect.width, rect.height);
}
 <span id="s">A span</span><br/> <button onclick="test()">Test</button>
<hr />
<div id="out"></div>
like image 236
Motti Avatar asked Sep 07 '15 12:09

Motti


People also ask

What is clientWidth and clientHeight?

Using clientWidth and clientHeight you're able to get the pixel dimensions of an HTML element. The dimensions are calculated using the dimensions of content inside the HTML element, along with the padding. Note: Borders, margins, or scrollbars (if present) are excluded when computing clientWidth and clientHeight.

What does clientWidth mean?

The clientWidth property returns the viewable width of an element in pixels, including padding, but not the border, scrollbar or margin.

What is offsetWidth and scrollWidth?

offsetWidth is the outer width (ie. the space occupied by the element, including padding and borders) scrollWidth is the total width including stuff that is only visible if you scroll.

How do I use clientHeight?

clientHeight can be calculated as: CSS height + CSS padding - height of horizontal scrollbar (if present). When clientHeight is used on the root element (the <html> element), (or on <body> if the document is in quirks mode), the viewport's height (excluding any scrollbar) is returned.

What is the difference between clientwidth and getboundingclientrect?

Also clientWidth and getBoundingClientRect serve different purposes and may return different values. The latter also considers transforms and returns the dimensions of an element as it is actually rendered. If clientWidth returned 1000 in this case then the width of getBoundingClientRect would be 500.

Why does clientheight return 0 when measuring height?

Though despite the element having display: block clientHeight would return 0. That is because I was using .innerHTML ( developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) in another place, another file even. And while doing so and HTML was added all other elements I measured would return 0 for their height.

Does clientwidth and clientheight work with inline HTML elements?

Block-level: clientWidth and clientHeight does NOT work with inline HTML elements (like span, em, or a ). It’ll just return 0! Rounded Values: Values are rounded to the nearest integer.

Why scrollheight is always 0 on GitHub?

Already on GitHub? Sign in to your account Based on scrollHeight am displaying footer or binding scroll event. So, in this case, scrollHeight is always 0.


2 Answers

From the spec (http://www.w3.org/TR/cssom-view/#dom-element-clientwidth)

The clientWidth attribute must run these steps:

1.If the element has no associated CSS layout box or if the CSS layout box is inline, return zero.
...

like image 143
potatopeelings Avatar answered Oct 17 '22 01:10

potatopeelings


In addition to @potatopeelings's answer:

Inline elements have no intrinsic or specified dimensions. E.g. you cannot define a width for a span (unless you change it's display property).

Also clientWidth and getBoundingClientRect serve different purposes and may return different values. The latter also considers transforms and returns the dimensions of an element as it is actually rendered.

.class {
  transform: scale(0.5);
}

If clientWidth returned 1000 in this case then the width of getBoundingClientRect would be 500.

You can regard clientWidth as "how much space do I have available within the element" and getBoundingClientRect as "how much space does the element occupy on the screen". So in our case the element would have enough space to contain two 500px elements side by side and it would occupy 500px on the screen.

like image 28
a better oliver Avatar answered Oct 17 '22 03:10

a better oliver