btx9000
btx9000

Reputation: 466

How to perform Javascript/CSS3 animation starting from unknown value?

I have a <div> whose height I don't know at page load.

How can I make it slide into view when page loads, and sticking to the bottom of the page?

I expected this code to work, but the div just jumps straight into view without a smooth animation.

var $warning = $('.bottom-warning');
var height = $warning.outerHeight();

/* Put div right below screen */
$warning.css('bottom', -height);

/* Make it visible */
$warning.css('display', 'inline-block');

/* Configure transition */
$warning.css('transition', 'bottom 400ms');

/* Apply new value */
/* SHOULDN'T VALUE BE ANIMATED? */
$warning.css('bottom', 0);

fiddle

If the last line is set to run later (with setTimeout) then it works, but I would like to avoid this as it is bad practice.

Requirement: use native CSS3 transitions or animations, no Javascript animating (including jQuery animations)

Upvotes: 2

Views: 720

Answers (6)

btx9000
btx9000

Reputation: 466

I figured out why the transition doesn't take place.

It seems that browsers will skip the transition when setting animatable properties sequentially. To work around this, we have to force a redraw, as described in http://blog.alexmaccaw.com/css-transitions (scroll down to the "Redraw" section)

So, for example, adding:

var redraw = $warning[0].offsetHeight;

...just before setting the property seems to make everything work the expected way.

fiddle

A big Thank You to Alex MacCaw for an awesome article!

Upvotes: 0

user4563161
user4563161

Reputation:

EDIT

try this new one instead.

$(function() {

  setTimeout(function() {
    $(".bottom-warning").addClass("up");
  }, 500);
});
body,
html {
  margin: 0;
  padding: 0;
}
.bottom-warning {
  background-color: lightblue;
  box-sizing: border-box;
  left: 0;
  padding: 0 20px;
  position: fixed;
  width: 100%;
  bottom: -20px;
  transition: all 1s ease-in-out;
  -webkit-transition: all 1s ease-in-out;
  height: 0px;
  overflow: hidden;
}
.up {
  height: auto;
  padding: 20px;
  bottom: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

<body>
  Lorem ipsum ipsum ipsum.
  <div class="bottom-warning">This site requires an HTML rendering engine!</div>
</body>

https://jsfiddle.net/wp3ndug6/2/

END EDIT

I think you might be over-complicating it sorry if this isn't right on the ball but think its what your looking for.

$(function() {

  setTimeout(function() {
    $(".bottom-warning").addClass("up");
  }, 500);
});
body,
html {
  margin: 0;
  padding: 0;
}
.bottom-warning {
  background-color: lightblue;
  box-sizing: border-box;
  left: 0;
  padding: 20px;
  position: fixed;
  width: 100%;
  bottom: -100%;
  transition: all 1s ease-in-out;
  -webkit-transition: all 1s ease-in-out;
}
.up {
  bottom: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<body>
  Lorem ipsum ipsum ipsum.
  <div class="bottom-warning">This site requires an HTML rendering engine!</div>
</body>

https://jsfiddle.net/wp3ndug6/1/

Upvotes: 0

sergdenisov
sergdenisov

Reputation: 8572

If you had display: none, when set display: inline-block (or display: block, doesn't matter), your transition won't be work. You could use setTimeout(fn, 0) hack — https://jsfiddle.net/sergdenisov/up430ww3/2/.

var $warning = $('.bottom-warning');
var height = $warning.outerHeight();

$warning.css('bottom', -height);
$warning.css('display', 'inline-block');

setTimeout(function() {
    $warning.css('bottom', 0);
}, 0);

About setTimeout(fn, 0)Why is setTimeout(fn, 0) sometimes useful?.

Upvotes: 0

chomp chomp
chomp chomp

Reputation: 68

Since you are already using JQuery to animate your css, I suggest looking up animate. It provides a smooth sliding animation and you can specify how fast you want the animation to be. http://api.jquery.com/animate/

$warning.animate({
      bottom: "0px"
    }, 400);

Upvotes: 0

Paulie_D
Paulie_D

Reputation: 115096

Translate the element off the page and the apply a class on document.ready to bring it back up.

.bottom-warning {
    background-color: lightblue;
    box-sizing: border-box;
    left: 0;
    padding: 20px;
    position: fixed;
    width: 100%;
    bottom:0;
    height: auto;
    transform:translateY(100%);
    transition: transform .5s ease;

}

JSfiddle Demo

$(document).ready(function() {
  $('.bottom-warning').addClass('up');
});
body,
html {
  margin: 0;
  padding: 0;
}
.bottom-warning {
  background-color: lightblue;
  box-sizing: border-box;
  left: 0;
  padding: 20px;
  position: fixed;
  width: 100%;
  bottom: 0;
  height: auto;
  transform: translateY(100%);
  transition: transform .5s ease;
}
.bottom-warning.up {
  transform: translateY(0%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

<body>Lorem ipsum ipsum ipsum.
  <div class="bottom-warning">This site requires an HTML rendering engine!</div>
</body>

Upvotes: 3

sbeliv01
sbeliv01

Reputation: 11820

If you want to have the "slide in" effect, from the bottom, you'll have to have the default bottom position somewhere off screen, like -999em. Otherwise, there isn't any "transition" because the element doesn't have a starting point to reference. Also, give the transition a time amount e.g. bottom 1s.

$(function () {
    
    setTimeout(function () {
        var $warning = $('.bottom-warning');
        var height = $warning.outerHeight();
        
        /* Put div right below screen */
        $warning.css('bottom', -height);
        
        /* Make it visible */
        $warning.css('display', 'inline-block');
        
        /* Configure transition */
        $warning.css('transition', 'bottom 1s');
        
        /* Apply new value */
        /* SHOULDN'T VALUE BE ANIMATED? */
        $warning.css('bottom', 0);
    }, 500);
});
body, html {
    margin: 0;
    padding: 0;
}

.bottom-warning {
    background-color: lightblue;
    box-sizing: border-box;
    display: none;
    left: 0;
    bottom: -999em;
    padding: 20px;
    position: fixed;
    width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Lorem ipsum ipsum ipsum.
    <div class="bottom-warning">This site requires an HTML rendering engine!</div>

Upvotes: 1

Related Questions