keyframe animation not playing after clicking link - html

I have a full screen drop down menu that goes up and down the screen when the user interacts with the menu button. I didn't like that the full screen menu animates when the page loads so I set the opacity of the menu to 0 so that you wouldn't see the animation when the page loads. I created an onclick event that sets the opacity to 1 when the user clicks on the menu. that solved the issue of seeing the animation when the user loads the index page. here's the code for how I did it:
HTML
<div class="menu">
<input type="checkbox" class="toggler" onclick="document.getElementById('overlay').style.opacity='1'">
<div class="icon">
<div></div>
</div>
<div class="overlay" id="overlay">
<nav>
<div id="nav-links"></div>
</nav>
</div>
</div>
CSS
#keyframes slideDown {
0% {
transform: translateY(-100%)
}
100% {
transform: translateY(0%)
}
}
#keyframes slideUp {
0% {
transform: translateY(0%)
}
100% {
transform: translateY(-100%);
}
}
.overlay {
position: fixed;
background: var(--taupe-color);
opacity: 0;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.menu .toggler:checked ~ .overlay {
animation: slideDown 2s forwards;
}
.menu .toggler:not(:checked) ~ .overlay {
animation: slideUp 2s forwards;
}
The only issue now is that when the user clicks on a link to navigate to another page from the menu, the menu no longer animates up. My guess is that on page load, the opacity over the overlay menu is set back to 0 so we can't see the animation actually happening on the other pages. My only idea to fix this is to duplicate the overlay class for the other pages and give it a different name but set the opacity to 1. I'm wondering if there is a better solution than the one I came up with. Ideally, the animation only happens when a link is clicked in the menu or when the menu button is toggled.
EDIT
is there a way to have the menu animate only when the user clicks the menu button or clicks one of the nav links in the menu?

I would suggest maybe adding a class to turn the opacity to 1 upon clicking?
I'm not sure if this is what you are looking for, but here is Codepen that I believe does what you're looking for:
#keyframes slideDown {
0% {
transform: translateY(-100%)
}
100% {
transform: translateY(0%)
}
}
#keyframes slideUp {
0% {
transform: translateY(0%)
}
100% {
transform: translateY(-100%);
}
}
.overlay {
position: fixed;
background: var(--taupe-color);
opacity: 0;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.active {
opacity:1;
}
.menu .toggler:checked ~ .overlay {
animation: slideDown 2s forwards;
}
.menu .toggler:not(:checked) ~ .overlay {
animation: slideUp 2s forwards;
}
<div class="menu">
<input type="checkbox" class="toggler" onclick="document.getElementById('overlay').classList.add('active')">
<div class="icon">
<div></div>
</div>
<div class="overlay" id="overlay">
<nav>
<div id="nav-links"></div>
TESTTTTTTTTTTTT
</nav>
</div>
</div>

Related

Why when i move my first div to the top, the others does not move too?

Imagine i have 3 div :
<div class="one animated">
I'm the first div
</div>
<div class="two">
second div
</div>
<div class="three">
Last one
</div>
I have a code to move the first to the top :
.animated {
animation: animation 2s;
animation-fill-mode: forwards;
}
#keyframes animation {
0% { top: 0; opacity: 1 }
100% { top: -300px; opacity: 0 }
}
I don't understand why the first div move to top, but not the others.
The first one disappear so i want to replace the blank by my others div ...
Something like that :
function test() {
document.getElementById("sample").classList.add("animated");
}
.one {
border: 1px solid red;
}
.animated {
animation: animation 2s;
animation-fill-mode: forwards;
}
#keyframes animation {
0% { top: 0; opacity: 1 }
100% { top: -300px; opacity: 0 }
}
<div class="one" id="sample">
I'm the first div
</div>
<div class="two">
second div
</div>
<div class="three">
Last one
</div>
<button onclick="test()">Test</button>
Use absolute:position; on Keyframes. This will make sure as soon as the div is hidden it automatically moves to the top.
Also you can add additional keyframes attributes to make if smooth.
function test() {
document.getElementById("sample").classList.add("animated");
}
.one {
border: 1px solid red;
}
.animated {
animation: animation 2s;
animation-fill-mode: forwards;
}
#keyframes animation {
0% {
top: 0;
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 0;
position: absolute;
}
}
<div class="one" id="sample">
I'm the first div
</div>
<div class="two">
second div
</div>
<div class="three">
Last one
</div>
<button onclick="test()">Test</button>
Add position: absolute; to .animated class in your css
function test() {
document.getElementById("sample").classList.add("animated");
}
.one {
border: 1px solid red;
}
.animated {
animation: animation 2s;
animation-fill-mode: forwards;
position: absolute; // Adding this will help
transition: all 2s linear;
}
#keyframes animation {
0% { top: 0; opacity: 1; }
50% {top: -1; opacity: 0.5;}
100% { top: -300px; opacity: 0; }
}
<div class="one" id="sample">
I'm the first div
</div>
<div class="two">
second div
</div>
<div class="three">
Last one
</div>
<button onclick="test()">Test</button>

