Reputation: 3680
I'm designing a website that makes use of both parallax scrolling and modal boxes. When you open one of the modal boxes, I'm using jQuery and CSS to add a class to the popup's DIV element so that its opacity goes from 0 to 100; I'm using a transition to make this look pretty. When you close the box, jQuery strips the class out to set the opacity back to 0.
So that the modal boxes are more readable, I've put an overlay behind them (actually a containing DIV) that overlays a transparency over the rest of the screen using a width and height of 100%. I also use the same trick to take the opacity of this from 0 to 100 when the box is opened, and vice versa when it's closed.
The problem lies in that even at opacity 0, the overlay is still "above" some of the screen, rendering links and text viewable but not selectable. I've tried setting the Z-Index to 0 and -1 when the overlay is meant to be hidden, but because the parallax scrolling (I'm using a customised version of the SCRN template, for reference http://rodrigob.com/themes/scrn/) uses Relative, Fixed and Absolute positioning, the Z-Index only applies to some of the site.
As a workaround, styling the overlay with Visibility:Hidden works (as does Display:None, but I want to avoid that for accessibility reasons), but this can't be managed by a transition, so when the modal closes, it just disappears instead of fading out nicely.
Is there any way around this? I thought setting the Visibility to Hidden after the transition from 100 opacity to 0 had happened would work, but I don't know how to do this, if it can even be done at all.
Thanks in advance.
Upvotes: 3
Views: 1518
Reputation: 183
Setting "opacity: 100" or "visibility: hidden" on the overlay isn't actually removing the overlay. What you want to do is remove the element.
Conceptually speaking the overlay is still there. Its like glass above your content, you can see but you can't touch, the invisible overlay glass is still there. It's like super transparent glass window thats been washed with windex That guy is the user trying to click on those links below the overlay.
What you want to do is either remove the element from the DOM or set it to "display: none" after the transition.
The best solution that is cross browser I would use is to set display: none after the animation.
$(".overlay").animate({"opacity": "0"}, function(){
$(this).hide();
// OR REMOVE it
// $(this).remove();
});
Personally I like to wrap my modals in a container and give it a fixed postion and remove the container along with the modal contents on hide but thats me.
I also like jeffery's fancy css transition end method too, if you want to be fancy with css3 but the caveat is you'd probably have to detect which vendor prefix you have to listen to.
Here are the vendor prefixed transition ends:
var transitionEnd = {
'WebkitTransition' : 'webkitTransitionEnd'
, 'MozTransition' : 'transitionend'
, 'OTransition' : 'oTransitionEnd'
, 'msTransition' : 'transitionend'
, 'transition' : 'transitionend'
}
You'd have to write something to detect it which one is relevant to the user.
$(".overlay").on(transitionEnd, function() {
$(this).hide();
// OR REMOVE it
// $(this).remove();
}
Upvotes: 1
Reputation: 64164
I think that you CAN use z-index, and you don't need to look for work-arounds. The only thing that you probably need is to put the layout higher in the DOM tree. It's difficult to say without looking at your code, but if you could go to something like
<body>
<div id="everyting-else">
...
</div>
<div id="overlay"/>
</body>
and then give #everyting-else a z-index of 2 and #overlay a z-index of 1, that should work whatever the content of "everything-else", because they are in a different stacking context.
It doesn't matter if you use "Relative, Fixed and Absolute positioning" inside the div
Upvotes: 0
Reputation: 21601
jQuery's function animate accepts a callback function, which executes when the animation is complete. Example:
$('.overlay').animate({
opacity: 0
}, 300 /* animation duration in ms */, function () {
// This will execute when the animation is complete
$(this).css({
visibility: 'hidden'
});
});
Upvotes: 0
Reputation: 2328
Working only with opacity
put the element in a context that can't be positioned via z-index
because the element must be mixed with the other elements into the layout (W3C).
Further consideration is that elements with only opacity
or visibility
, doesn't come extracted from the layout flow so, even if not visible, they still occupy its position and size, and this will prevent every element underlying the one invisible to be reached (clicks are inhibited, buttons aren't clickable, and so on).
To solve your problem, you need to set display
to none
. In this way, the element will be invisible and no more occupy space into the layout flow.
Upvotes: 0
Reputation: 11936
You can listen for a transition end event to set visibility: hidden
after the opacity transition.
Upvotes: 0
Reputation: 6114
Use setTimeout
to start the animation after the overlay appears, and hide the overlay after the animation is finished
to show overlay:
// show the overlay (in whatever manner you like) BEFORE the animation starts
// opacity is 0
$('#overlay').show();
setTimeout(function() {
// fade in the opacity AFTER the overlay is there
$('#overlay').addClass('opaque');
}, 0);
to hide overlay:
// fade out the opacity BEFORE the overlay goes away
$('#overlay').removeClass('opaque');
setTimeout(function() {
// hide the overlay (in whatever manner you like) AFTER the animation is done
// opacity is 0
$('#overlay').hide();
}, 250);
Upvotes: 1