Is getBoundingClientRect () left invalid value?

I want to position the div ".indicator" where the li element starts, so for example, if I want to position the div in relation to the second li, I:

indicator.style.left = li[1].getBoundingClientRect().left+"px";

      

This is my code:

var li = document.querySelectorAll(".ulcontainer > li");

var indicator = document.querySelector(".indicator");

indicator.style.left = li[1].getBoundingClientRect().left+"px";
      

html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
.ulcontainer {
    white-space: nowrap;
    padding: 0;
    position: relative;
}
.ulcontainer li {
    list-style: none;
    display: inline-block;
    border: 1px solid;
    padding: 0 20px;
}

.indicator {
    background-color: red;
    display: inline-block;
    position: relative;
}
      

<ul class="ulcontainer">
    <li>OPTION 1</li><li>OPTION 2</li><li>OPTION 3</li>
</ul>
<div class="indicator">indicator</div>
      

Run code


The problem is that the div getBoundingClientRect (). left does not return the correct value for li elements. If you run the example, you will see that ".indicator" does not start at the beginning of the current li.

Why is getBoundingClientRect () not returning a return value?

+3


source to share


1 answer


.indicator

has relative positioning. So any offset will be relative to the default position, not relative to the browser window. (By comparison, a fixed position is almost always relative to the browser window, and an absolute position relative to the nearest located ancestor is often the browser window.)

Since it .indicator

is a block-level element and its immediate parent is the document body, its left position by default equals the left edge of the document body.

Set the body margin to 0 and it will be aligned:



var li = document.querySelectorAll(".ulcontainer > li");

var indicator = document.querySelector(".indicator");

indicator.style.left = li[1].getBoundingClientRect().left+"px";
      

body {
  margin: 0;
}
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
.ulcontainer {
    white-space: nowrap;
    padding: 0;
    position: relative;
}
.ulcontainer li {
    list-style: none;
    display: inline-block;
    border: 1px solid;
    padding: 0 20px;
}

.indicator {
    background-color: red;
    display: inline-block;
    position: relative;
}
      

<ul class="ulcontainer">
    <li>OPTION 1</li><li>OPTION 2</li><li>OPTION 3</li>
</ul>
<div class="indicator">indicator</div>
      

Run code


+3


source







All Articles