Search code examples
javascriptcsswidth

Calculate the value of span's scrollWidth,offsetWidth,clientWidth


The Element.scrollWidth read-only property is a measurement of the width of an element’s content, including content not visible on the screen due to overflow.The post in SO had an introduction on scrollWidth,offsetWidth,clientWidth in detail

an introduction on scrollWidth,offsetWidth,clientWidth in detail

enter image description here

Border ,padding ,margin all set to zero and overflow is hidden in the example,in imgbox1 there is a white space between images,no white space in imgbox2.Click Run code snippet in firefox.

var imgbox1 = document.getElementById("imgbox1");
imgbox1.innerHTML += imgbox1.innerHTML;
var span1 = document.getElementById("span1");
console.log("span1.scrollWidth " + span1.scrollWidth);
var imgbox2 = document.getElementById("imgbox2");
imgbox2.innerHTML += imgbox2.innerHTML;
var span2 = document.getElementById("span2");
console.log("span2.scrollWidth " + span2.scrollWidth);
* {
  padding: 0px;
  margin: 0px;
  border: 0px;
}

div {
  border: 0px;
  width: 933px;
  height: 129px;
  overflow: hidden;
  white-space: nowrap;
}
<div id="imgbox1">
  <span id="span1">
        <a href=""><img src="https://i.sstatic.net/b7J9w.jpg" alt=""></a>
        <a href=""><img src="https://i.sstatic.net/yh7YJ.jpg" alt=""></a>
        <a href=""><img src="https://i.sstatic.net/5uIog.jpg" alt=""></a>
        <a href=""><img src="https://i.sstatic.net/r5GCW.jpg" alt=""></a>
    </span>
</div>
<br>
<div id="imgbox2">
  <span id="span2"><a href=""><img src="https://i.sstatic.net/b7J9w.jpg" alt=""></a><a href=""><img src="https://i.sstatic.net/yh7YJ.jpg" alt=""></a><a href=""><img src="https://i.sstatic.net/5uIog.jpg" alt=""></a><a href=""><img src="https://i.sstatic.net/r5GCW.jpg" alt=""></a>
    </span>
</div>

We got the output

span1.scrollWidth 39 
span2.scrollWidth 10

How to explain the scrollWidth in span1 is 39px while scrollWidth in span2 is 10px?Why the scrollWidth in span1 is not 40px.

window.onload = function() {
  var imgbox = document.getElementById("imgbox");
  imgbox.innerHTML += imgbox.innerHTML;
  var span = imgbox.getElementsByTagName("span");
  console.log("span[0].offsetWidth " + span[0].offsetWidth);
  console.log("imgbox.scrollWidth - imgbox.clientWidth " + (imgbox.scrollWidth - imgbox.clientWidth));
}
* {
  border: 0px;
  margin: 0px;
  padding: 0px;
}

div {
  width: 933px;
  height: 129px;
  overflow: hidden;
  white-space: nowrap;
}
<div id="imgbox">
  <span>
        <a href=""><img src="https://i.sstatic.net/b7J9w.jpg" alt=""></a>
        <a href=""><img src="https://i.sstatic.net/yh7YJ.jpg" alt=""></a>
        <a href=""><img src="https://i.sstatic.net/5uIog.jpg" alt=""></a>
        <a href=""><img src="https://i.sstatic.net/r5GCW.jpg" alt=""></a>
    </span>
</div>

We get the output:

span[0].offsetWidth 943 
imgbox.scrollWidth - imgbox.clientWidth 942

Please point out where is the 1 px difference (943-942) between them.


Solution

  • This is coming from the fact that you are trying to use span tag as a container. As it is default display: inline-block. It is not applying the same calculation as you show in your image. The image discribe the all the width for a display: block; element.

    Each display as its own width rules. To be extreme, if you would apply display: none;, you cannot expect to have the same rules as in your image.

    So set display: block and rules will be respected:

    span{
      display: block;
    }
    

    And you wont have any problem no matter what.

    DEMO:

    window.onload = function() {
      var imgbox = document.getElementById("imgbox");
      imgbox.innerHTML += imgbox.innerHTML;
      var span = imgbox.getElementsByTagName("span");
      console.log("span[0].offsetWidth " + span[0].offsetWidth, '\n', "imgbox.scrollWidth - imgbox.clientWidth " + (imgbox.scrollWidth - imgbox.clientWidth));
    }
    * {
      border: 0px;
      margin: 0px;
      padding: 0px;
    }
    
    div {
      width: 933px;
      height: 129px;
      overflow: hidden;
      white-space: nowrap;
    }
    span{
      display: block;
    }
    <div id="imgbox">
      <span>
            <a href=""><img src="https://i.sstatic.net/b7J9w.jpg" alt=""></a>
            <a href=""><img src="https://i.sstatic.net/yh7YJ.jpg" alt=""></a>
            <a href=""><img src="https://i.sstatic.net/5uIog.jpg" alt=""></a>
            <a href=""><img src="https://i.sstatic.net/r5GCW.jpg" alt=""></a>
        </span>
    </div>