Reveal animation

I've coded a reveal image animation and have stumbled across an issue when in the creation.
.container{
overflow: hidden;
}
.image {
background-image: url('https://images.wallpaperscraft.com/image/honda_civic_type_r_honda_type_r_honda_129270_3840x2160.jpg');
background-size: cover;
width: 400px;
height: 400px;
animation: 1s ease-out 0s 1 slideInFromLeft;
overflow: hidden;
}
#keyframes slideInFromLeft {
0% {
transform: translatex(-100%);
}
100% {
transform: translatex(0%);
}
}
<div class="container">
<div class="image">
</div>
</div>
The animation seems to be working fine except for it not sliding smoothly. It seems to have a jitter of some sort.
How can I make the animation slide more smoothly?
You could wait for the page/image to load and then trigger the animation to happen. The code below is a crude way of applying the animation class once with js.
window.onload = function() {
var element = document.getElementById('img1');
element.classList.add("show");
element.classList.add("animate");
}
.container{
overflow: hidden;
}
.image {
background-image: url('https://images.wallpaperscraft.com/image/honda_civic_type_r_honda_type_r_honda_129270_3840x2160.jpg');
background-size: cover;
width: 400px;
height: 400px;
opacity: 0;
overflow: hidden;
}
#img1.animate{
animation: 1s ease-out 0s 1 slideInFromLeft;
}
.show {
opacity:1;
}
#keyframes slideInFromLeft {
0% {
transform: translatex(-100%);
}
100% {
transform: translatex(0%);
}
}
<div class="container">
<div id="img1" class="image" >
</div>
</div>
I'd use an <img> element for this and remove it when it loaded, after I pass it's src to the backgroundImage of the parent, as it was already loaded:
let imageDivs = document.querySelectorAll('.image img');
for (var i = 0; i < imageDivs.length; i++) {
imageDivs[i].addEventListener('load', imageLoaded)
}
function imageLoaded(e) {
let div = e.target.closest('div');
div.style.backgroundImage = 'url('+this.src+')';
div.classList.add('loaded');
div.removeChild(div.querySelector('img'));
}
.container{
overflow: hidden;
}
.image {
background-size: cover;
width: 400px;
height: 400px;
transform: translatex(-100%);
overflow: hidden;
}
.image.loaded{
animation: slideInFromLeft 1s cubic-bezier(.5,0,.3,1) forwards;
}
.image img {
height: 0;
}
#keyframes slideInFromLeft {
0% {
transform: translatex(-100%);
}
100% {
transform: translatex(0);
}
}
<div class="container">
<div class="image">
<img src="https://images.wallpaperscraft.com/image/honda_civic_type_r_honda_type_r_honda_129270_3840x2160.jpg">
</div>
</div>
This triggers the animation of a particular <div> (if you have more than one) as soon as that image loaded, rather than triggering all of them after all images in the page have loaded (if you use window.load).
However, this doesn't mean you should load huge resources in your page. Optimizing your images and loading them the right size for current device is a very important step in website optimization. You should use srcset for this purpose.

CSS cannot fade out and then hide

