Search code examples
htmlcssslider

How to slide child element the length of parent on hover?


I am creating a slider in CSS and I'm trying to make the child element slide the length of the parent container, no matter what the width of the parent container is. I currently have the width of the parent container set to 22%. This is my first attempt at trying to make the child slide the length of the parent:

div.parent {
  position: absolute;
  display: block;
  width: 22%;
  height: 60px;
  background: #333;
  color: white;
  cursor: pointer;
  margin: 10px;
  overflow: hidden;
  min-width: 60px;
  max-width: 30%;
}
div.child {
  position: absolute;
  height: 60px;
  width: 60px;
  background-color: #888;
  z-index: 0;
  color: #333;
  text-align: center;
  line-height: 60px;
  font-size: 40px;
  transition: .5s;
}
div.parent:hover div.child {
    transform: translateX(100%);
    background: orange;
    color: #fff;
}
<div class="slider-container">
  <div class="parent">
    <div class="child">
    </div>
  </div>
</div>

Obviously, that's not the solution. I found this JSFiddle that had a pretty good solution. However, when I move mouse within the parent container, the child moves back and forth (see example below). I would like the child element to stay still regardless if the mouse is moving within the slider or not (just like how it behaves in the snippet above).

div.parent {
  position: absolute;
  display: block;
  width: 22%;
  height: 60px;
  background: #333;
  color: white;
  cursor: pointer;
  margin: 10px;
  overflow: hidden;
  min-width: 60px;
  max-width: 30%;
}
div.child-wrapper{
  position: absolute;
  width: 100%;
  height: 100px;
  transition: all .5s;
  z-index: 1;
  background: #333;
}
div.child {
  position: absolute;
  height: 60px;
  width: 60px;
  background-color: #888;
  transition: inherit;
  z-index: 0;
  color: #333;
  text-align: center;
  line-height: 60px;
  font-size: 40px;
}
div.child-wrapper:hover {
    transform: translateX(100%);
    background: orange;
}

div.child-wrapper:hover div.child {
    transform: translateX(-100%);
    background: orange;
    color: #fff;
}
<div class="slider-container">
  <div class="parent">
    <div class="child-wrapper">
    <div class="child">
      </div>
    </div>
  </div>
</div>

Is there another way that I can make the child element slide the length of the parent element, regardless of the width of the parent?


Solution

  • Since you're using an absolutely positioned child you can use the left (and right, top, etc) properties to position the child. See below.

    Remember transform% is the percentage of the element's width, not the parent's. If you see the child cube, translateX just moves it the width of the child in the X direction

    div.parent {
      position: absolute;
      display: block;
      width:52%;
      height: 60px;
      background: #333;
      color: white;
      cursor: pointer;
      margin: 10px;
      overflow: hidden;
      min-width: 60px;
      max-width: 30%;
    }
    div.child {
      position: absolute;
      height: 60px;
      width: 60px;
      left:0;
      background-color: #888;
      transition: inherit;
      z-index: 0;
      color: #333;
      text-align: center;
      line-height: 60px;
      font-size: 40px;
      transition: .5s;
    }
    div.parent:hover div.child {
        left:100%;
        transform: translateX(-100%);
        background: orange;
        color: #fff;
    }
    <div class="slider-container">
      <div class="parent">
        <div class="child">
        </div>
      </div>
    </div>

    Even simpler version here using margin-left instead:

    .parent {
      width: 52%;
      height: 60px;
      background: #333;
      color: white;
      cursor: pointer;
      margin: 10px;
    }
    
    .child {
      height: 100%;
      width: 60px;
      margin-left: 0;
      background-color: #888;
      color: #333;
      text-align: center;
      line-height: 60px;
      font-size: 40px;
      transition: 0.5s;
    }
    
    .parent:hover .child {
      margin-left: 100%;
      translate: -100%;
      background: orange;
    }
    <div class="parent">
      <div class="child">
      </div>
    </div>