jQuery UI blind effect - reveal from bottom
jquery, jquery-ui
Solution
The effect you're looking for is a little tricky to achieve, but it can be done, even without a wrapper element.
The main issue here is that elements naturally render top-down, not bottom-up. Animating both the `top` and `height` CSS properties of a relatively-positioned element allows us to implement a slide-up effect, but the element will still render top-down:
+-------------------------------------------+
| | ^
| | | Hidden area collapses upwards.
| | |
+-------------------------------------------+ <-- 'top'
| | ^
| | Upper part of element (visible). | |
| | | | Animation goes bottom-up.
| | Element still renders top-down. | |
| | | |
+--|----------------------------------------+ <-- 'top + height'
| | | |
| | Lower part of element (hidden). | |
| V | |
+-------------------------------------------+
If we want to simulate bottom-up rendering, we have to modify the scrollTop property of the element during the animation, in order for its lower part to always remain in view:
+-------------------------------------------+
| | ^
| | Upper part of element (hidden). | | Hidden area collapses upwards.
| | | |
+--|----------------------------------------+ <-- 'top' and 'scrollTop'
| | | ^
| | Element still renders top-down. | |
| | | | Animation goes bottom-up.
| | Lower part of element (visible). | |
| V | |
+-------------------------------------------+ <-- 'top + height'
We can use animate() with `scrollTop`, but doing so in conjunction with `top` and `height` did not work correctly in my tests (I suspect `scrollTop` is reset when `top` or `height` are modified in the first animation step, so it ends up stuck to `0`).
To work around this, we can handle `scrollTop` ourselves through the optional step function we can pass to `animate()`. This function is called with two arguments, `now` and `fx`, `now` being the current value of the animated property and `fx` being a wrapper object around useful information, like the element and property being animated.
Since we always want `scrollTop` to be the same as `top`, we only have to test if `top` is being animated in our `step` function. If it is, we set `scrollTop` to `now`. This solution gives acceptable results, although it flickers a little too much for my taste (that might be an artifact of my browser, though).
So, in summary, to implement that effect, we have to:
- Fetch the element's original height,
- Make the element `position: relative;` so we can animate its `top` property,
- Collapse the element by setting `top` to the original height and `height` to `0`,
- Show the element (necessary in your fiddle since `display: none;` is applied),
- Animate `top` to `0` and `height` to the original height,
- Give `scrollTop` the value of `top` on each animation step.
Resulting in the following code:
$("#click").click(function() {
var $revealMe = $("#revealMe");
var originalHeight = $revealMe.height();
$revealMe.css({
position: "relative",
top: originalHeight,
height: 0
}).show().animate({
top: 0,
height: originalHeight
}, {
duration: 1000,
step: function(now, fx) {
if (fx.prop == "top") {
$(fx.elem).scrollTop(now);
}
}
});
});
You can test it in this fiddle.
Problem
This could be really obvious and I'm completely missing it. I've searched for hours and can't seem to find a way to, using jQuery, reveal a hidden div from the bottom up. What I am trying to achieve is exactly as in the following link, but in reverse: http://jqueryui.com/demos/show/ I can slide a div from the bottom to the top, but this reveals itself as it moves, rather than being 'masked' in. Like I said, this could (should?) be really obvious and I'm not seeing it, but I've been looking for ages and can't find a solution to this relatively simple problem. Thanks, Ronnie