skip to Main Content

Can anyone help me to create a translation transition on hover in the div when the cursor moves the previous area position of the div?

I have tried:

#test {
  border: 1px solid black;
  width: 100px;
  height: 150px;
}

#test:hover {
  transform: translate(300px, 0px);
  transition: all 3s ease;
}
<div id="test">
  Hover me but the cursor always moves in the previous position of the div's area 
</div>

As you can see, the div always translates when the cursor moves in the previous position of the div. But I want the translation stopped even if the cursor moves in the previous area. Thanks


Illustration:

image

4

Answers


  1. Try like this :

    #test {
      border: 1px solid black;
      width: 100px;
      height: 150px;
      transition: all 3s ease;
    }
    
    #test:hover {
      transform: translate(300px, 0px);
      /* transition: all 3s ease; */
    }
    <div id="test">
                Hover me but the cursor always moves in the previous position of the div's area 
    </div>
    Login or Signup to reply.
  2. Is the onMouseOver function did answer the question?
    I’m sorry, but i hope it could help you in some ways.

    Here how:

    function moveToRight(){
      let myDiv = document.getElementById("test");
      myDiv.style.transform = "translate(300px, 0px)";
      myDiv.style.transition = "all 3s ease";
    }
    #test {
      border: 1px solid black;
      width: 100px;
      height: 150px;
    }
    <div id="test" onMouseOver="moveToRight()">
      Hover me but the cursor always moves in the previous position of the div's area 
    </div>
    Login or Signup to reply.
  3. Make a wrapper, then use :hover on it instead (note that it is inline-block):

    #test {
      border: 1px solid black;
      width: 100px;
      height: 150px;
      transition: all 3s ease;
    }
    
    #wrapper {
      display: inline-block;
    }
    
    #wrapper:hover > #test {
      transform: translate(300px, 0px);
    }
    <div id="wrapper">
      <div id="test">
        Hover me but the cursor always moves in the previous position of the div's area
      </div>
    </div>
    Login or Signup to reply.
  4. As your illustration shows, we can use some box that stays in the previous position. That box may be an actual element (like the #wrapper in InSync’s answer), or a pseudo-element.

    The initial problem with using a pseudo-element is: Since it is a child, it will naturally follow its translating parent.

    To make it "stay in place", we need the pseudo-element to e.g. translate into the opposite direction:

    #test {position: relative} /*Non-`static` position required for `absolute`.*/
    #test::before {
      content: "";
      
      /*Make similar size to parent and place on top:*/
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      
      opacity: .6;
      background-color: lightblue;
    }
    #test:hover::before {
      /*Translate opposite on hover*/
      transform: translate(-300px, 0);
      transition: transform 3s ease;
    }
    
    /*Your CSS:*/
    #test {
      border: 1px solid black;
      width: 100px;
      height: 150px;
    }
    #test:hover {
      transform: translate(300px, 0px);
      transition: transform 3s ease;
    }
    <div id="test">
      Hover me but the cursor always moves in the previous position of the div's area <button onclick="console.log('Pressed')">Press</button>
    </div>

    Notice how the pseudo-element is placed in front of other content because of position: absolute. This obstructs the actual content e.g. from receiving pointer events.

    But we can use the z-index property to place it behind other content.

    By declaring z-index: -1 on the pseudo-element, it will be placed behind. Unfortunately, it will also be placed behind any ancestor in the same stacking context:

    #ancestor {background-color: lightpink}
    #test::before {z-index: -1}
    
    /*Previous CSS:*/
    #test {position: relative}
    #test::before {
      content: "";
      
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      
      opacity: .6;
      background-color: lightblue;
    }
    #test:hover::before {
      transform: translate(-300px, 0);
      transition: transform 3s ease;
    }
    
    #test {
      border: 1px solid black;
      width: 100px;
      height: 150px;
    }
    #test:hover {
      transform: translate(300px, 0px);
      transition: transform 3s ease;
    }
    <div id="ancestor">
      <div id="test">
        Hover me but the cursor always moves in the previous position of the div's area <button onclick="console.log('Pressed')">Press</button>
      </div>
    </div>

    The CSS Transforms Module Level 1 specification reads:

    For elements whose layout is governed by the CSS box model,
    any value other than none for the transform property results in
    the creation of a stacking context.

    Simply put: Luckily the pseudo-element is where it is supposed to be when needed; when #test is translating.

    Alternatively, we could establish a new stacking context to always exist by declaring z-index: 0 on #test.

    #test {z-index: 0}
    
    /*Previous CSS:*/
    #ancestor {background-color: lightpink}
    #test::before {z-index: -1}
    
    #test {position: relative}
    #test::before {
      content: "";
      
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      
      background-color: lightblue;
    }
    #test:hover::before {
      transform: translate(-300px, 0);
      transition: transform 3s ease;
    }
    
    #test {
      border: 1px solid black;
      width: 100px;
      height: 150px;
    }
    #test:hover {
      transform: translate(300px, 0px);
      transition: transform 3s ease;
    }
    <div id="ancestor">
      <div id="test">
        Hover me but the cursor always moves in the previous position of the div's area <button onclick="console.log('Pressed')">Press</button>
      </div>
    </div>

    Note: The pseudo-element is still placed in front of #test‘s box, so it will still obstruct #test‘s background. Since the pseudo-element will be transparent, this shouldn’t be an issue.


    If you want the transition to also apply when not hovering, simply declare it on #test (instead of on #test:hover):

    #ancestor {background-color: lightpink}
    
    #test {
      z-index: 0;
      position: relative;
      border: 1px solid black;
      width: 100px;
      height: 150px;
      transition: transform 3s ease;
    }
    #test:hover {
      transform: translate(300px, 0px);
    }
    
    #test::before {
      content: "";
      z-index: -1;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: lightblue;
      transition: transform 3s ease;
    }
    #test:hover::before {
      transform: translate(-300px, 0);
    }
    <div id="ancestor">
      <div id="test">
        Hover me but the cursor always moves in the previous position of the div's area <button onclick="console.log('Pressed')">Press</button>
      </div>
    </div>

    Note: Don’t forget to make the pseudo-element also transition when not hovering!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search