My page has an overlapped div, which it will be hided after 5 seconds. However, I realize that the buttons behind the div cannot be pressed due to the div is still there after 5 seconds.
To remove the div, I have tried with display:none but it does not work.
Here are my css:
.ox-messages {
-webkit-animation: seconds 1.0s forwards;
-webkit-animation-iteration-count: 1;
-webkit-animation-delay: 5s;
animation: seconds 1.0s forwards;
animation-iteration-count: 1;
animation-delay: 5s;
position: relative;
}
#-webkit-keyframes seconds {
0% {
opacity: 1;
}
100% {
opacity: 0;
left: -9999px;
//display: none;
}
}
#keyframes seconds {
0% {
opacity: 1;
}
100% {
opacity: 0;
left: -9999px;
//display: none;
}
}
The problem looks like this:
The alert messages (in green) are overlapping the buttons (the note-plus icon).
Please help and thanks.
EDIT: I change position:relative to position:absolute, which it does not block the buttons but the messages stack together.
Please feel free to copy and paste this code in any html editor (or press code snippet below) and you will see that the JavaScript function will indeed remove the div. In this example, no text will be displayed in the website, because we removed the div in which the text is contained by using JavaScript:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<div id="div_we_want_to_remove">
<!-- We will not see the following text on the webpage if we execute the the JavaScript code that I included -->
<p1> It is possible to get rid of this text using javascript</p1>
</div>
<script>
//this is the JavaScript code that's needed to get rid of that div
function remove_div() {
var elem = document.getElementById('div_we_want_to_remove');
elem.parentNode.removeChild(elem);
return false;
}
//remove_div literally will remove the div
remove_div();
</script>
</html>
you can set pointer-events: none; on that div when you hide it, and it won't get in the way anymore
Set the visibility: hidden then the element will be hidden from the document. Making the button behind it clickable.
.ox-messages {
-webkit-animation: seconds 1.0s forwards;
-webkit-animation-iteration-count: 1;
-webkit-animation-delay: 5s;
animation: seconds 1.0s forwards;
animation-iteration-count: 1;
animation-delay: 5s;
position: relative;
height: 200px;
width: 500px;
background: red;
position: absolute;
top: 0;
}
#-webkit-keyframes seconds {
0% {
opacity: 1;
visibility: visible;
}
100% {
opacity: 0;
visibility: hidden;
}
}
#keyframes seconds {
0% {
opacity: 1;
visibility: visible;
}
100% {
opacity: 0;
visibility: hidden;
}
}
<button>TEST</button>
<div class="ox-messages"></div>
Related
I'm trying to create a visual transition between content changes in a toy SPA I'm writing. To that end, I define a simple class for animating the opacity of an element.
.fade {
transition: opacity 1.5s;
}
In my render function, I now change the opacity of my outlet div after content changes like so:
function render(content) {
var outlet = document.getElementById("outlet");
outlet.classList.remove("fade");
outlet.style.opacity = 0;
outlet.innerHTML = content;
outlet.classList.add("fade");
outlet.style.opacity = 1;
}
Unfortunately, the animation never fires. When I delay changing the opacity to 1 via setTimeout for 10ms, say, it works sometimes if I don't change the content again while the animation is still running, indicating a timing issue/race condition.
I used a similar approach in the past to fade out messages, but there I intentionally delayed changing the opacity by a few seconds so users could read the message before it starts fading out.
Pure CSS animation fadeIn
li {
position: absolute;
top: 50%;
left: 50%;
margin-top: -75px;
}
.logo {
width: 300px;
height: 150px;
background: red;
margin-left: -150px;
z-index: 30;
-webkit-animation: fade-in-slogan 4s .2s ease-in forwards;
-moz-animation: fade-in-slogan 4s .2s ease-in forwards;
animation: fade-in-slogan 4s .2s ease-in forwards;
}
.menu {
width: 600px;
height: 150px;
background: blue;
margin-left: -300px;
opacity: 0;
-webkit-animation: fade-in-menu 3s 4s ease-out forwards;
-moz-animation: fade-in-menu 3s 4s ease-out forwards;
animation: fade-in-menu 3s 4s ease-out forwards;
}
#-webkit-keyframes fade-in-slogan {
0% { opacity: 0; }
30% { opacity: 1; }
50% { opacity: 1; }
70% { opacity: 1; }
100% { opacity: 0; }
}
#-webkit-keyframes fade-in-menu {
0% { display: block; opacity: 0; }
30% { display: block; opacity: .3; }
60% { display: block; opacity: .6; }
80% { display: block; opacity: .8; }
100% { display: block; opacity: 1; }
}
<ul class"main">
<li class="logo"></li>
<li class="menu"></li>
</ul>
Try this, I hope this will solve the issue
.fade{
animation-name: example;
animation-duration: 4s;}
#keyframes example {
from {opacity:1}
to {opacity:0;}
}
div{
width:200px;
height:200px;
background:#000;
}
<html>
<head>
</head>
<body>
<div class="fade"></div>
</body>
</html>
I've solved it now inspired by Muhammad's answer. I defined the fade class as follows:
.fade {
animation-name: fadein;
animation-duration: 1.25s;
#keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
Then in the render function, I do
function render(content) {
outlet.classList.remove("fade");
outlet.innerHTML = "";
setTimeout(() => {
outlet.classList.add("fade");
outlet.appendChild(content);
}, 100);
}
Even though this adds an additional delay before the new content actually starts to fade in, it seems the most elegant and concise solution to me.
I have a div element, which has an animation to play when starting the page. I want to make it have another animation to play when I'm hovering over it. It works just fine, but when I get my mouse out of the div element, it plays the starting animation again (fades in from out of the screen).
#keyframes div{
0%{
opacity: 0;
}
}
#keyframes divHover{
50%{
top: 200px;
}
100%{
top: 0px;
}
}
#div{
opacity: 1;
animation: div 1s;
position: absolute;
left: 0px;
top: 0px;
}
#div:hover{
animation: divHover 1s linear 0s infinite;
}
<div id="div"> abc </div>
Expected:
Div starts invisible and fades in. When hovering div, it goes up and down, and keeps doing it while hovering. After stopping the hover, div stops the animation and keeps its full opacity
Actual:
After stopping the hover, div stops the animation but returns to 0 opacity, then takes one second to display the starting animation again.
https://jsfiddle.net/odq125Lu/6/
The issue is due to the fact that you are overriding the first opacity animation with the up & down one then when you unhover you active the first one again.
You can use multiple animations and consider animation-play-state to activate the second one:
#keyframes div {
0% {
opacity: 0;
}
}
#keyframes divHover {
50% {
top: 200px;
}
100% {
top: 0px;
}
}
#div {
opacity: 1;
animation:
div 1s,
divHover 1s linear 0s infinite;
animation-play-state:running,paused;
position: absolute;
left: 0px;
top: 0px;
background:red;
padding:20px;
}
#div:hover {
animation-play-state:running,running;
}
<div id="div"> abc </div>
I'm no expert, but it may have something to do with the fact that you haven't set a 100% value for the animation "divHover"?
#keyframes div{
0%{
opacity: 0;
}
100% {
opacity: 1;
}
}
I'm currently attempting to get the background image of #InnerImage to fade out. Here is the code for #InnerImage:
<div id="InnerImage" style="background-image:url('imgurl.com'););background-repeat:no-repeat;background-position:50% 0%;">
Here's the code that I'm using:
#OuterImage #InnerImage {
-webkit-animation: 3s ease 0s normal forwards 1 fadein;
animation: 3s ease 0s normal forwards 1 fadein;
}
#keyframes fadein{
0% { opacity:0; }
66% { opacity:0; }
100% { opacity:1; }
}
#-webkit-keyframes fadein{
0% { opacity:0; }
66% { opacity:0; }
100% { opacity:1; }
}
I'm running into an issue where the code is making every other child(?) div within #InnerImage fade out as well, but I only want the background-image to fade.
I have two questions:
1) I did read that it was not possible for background-image opacity changes that the above code is performing. Is there a work around for this?
2) How do I go about making it so that after the image has been faded in, it fades back out in an infinite loop?
[EDIT]
#OuterImage #InnerImage{
-webkit-animation: 3s ease 0s normal forwards 1 fadein;
animation: 3s ease 0s normal forwards 1 fadein;
animation-iteration-count: infinite;
}
#keyframes fadein{
0% { opacity:0; }
66% { opacity:0; }
100% { opacity:1; }
}
#-webkit-keyframes fadein{
0% { opacity:0; }
66% { opacity:0; }
100% { opacity:1; }
}
#OuterImage #InnerImage::before {
background: url('imgurl.com') no-repeat center left;
content: "";
position: absolute;
/* the following makes the pseudo element stretch to all sides of host element */
top: 0;
right: 0;
bottom: 0;
left: 0;
transition: opacity 1s ease 2s;
z-index: 1;
}
#OuterImage #InnerImage {
position: relative;}
#OuterImage #InnerImage * {
position: relative;
z-index: 2;
}
#OuterImage #InnerImage
Answer to your first question:
Put the background-image on a pseudo element ::before instead:
#InnerImage::before {
background: url('imgurl.com') no-repeat center left;
content: "";
position: absolute;
/* the following makes the pseudo element stretch to all sides of host element */
top: 0; right: 0; bottom: 0; left: 0;
z-index: 1;
}
This requires to set position: relative; on #InnerImage:
#InnerImage {
position: relative;
}
and you need to make sure all other child elements are above the pseudo element using z-index (which only applies the way you need if you position those elements):
#InnerImage * {
position: relative;
z-index: 2;
}
Notice: #OuterImage #InnerImage can be safely shortened to #InnerImage since there may be only one element on a page with any given id value anyway. Also I'd advise not to use id selectors in CSS unless you know for sure why you are doing it.
Regarding your animation, it seems like you want it to start only after two seconds have gone by. This can be achieve using a transition like this:
transition: opacity 1s ease 2s;
where 1s is transition-duration and 2s is transition-delay.
https://developer.mozilla.org/en/docs/Web/CSS/transition
Example:
#InnerImage::before {
background: url(http://lorempixel.com/300/200) no-repeat center left;
content: "";
position: absolute;
/* the following makes the pseudo element stretch to all sides of host element */
top: 0;
right: 0;
bottom: 0;
left: 0;
transition: opacity 1s ease 2s;
z-index: 1;
}
#InnerImage {
position: relative;
width: 300px;
height: 200px;
}
#InnerImage * {
position: relative;
z-index: 2;
}
#InnerImage:hover::before {
opacity: 0.25;
}
<div id="InnerImage">
<h2>Hey!</h2>
<button>noop</button>
</div>
If you want a permanently on-going fadein-fadeout, you'll have to go with an animation instead of a transition.
#InnerImage::before {
background: url(http://lorempixel.com/300/200) no-repeat center left;
content: "";
position: absolute;
/* the following makes the pseudo element stretch to all sides of host element */
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
animation: 3s ease 0s normal forwards 1 fadein;
animation-iteration-count: infinite;
}
#InnerImage {
position: relative;
width: 300px;
height: 200px;
}
#InnerImage * {
position: relative;
z-index: 2;
}
#keyframes fadein{
0% { opacity:0; }
50% { opacity: 1; }
100% { opacity:0; }
}
<div id="InnerImage">
<h2>Hey!</h2>
<button>noop</button>
</div>
To animate in an infinite loop you can use the animation-iteration-count property and set the value to infinite.
#OuterImage #InnerImage {
-webkit-animation: 3s ease 0s normal forwards 1 fadein;
animation: 3s ease 0s normal forwards 1 fadein;
animation-iteration-count: infinite;
}
Changing the opacity of an element will effect all child elements there is no way around that.
A work around you may consider is to create a element inside #InnerImage that solely handles the background. You set the background div to be position absolute, with a z-index of 0, then animate only this div. That way the other elements will not change in opacity as the animation changes.
#InnerImage {
height:200px;
position:relative;
}
.bg {
position: absolute;
height: 100%;
width: 100%;
background: red;
z-index: 0;
animation-name: fadein;
animation-duration: 6s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
}
.content {
position: relative;
}
#keyframes fadein{
0% { opacity:0; }
50% { opacity:1; }
100% { opacity:0; }
}
<div id="InnerImage">
<div class="bg"></div>
<div class="content">other content</div>
</div>
Note in the example the text content does not fade while the background does
I am trying to implement some animation onLoad without Javascript. JS is easy, CSS is ... not.
I have a div which should be on display: none; and should be display: block; after 3 secondes. Lots of resources told me animate does not work with display, but should with visibility (which I use often in my transition).
Right know I have this terrible javascript function :
<script type="text/javascript">
$(document).ready(function(){
$(".js_only").hide();
setTimeout(function () {
$(".js_only").show();
}, 3000);
});
</script>
I tried some animation in CSS but no result ... nothing seems to work.
I have few animation in my page, but just struggling with the display: none; on animation.
#-moz-keyframes showEffect {
0% { display: none; visibility: hidden; }
100% { display: block; visibility: block; }
}
#-webkit-keyframes showEffect {
0% { display: none; visibility: hidden; }
100% { display: block; visibility: block; }
}
#keyframes showEffect {
0% { display: none; visibility: hidden; }
100% { display: block; visibility: block; }
}
.css_only {
-moz-animation-name: showEffect;
-moz-animation-iteration-count: 1;
-moz-animation-timing-function: ease-in;
-moz-animation-duration: 2.3s;
-webkit-animation-name: showEffect;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in;
-webkit-animation-duration: 2.3s;
animation-name: showEffect;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 2.3s;
}
It is important as hidden, this element does not take space at all. I created a JSFiddle to make quite tests.
My main concerne is SEO ... I don't think the JS option is really nice for that which is why I would like a pure CSS alternative. Also interested to test those animations and see where are those limits (Am I seeing one right now ?). Kinda having fun on such challenge.
Thanks for reading, hope someone has an answer.
You are correct in thinking that display is not animatable. It won't work, and you shouldn't bother including it in keyframe animations.
visibility is technically animatable, but in a round about way. You need to hold the property for as long as needed, then snap to the new value. visibility doesn't tween between keyframes, it just steps harshly.
.ele {
width: 60px;
height: 60px;
background-color: #ff6699;
animation: 1s fadeIn;
animation-fill-mode: forwards;
visibility: hidden;
}
.ele:hover {
background-color: #123;
}
#keyframes fadeIn {
99% {
visibility: hidden;
}
100% {
visibility: visible;
}
}
<div class="ele"></div>
If you want to fade, you use opacity. If you include a delay, you'll need visibility as well, to stop the user from interacting with the element while it's not visible.
.ele {
width: 60px;
height: 60px;
background-color: #ff6699;
animation: 1s fadeIn;
animation-fill-mode: forwards;
visibility: hidden;
}
.ele:hover {
background-color: #123;
}
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
visibility: visible;
opacity: 1;
}
}
<div class="ele"></div>
Both examples use animation-fill-mode, which can hold an element's visual state after an animation ends.
Use animation-delay:
div {
width: 100px;
height: 100px;
background: red;
opacity: 0;
animation: fadeIn 3s;
animation-delay: 5s;
animation-fill-mode: forwards;
}
#keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
Fiddle
You can play with delay prop of animation, just set visibility:visible after a delay, demo:
#keyframes delayedShow {
to {
visibility: visible;
}
}
.delayedShow{
visibility: hidden;
animation: 0s linear 2.3s forwards delayedShow ;
}
So, Where are you?
<div class="delayedShow">
Hey, I'm here!
</div>
Unfortunately you can't animate the display property. For a full list of what you can animate, try this CSS animation list by w3 Schools.
If you want to retain it's visual position on the page, you should try animating either it's height (which will still affect the position of other elements), or opacity (how transparent it is). You could even try animating the z-index, which is the position on the z axis (depth), by putting an element over the top of it, and then rearranging what's on top. However, I'd suggest using opacity, as it retains the vertical space where the element is.
I've updated the fiddle to show an example.
Good luck!
you can't animate every property,
here's a reference to which are the animatable properties
visibility is animatable while display isn't...
in your case you could also animate opacity or height depending of the kind of effect you want to render_
fiddle with opacity animation
I have a one pager that shows one page at a time and that uses animation when transitioning from one page to the next. It works like this:
The user clicks on a button
An ajax call is done and while waiting for the response the page fades out (opacity: 0)
If the server does not respond within 500 msec after the fade out finishes a spinner fades in and stays there until the ajax call finishes
When receiving the response the spinner is faded out and the new page fades in.
I currently use a CSS 3 transition animation on the opacity of the page. This issue is however that during the time the spinner is visible the user can still interact with the (invisible) form of the page that just faded out (it's not gone, it's just invisible using opacity).
So I would like to have a CSS only solution that sets the page to visibility: hidden at the end of the transition (I cannot use display: none). What would be the way to go here?
Based on the answer of #Rev I created a proof of concept. It works nicely (see fiddle).
When you add the class 'fadeOut' to the div it'll fade out and end with a visibility: hidden state. Remove the class and it fades in again. You can tell that it is really hidden by hovering your mouse over it: if hidden it will no longer give the "text selection" mouse pointer.
HTML
<div class="page">
Lorem ipsum etc etc etc.
</div>
CSS
.page {
-moz-animation-name: fadeIn;
-webkit-animation-name: fadeIn;
-ms-animation-name: fadeIn;
animation-name: fadeIn;
-moz-animation-duration: 1s;
-webkit-animation-duration: 1s;
-ms-animation-duration: 1s;
animation-duration: 1s;
-moz-animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out;
-ms-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
-moz-animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
-ms-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
.page.fadeOut {
-moz-animation-name: fadeOut;
-webkit-animation-name: fadeOut;
-ms-animation-name: fadeOut;
animation-name: fadeOut;
}
#-moz-keyframes fadeIn { 0% { opacity: 0; visibility: hidden; } 100% { opacity: 1; visibility: visible; }}
#-webkit-keyframes fadeIn { 0% { opacity: 0; visibility: hidden; } 100% { opacity: 1; visibility: visible; }}
#-ms-keyframes fadeIn { 0% { opacity: 0; visibility: hidden; } 100% { opacity: 1; visibility: visible; }}
#-keyframes fadeIn { 0% { opacity: 0; visibility: hidden; } 100% { opacity: 1; visibility: visible; }}
#-moz-keyframes fadeOut { 0% { opacity: 1; visibility: visible; } 100% { opacity: 0; visibility: hidden; }}
#-webkit-keyframes fadeOut { 0% { opacity: 1; visibility: visible; } 100% { opacity: 0; visibility: hidden; }}
#-ms-keyframes fadeOut { 0% { opacity: 1; visibility: visible; } 100% { opacity: 0; visibility: hidden; }}
#-keyframes fadeOut { 0% { opacity: 1; visibility: visible; } 100% { opacity: 0; visibility: hidden; }}
Some additional remarks:
If you have child elements in the .page element that have explicitly visibility: visible set on them then they will react to interaction via mouse. This is because hey are not hidden just invisible due to the opacity: 0. The twitter bootstrap collapse plugin does this for instance. You can solve this by setting their visibility to inherit instead of visible. This will cause them to only be visible if their parent is. For instance the collapse plugin can be made to behave using this additional css:
.page .collapse {
visibility: inherit;
}
This does not work in IE 9 and below.
You need the browser prefixes as seen in my code to make this work. I tested this without the prefixes and both the latest chrome (42) and firefox (37) did not work without them. This is ugly but can be made easier by using something like SASS with Compass. Here's the same code using that approach:
SASS with Compass
.page {
#include animation(fadeIn 1s ease-in-out forwards);
}
.page.fadeOut {
#include animation-name(fadeOut);
}
#include keyframes(fadeIn) {
0% { opacity: 0; visibility: hidden; }
100% { opacity: 1; visibility: visible; }
}
#include keyframes(fadeOut) {
0% { opacity: 1; visibility: visible; }
100% { opacity: 0; visibility: hidden; }
}
Not completely JS-only, but when you start the fade animation, also add a class to the form container with the following CSS:
.disableMouse * {
pointer-events: none;
}
This will disable clicks (but it won't disable scrolling). Works in all current browsers, but IE support was only added in version 11. So this may not be the best option for you if you need to support IE10 and earlier.
Pretty sure I can't be done with CSS alone. You could look in to the JavaScript's transitionend.
You could look in to CSS animations rather than transitions as well. I know you can't transition visibility: hidden; but you might be able to set up an animation key frame at 100% to do this.
If your only intent is to disable interaction, you could use pointer-events: none (IE11+) on your page, or have a floating blocker over the top, like;
.page.loading {
position: relative;
}
.page.loading:after {
content: ' ';
display: block;
position: relative;
background: white;
top: 0;
right: 0;
bottom: 0;
left: 0;
}