Tim
Tim

Reputation: 901

How to animate alignment from top to bottom on hover?

I'm looking for a way to animate a hover transition with css. And I'm hoping to keep it pure css. If not I'll use jquery as backup.

This would be my goal:

A container with a content div. And when hovering it would animate / slide up. As illustrated: enter image description here

I've tried something like the code below. Problem is than transition does not animate the auto part. The content has a variable height. So it differs each time. (per grid item)

    .my_container{
        position: relative;
        width: 100%;
        padding-top: 160%;
        overflow: hidden;
    }

    .my_container > .my_content{
        position: absolute;
        top: 0;
        bottom: auto;
        left: 0;
        right: 0;
    }


    .my_container > my_content:hover{
        top: auto;
        bottom: 0;
    }

    .my_container * {
        -webkit-transition: all .6s ease-in-out;
        -moz-transition: all .6s ease-in-out;
        -o-transition: all .6s ease-in-out;
        transition: all .6s ease-in-out;
    }

I thought about transform: translateY(); But as far as I know this only works with percentages and px.

The goal is to animate it aligned top to bottom on hover.

(typing this made me think of another thing. This would be useless on a mobile device, right? :) )

Upvotes: 6

Views: 4811

Answers (2)

Tim
Tim

Reputation: 901

This is my jQuery approach. It compares the size of the container and the content. And if it's bigger than the container it animates the difference up so it all comes visible.

var $ = jQuery;

$(document).ready(function () {

    $('.post_grid_item').hover(

        function() {

            $containter = $(this).find('.content_slide');
            $content = $(this).find('.content_slide > .vce-row-content');

            $content_height    = $content.outerHeight();
            $containter_height = $containter.outerHeight() ;

            // if content is bigger than container
            if( $content_height >  $containter_height ) {

                $content_hover_offset = $containter_height - $content_height;

                $content.animate({
                    top: $content_hover_offset + 'px',
                }, 'fast');
            }

        },function() {

            $containter = $(this).find('.content_slide');
            $content = $(this).find('.content_slide > .vce-row-content');

            $content.animate({
                top: '0',
            },'fast');
        }
    );


});

This would give me some more conditional flexibility when adding specific mobile device conditions.

If anyone sees some improvements let me know.

Upvotes: 0

Temani Afif
Temani Afif

Reputation: 273668

In case there is a known relation between the child and parent element you can then easily apply translation.

Here is a basic example

.box {
  height:100px;
  width:50px;
  margin:50px;
  border:3px solid;
  position:relative;
}
.box:before {
  content:"";
  position:absolute;
  top:0;
  width:100%;
  height:143%;
  background:red;
  transition:1s all;
}
.box:hover::before {
  transform:translateY(-30%) 
  /* 143% is 100%
     100% is X% ---> X = 70% so we move by (100% - 70%)
  */
}
<div class="box">

</div>

You can express with a CSS variable:

.box {
  height:100px;
  width:50px;
  margin:50px;
  display:inline-block;
  border:3px solid;
  position:relative;
}
.box:before {
  content:"";
  position:absolute;
  top:0;
  width:100%;
  height:calc(var(--p)*1%);
  background:red;
  transition:1s all;
}
.box:hover::before {
  transform:translateY(calc((10000/var(--p))*1% - 100%)) 
}
<div class="box" style="--p:143;">

</div>

<div class="box" style="--p:170;">

</div>

<div class="box" style="--p:120;">

</div>

UPDATE

In case of dynamic content you can add small JS code like below:

$('.box').each(function() {
  var h0 = $(this).height();
  var h1 = $(this).find('span').height();
  
  $(this).css('--t',(h0-h1));
})
.box {
  height: 100px;
  width: 50px;
  margin: 50px;
  display: inline-block;
  border: 3px solid;
  position: relative;
}

.box span {
  position: absolute;
  top: 0;
  width: 100%;
  background: red;
  transition: 1s all;
}

.box:hover span{
  transform: translateY(var(--t));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
  <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed est ex, pretium tempus turpis vitae, </span>
</div>

<div class="box">
  <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
</div>

<div class="box">
  <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed est ex, pretium </span>
</div>

Upvotes: 5

Related Questions