2

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)

btx9000
  • 438
  • 4
  • 10

6 Answers6

3

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>
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
1

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>
sbeliv01
  • 11,550
  • 2
  • 23
  • 24
  • This works, but I can't understand why. At the moment when the transition is configured, I already set `bottom` to `-height`, so the property _does_ have a defined value. Why does it make a difference to have a value set at page load? – btx9000 May 11 '15 at 14:55
  • `-height` equates to `-58`, for instance, which isn't a properly defined value for the `bottom` positioning. If you wanted to set the `bottom` properly via jQuery, you'd need to write it like this `$warning.css('bottom', '-'+ height +'px');` – sbeliv01 May 11 '15 at 16:17
  • Setting the property with 'px' doesn't change anything. In fact jQuery already does that behind the scenes. – btx9000 May 12 '15 at 12:43
0

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/

  • Your fiddle doesn't seem to work. In any case, I want the animation to start from immediately below the page, that's the issue. Your code seems to make it start from -100% below the end of the viewport. – btx9000 May 11 '15 at 15:12
  • https://jsfiddle.net/wp3ndug6/1/ sorry no library selected and I also had the code snippet there which works. as for the 100% thing its pretty much unnoticeable. –  May 11 '15 at 15:16
0

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);
  • Using native CSS3 transition or equivalent is a requirement, like the question says. AFAIK jQuery's animate does not translate to CSS3 transitions – btx9000 May 11 '15 at 15:03
0

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?.

Community
  • 1
  • 1
sergdenisov
  • 8,327
  • 9
  • 48
  • 63
  • I actually tried it but it didn't seem to work unless I give it a value of something like 30 instead. If you can make it work with 0 please share a fiddle – btx9000 May 11 '15 at 15:09
  • @btx9000 It works without main `setTimeout(fn, 500)`, check https://jsfiddle.net/sergdenisov/up430ww3/2/, I updated answer. – sergdenisov May 11 '15 at 15:17
0

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!

btx9000
  • 438
  • 4
  • 10