I'm trying to make a css class and animation which will make a div (and it's contents) fade out or move, but ultimately, the div to have display:none and visibility:hidden
My effort is not working! I can get it to either animate, or to appear to be "removed"
This crude example demonstrates the issue
.hide {
animation-name:fadeOut;
animation-duration:1s;
/*visibility: hidden;
display: none;*/
}
#keyframes fadeOut {
from {
opacity: 1;
margin-left: 0%;
}
to {
opacity: 0;
margin-left: -100%;
}
}
<div class="hide">
<div style="padding:20px;background:orange;">
<div style="padding:5px;background:azure;">
My content
</div>
</div>
</div>
I also tried updating the CSS to
to {
opacity: 0;
margin-left: -100%;
visibility: hidden;
display: none;
}
And also on https://jsfiddle.net/
As you can see, in the CSS I have commented out the hiding part (although the opacity makes it hidden).
Is it possible to apply the fadeout and then update the visibility and display without using JavaScript?
Add animation-fill-mode: forwards; so that the element you're animating stays on the last (key)frame, and it doesn't start over or refresh to the beginning.
Learn more about animation-fill-mode.
Another way to write this animation:
.hide {
animation: fadeOut 1s forwards;
}
.hide {
animation-name:fadeOut;
animation-duration:1s;
animation-fill-mode: forwards; /* added */
/*visibility: hidden;
display: none;*/
}
#keyframes fadeOut {
from {
opacity: 1;
margin-left: 0%;
}
to {
opacity: 0;
margin-left: -100%;
height: 0; /* added */
}
}
<div class="hide">
<div style="padding:20px;background:orange;">
<div style="padding:5px;background:azure;">
My content
</div>
</div>
</div>
<div>
Other content
</div>
Scrollbar fix
A possible solution to the scrollbar issue is to bring the hidden element back to the initial position with margin: 0; (or whatever the initial margin was):
#keyframes fadeOut {
0% {
opacity: 1;
margin-left: 0%;
}
99% {
opacity: 0;
margin-left: -100%;
height: 0;
}
100% {
opacity: 0;
margin-left: 0; /* added */
height: 0;
}
}

Use transition with hover without it reverting to previous state

I have a div 'box' which rotates 90 degrees when the user hovers it.
When the user moves the mouse away the box counter rotates back to its original position.
I would like to prevent this.
I.E: When the user hover over the box it rotates and stays that way, even when he removes the mouse from the box.
Please look at for the basic setup:
.box {
height: 150px;
width: 150px;
background-color: blue;
transition: 1s all;
}
.box:hover {
transform: rotate(90deg);
}
<div class="box">
Hover me!
</div>
JSFIDDLE
What should I change in order to make it act as I want?
One way you can achieve this using animation
Like this
.box {
height: 150px;
width: 150px;
background-color: grey;
transition: 1s all;
animation: rotate .4s forwards paused;
}
.box:hover {
animation-play-state: running;
}
#keyframes rotate {
from {
transform: rotate(0);
}
to {
transform: rotate(90deg);
}
}
<div class="box">
Hover me!
</div>
Or
You can use js. Like this
$(document).ready(function() {
$(".box").mouseover(function(e) {
$(this).css("transform","rotate(90deg)");
});
});
.box {
height: 150px;
width: 150px;
background-color: grey;
transition: 1s all;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
Hover me!
</div>

overlaying divs with onclick in slideshow -> onclick doesnt change

what I mean in the title is, no matter which container is on top (is visible) in the fade-style animation, the href in the "onclick" is always the same.
here is the html
<div id="teaserslider">
<ul>
<li>
<section id="container_1">
<div class="head gradient-top loading" onclick="document.location.href='container1_detail.html'">
<div>
<!-- Content -->
</div>
</div>
</section>
</li>
<li class="animation">
<section id="container_2">
<div class="head gradient-top loading" onclick="document.location.href='container2_detail.html'">
<div>
<!-- Content -->
</div>
</div>
</section>
</li>
</ul>
</div>
here is the css
#teaserslider{
height: 100px;
margin-bottom: 6px;
}
#teaserslider li {
position: absolute;
list-style: none;
-webkit-transition: opacity 1s ease-in-out;
}
#-webkit-keyframes fadeout{
0% {
opacity:1;
}
45% {
opacity:1;
}
55% {
opacity:0;
}
100% {
opacity:0;
}
}
#teaserslider li.animation {
-webkit-animation-name: fadeout;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-iteration-count: infinite;
-webkit-animation-duration: 5s;
-webkit-animation-direction: alternate;
-webkit-transform: translateZ(0);//hardware acceleration
}
you may have noticed, I only use the webkit engine because this code runs inside a Phonegap Application for iOS.
No matter which container is showed currently, when I click the container I always get to "container2_detail.html". Anyone know how to solve this? thanks.
May be you have to define z-index to it. Write like this:
#-webkit-keyframes fadeout{
0% {
opacity:1;
z-index:1;
}
45% {
opacity:1;
z-index:1;
}
55% {
opacity:0;
z-index:-1;
}
100% {
opacity:0;
z-index:-1;
}
}
I tried this and it seems to work
#-webkit-keyframes fadeout{
0% {
opacity:1;
z-index: 1;
display: block;
}
45% {
z-index: 1;
display: block;
opacity:1;
}
55% {
z-index: -1;
display: none;
opacity:0;
}
100% {
z-index: -1;
display: none;
opacity:0;
}
}