Search code examples
javascriptcsscss-transitionsgetboundingclientrect

CSS get div left position before a transformation


Given :

const display = document.querySelector('.display');
const container = document.querySelector('.outer-div');

document.addEventListener("click", (event) => {
  if (!event.target.closest("button")) return;
  
  if(event.target.id === "button") {

    if(event.target.textContent === "left"){
        console.log("before : " + display.getBoundingClientRect().left);
        display.style.transform += "translateX(50px)";
        console.log("after : " + display.getBoundingClientRect().left);
    }
  }
    
});
.meta-div {
  box-shadow: 0 0 25px  rgba(0, 0, 0, 0.4);
  position: relative;
  overflow: hidden; /* allows the border-radius to be visible. */
  width: 14rem;
}
.outer-div {
  color: black;
  text-overflow: normal;
  white-space: nowrap;
  overflow: hidden;
  text-align: right;
}

.display {
  float:right;
  transition: transform 250ms;
}
<div class="meta-div">
  <div class="outer-div">
    <div class="display">111 + 222 + 333 + 444 + 555 + 666 + 777 + 888 + 999</div>
  </div>
</div>
 <button id="button">left</button>

my goal is to extract the display div left position relative to its container before and after the transformation : display.style.transform += "translateX(50px)";.


I understand that the function .getBoundingClientRect() returns dimensions and location of elements as floating-point numbers after performing CSS transforms, so here I should use some other function to extract the position before the transformation. Looking at the 3 other questions on SO, the solution seems to use offsetLeft but in my case console.log(display.offsetLeft) just returns -127 on every successive left button click, while it is supposed to be incrementing by 50 pixels.

I don't know how to extract the div's left position before the translateX() transformation. I have been spending long hours on this.

Does anyone have an idea or hints?


Solution

  • Because you are using transition animation, you'll need listen for transitionend event:

    const display = document.querySelector('.display');
    const container = document.querySelector('.outer-div');
    
    document.addEventListener("click", (event) => {
      if (!event.target.closest("button")) return;
      
      if(event.target.id === "button") {
    
        if(event.target.textContent === "left"){
            console.log("before : " + display.getBoundingClientRect().left);
            display.style.transform += "translateX(50px)";
        }
      }
        
    });
    
    display.addEventListener('transitionend', e => {
      console.log("after : " + display.getBoundingClientRect().left);
    });
    .meta-div {
      box-shadow: 0 0 25px  rgba(0, 0, 0, 0.4);
      position: relative;
      overflow: hidden; /* allows the border-radius to be visible. */
      width: 14rem;
    }
    .outer-div {
      color: black;
      text-overflow: normal;
      white-space: nowrap;
      overflow: hidden;
      text-align: right;
    }
    
    .display {
      float:right;
      transition: transform 250ms;
    }
    <div class="meta-div">
      <div class="outer-div">
        <div class="display">111 + 222 + 333 + 444 + 555 + 666 + 777 + 888 + 999</div>
      </div>
    </div>
     <button id="button">left</button>