12

Here is a crude example to help show what I would like: http://jsfiddle.net/GVaNv/

I was wondering if there is anyway to make the overlay transition in from the left, but to then leave from the right side.

So, on hover, the overlay comes in as it is in the example, but instead of retreating back to the left, to transitions to the right.

Is this possible? (doesn't necessarily need to use transition, I'm open to any way to do it).

justinw
  • 3,856
  • 5
  • 26
  • 41
  • It'd be trivial if you added a tiny bit of JavaScript to add a class depending if it were hover *on* or *off*. – alex Apr 08 '14 at 06:18

3 Answers3

22

Here is a simple solution that does not require more HTML or JavaScript:

.box {
    height: 100px;
    width: 250px;
    background: aqua;
    position: relative;
    overflow: hidden;
}

.overlay {
    position: absolute;
    background-color: rgba(0, 0, 0, 0.5);
    width: 100%;
    color: white;
    padding: 10px;
    left: -270px;
    margin-left: 520px;
    bottom: 0;
    transition: left 300ms linear, margin-left 300ms ease-out;
}

.box:hover .overlay {
    left: 0;
    margin-left: 0;
    transition: left 300ms ease-out;
}
<div class="box">
    <div class="overlay">
        Overlay
    </div>
</div>

This leverages the margin for the animation. It works as follows:

  1. The overlay resting state is set to the right of the element using a margin (while the left is positioned to the left of the element).
  2. Upon hover, we set the margin to 0 without an animation. This allows the left animation to occur from the left side of the element.
  3. Upon mouse-out, the margin is animated to go to its resting state on the right side of the element.
jsea
  • 3,859
  • 1
  • 17
  • 21
  • 2
    No need to use `0ms`, just don't include it in the transition list, ie: `transition: left 300ms ease-out;`. Great solution. – Qtax Apr 08 '14 at 08:25
2

I tried to achieve this only with CSS including additiona div markup as follows DEMO

HTML

<div class="box">
    <div class="overlay">
        Overlay
    </div>
    <div class="overlayFalse">
        Overlay false
    </div>
</div>

CSS

.box {
    height: 250px;
    width: 250px;
    background: aqua;
    position: relative;
    overflow: hidden;
}

.overlay, .overlayFalse {
    position: absolute;
    background-color: rgba(0, 0, 0, 0.5);
    width: 96%;
    color: white;
    padding: 2%;
    right:-274px;
    bottom: 0;
    transition: right 300ms ease-out, left 300ms ease-out;

}

.overlayFalse{
    opacity:0;
    right:auto;
    left:-274px;
}

.box:hover .overlay {
    right:0;
    opacity:0;
}

.box:hover .overlayFalse{
    opacity:1;
    left:0;
}
Pravin W
  • 2,451
  • 1
  • 20
  • 26
  • I think it could be possible to do without the extra duplicate element (while still only using CSS). – Qtax Apr 08 '14 at 08:03
  • @Qtax - can you give it a try It would be great to achieve this without extra markup with css only – Pravin W Apr 08 '14 at 08:05
1

Maybe you can make use of CSS3 Animations, using one for sliding in and another one for sliding out:

@keyframes overlay-in {
  from {
    left: -999px;
  }

  to {
    left: 0;
  }
}

@keyframes overlay-out {
  from {
    left: 0;
  }

  to {
    left: 999px;
  }
}

Now you can apply the overlay-in animation on :hover and the other one on the normal element definition:

.box .overlay {
    /* other definitions ... */
    animation-name: overlay-out;
    animation-duration: 1000ms;
    animation-fill-mode: none;
}

.box:hover .overlay {
    animation-name: overlay-in;
    animation-duration: 600ms;
    animation-fill-mode: forwards;
}

But there is one problem with this: The slide-out animation will play once on page load. I can't figure out a way to prevent this without a tiny JavaScript, adding a class to the overlay on the first mouseout event. I've done it this way in a JSFiddle.

But of course, as soon as you require JavaScript, you could also have used simple transitions. But this method works even without JavaScript if you can live with the animation playing on page load.

Callidior
  • 2,899
  • 2
  • 18
  • 28