Final item will be background-image, this test is on background-color.
https://jsfiddle.net/broj3064/17/ when you scroll down, red block fades in, but if you scroll up, it doesn't fade out, it just disappears.
HTML
<header>
<nav>
<ul>
<li class="up"></li>
</ul>
</nav>
</header>
<div class="content">
</div>
CSS
header {
display: block;
width: 100%;
position: fixed;
}
nav ul li {
list-style: none;
display: block;
background-color: red;
width: 50px;
height: 50px;
}
nav ul li.up {
}
nav ul li.down {
}
.content {
min-height: 1000px;
}
/* animation */
nav ul li.down {
-webkit-animation: bummer 0.5s;
animation: bummer 0.5s;
-webkit-transform: scale(0,0);
transform: scale(0,0);
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
#-webkit-keyframes bummer {
100% {
-webkit-transform: scale(1);
}
}
#keyframes bummer{
100% {
transform: scale(1);
}
}
nav ul li.up {
-webkit-animation: bummer2 0.5s;
animation: bummer2 0.5s;
-webkit-transform: scale(1,0);
transform: scale(1,0);
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
#-webkit-keyframes bummer2 {
100% {
-webkit-transform: scale(0);
}
}
#keyframes bummer2{
100% {
transform: scale(0);
}
}
jQuery
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 50) {
$("li").addClass("down").removeClass("up");
}
else {
$("li").removeClass("down").addClass("up");
}
});
Is this what you need?
$(window).scroll(function() {
var scroll = $(window).scrollTop();
$("li").toggleClass('show',(scroll >= 50)); /* toggleClass add or remove a class in a div if you pass a boolean to it, in this case, when scroll is greater than 50 wich its true adds the show class to the selector, in this case a $('li'), otherwise it remove the class */
});
header {
display: block;
width: 100%;
position: fixed;
}
nav ul li {
list-style: none;
display: block;
background-color: red;
width: 50px;
height: 50px;
transition:all 400ms; /* This line create an animated transition if any property is overwritten */
transform:scale(0);
}
nav ul li.show {
/*Due to css specificity, adding a second class to an item, it overwrite its value, triggering the transition property to animate between old and new value*/
transform:scale(1);
}
.content {
min-height: 1000px;
}
/* animation */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<nav>
<ul>
<li></li>
</ul>
</nav>
</header>
<div class="content">
</div>
if it is, hope it helps
Related
Good evening, I'm a beginner front-end developer who is trying to implement sketches of Pinterest for training.
I've found this gif for the signup/login page but I have a major issue for implementing animation, I don't have any idea for reversing the animation when the user clicks on the signup button can anybody tell me how can I reverse an animation?
function animation() {
var element = document.getElementById("containerForm")
element.classList.add("slide")
}
.containerForm {
width:50px;height:50px;background-color:red;
}
.slide {
animation: slide 2s ease-in-out;
position: relative;
animation-fill-mode: forwards;
}
#keyframes slide {
0% {
transform: translateX(0);
}
100% {
transform: translateX(100%);
overflow: hidden;
visibility: visible;
}
}
<div class="containerForm" id="containerForm">
<form></form>
</div>
<button onclick="animation()">click</button>
but as I've said I don't have an idea for the second step
Link of gif
you can add another css class and make use of the animation-direction property.
ie
.slide-back{
animation: slide 2s ease-in-out;
position: relative;
animation-direction: reverse;
}
function animation() {
var element = document.getElementById("containerForm")
element.classList.add("slide")
}
function reverse() {
var element = document.getElementById("containerForm")
element.classList.remove("slide")
}
.containerForm {
width:50px;
height:50px;
background-color:red;
transform: translateX(0);
transition: transform 2s;
}
.slide {
transform: translateX(100%);
}
<div class="containerForm" id="containerForm">
<form></form>
</div>
<button onclick="animation()">click</button>
<button onclick="reverse()">click</button>
transition works too:
example:
*{margin:0;}
#tst {
display: grid;
grid-template-columns: repeat(2, 1fr);
min-height: 100vh;
background: #555;
}
label {
margin: auto;
appearance: button;
cursor: pointer;
min-width: 6em;
text-align: center;
}
#a,
#b {/*hides radios */
position: absolute;
right: 100vw;
}
[for="a"],
#c {
grid-row: 1;
grid-column: 1;
}
#c {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto 1fr;
background: white;
border: solid;
transition: 0.5s;
font-size:2vw;
}
#a:checked~#c {
transform: translatex(0)
}
#b:checked~#c {
transform: translatex(100%)
}
h1 {
margin: auto;
}
#c p[class] {
margin: auto;
grid-column: 1;
grid-row: 2;
transition: 0.25s;
background: inherit;
color: #164fb7;
font-size: 3vw;
}
#c p.b {
opacity: 0;
color: tomato;
}
#b:checked~#c p.b {
opacity: 1
}
/* there were no js nor animation nor absolute positionning ;) */
<div id="tst">
<input id="a" type=radio name=toggle>
<input id="b" type=radio name=toggle>
<label for="a">Left</label>
<label for="b">Right</label>
<div id="c">
<h1>here or there ?</h1>
<p class="a">Standing on the left</p>
<p class="b">Standing on the right</p>
</div>
</div>
Instead of adding a class I suggest using the animation-play-state property and adding event listeners:
one click listener to the button
one animationiteration to the div
simply change the play state from paused to running
Let me show you what I mean:
const element = document.getElementById("containerForm");
const btn = document.querySelector("button");
function animation() {
element.style.animationPlayState = "running";
}
function stopAnimation() {
element.style.animationPlayState = "paused";
}
btn.addEventListener("click", animation);
element.addEventListener("animationiteration", stopAnimation);
.containerForm {
width: 50px;
height: 50px;
background-color: red;
animation: slide 2s ease-in-out infinite alternate paused;
}
#keyframes slide {
0% {
transform: translateX(0);
}
100% {
transform: translateX(100%);
}
<div class="containerForm" id="containerForm">
<form></form>
</div>
<button>click</button>
I am trying to add animation in grouped progress bar that will load each progress bar from 0 to its value. e.g in my sample code below I want to first load red progress bar then load the green progress bar. How can I do that?
Please check the code in this jsfiddle.
html:
<div class="progress-bar-outer">
<div class="progress-bar-inner">
</div>
<div class="progress-bar-inner2">
</div>
</div>
css:
.progress-bar-outer {
width: 300px;
height: 40px;
flex: auto;
display: flex;
flex-direction: row;
border-radius: 0.5em;
overflow: hidden;
background-color: gray;
}
.progress-bar-inner {
/* You can change the `width` to change the amount of progress. */
width: 75%;
height: 100%;
background-color: red;
}
.progress-bar-inner2 {
/* You can change the `width` to change the amount of progress. */
width: 50%;
height: 100%;
background-color: green;
}
.progress-bar-outer div {
animation:loadbar 3s;
-webkit-animation:loadbar 3s;
}
#keyframes loadbar {
0% {width: 0%;left:0;right:0}
}
I would transition transform instead for better performance. Use translateX(-100%) with opacity: 0 to move them to their default, hidden position, then animate to translateX(0); opacity: 1; to put them in place. And just add an animation-delay to the green bar that matches the animation-duration
I made the bars semi-opaque to show when the animations fire.
.progress-bar-outer {
width: 300px;
height: 40px;
border-radius: 0.5em;
overflow: hidden;
background-color: gray;
display: flex;
}
.progress-bar-inner {
/* You can change the `width` to change the amount of progress. */
width: 75%;
background-color: red;
}
.progress-bar-inner2 {
/* You can change the `width` to change the amount of progress. */
width: 100%;
background-color: green;
}
.progress-bar-outer div {
transform: translateX(-100%);
animation: loadbar 3s forwards;
-webkit-animation: loadbar 3s forwards;
opacity: 0;
}
.progress-bar-outer .progress-bar-inner2 {
animation-delay: 3s;
}
#keyframes loadbar {
0% {
opacity: 1;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress -->
<div class="progress-bar-outer">
<div class="progress-bar-inner">
</div>
<div class="progress-bar-inner2">
</div>
</div>
Modified Michael Coker's answer to better reflect my interpretation of what you're asking for.
.progress-bar-outer {
width: 300px;
height: 40px;
border-radius: 0.5em;
overflow: hidden;
background-color: gray;
position: relative;
}
.progress-bar-inner {
/* You can change the `width` to change the amount of progress. */
width: 100%;
background-color: red;
z-index: 1;
}
.progress-bar-inner2 {
/* You can change the `width` to change the amount of progress. */
width: 100%;
background-color: green;
z-index: 2;
}
.progress-bar-outer div {
position: absolute;
top: 0; bottom: 0;
transform: translateX(-100%);
animation: loadbar 3s linear;
-webkit-animation: loadbar 3s linear;
opacity: 1;
}
.progress-bar-outer .progress-bar-inner2 {
animation-delay: 3s;
}
#keyframes loadbar {
100% {
transform: translateX(0);
}
}
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress -->
<div class="progress-bar-outer">
<div class="progress-bar-inner">
</div>
<div class="progress-bar-inner2">
</div>
</div>
Apply Transition to inner classes, add delays to secondary inner and use opacity to hide the element before transition begins.
.progress-bar-inner {
animation:loadbar 2s;
-webkit-animation:loadbar 2s;
}
.progress-bar-inner2 {
-webkit-animation: loadbar 2s ease 2s forwards;
animation: loadbar 2s ease 2s forwards
animation-delay: 2s;
-webkit-animation-delay: 2s;
opacity:0;
}
#keyframes loadbar {
0% { width: 0%;left:0;right:0}
1% { opacity: 1}
100% { opacity: 1}
}
See working example:
https://jsfiddle.net/dfkLexuv/10/
I have a div. When I hover into this div, 3 circles should pop in using css animation. But they disappear, when I move the mouse away from the div. How can I make them stay without using jquery? Here is my code:
.circle {
width: 50px;
height: 50px;
border-radius: 50px;
background-color: blue;
list-style: none;
opacity: 0;
transform: scale(0);
}
.circles li {
margin-top: 10px;
}
.hoverover:hover + .circles .circle {
animation: popin .25s forwards;
}
#keyframes popin {
80% {
transform: scale(1.15);
}
100% {
opacity: 1;
transform: scale(1);
}
}
<div class="hoverover">Hover Over Me</div>
<ul class="circles">
<li class="circle"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
To make the circles stay as long as the .hoverover element or they are hovered you need to insert the .circles container into .hoverover, and make some changes to the way .circles behave when hovered, and not hovered:
.circles {
margin: 0;
padding: 15px;
}
.hoverover {
display: inline-block; /** limit it to the size and height of the text **/
height: 20px;
}
.hoverover:not(:hover) > .circles { /** prevent opening circles by hovering it when invisible **/
pointer-events: none;
}
.circle {
width: 50px;
height: 50px;
border-radius: 50px;
background-color: blue;
margin-top: 10px;
list-style: none;
opacity: 0;
transform: scale(0);
}
.hoverover:hover .circle {
animation: popin .25s forwards;
}
#keyframes popin {
80% {
transform: scale(1.15);
}
100% {
opacity: 1;
transform: scale(1);
}
}
<div class="hoverover">
<span>Hover Over Me</span>
<ul class="circles">
<li class="circle"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
</div>
Previous answer:
When the .hoverover element is hovered, it applies the animation animation: popin .25s forwards; to the .circle elements. When the hover ends the animation is removed, and the element disappears.
To solve that start the animation paused on the .circle, and "resume" it when .hoverover is hovered:
.circle {
width: 50px;
height: 50px;
border-radius: 50px;
background-color: blue;
list-style: none;
opacity: 0;
transform: scale(0);
animation: popin .25s forwards;
animation-play-state: paused;
}
.circles li {
margin-top: 10px;
}
.hoverover:hover + .circles .circle {
animation-play-state: running;
}
#keyframes popin {
80% {
transform: scale(1.15);
}
100% {
opacity: 1;
transform: scale(1);
}
}
<div class="hoverover">Hover Over Me</div>
<ul class="circles">
<li class="circle"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
You only need to pause animation with
-webkit-animation-play-state: paused; /* Chrome, Safari, Opera */
animation-play-state: paused;
And run it again on hover
-webkit-animation-play-state: running; /* Chrome, Safari, Opera */
animation-play-state: running;
<html>
<div class="hoverover">Hover Over Me</div>
<ul class="circles">
<li class="circle"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
<style>
.circle {
width: 50px;
height: 50px;
border-radius: 50px;
background-color: blue;
list-style: none;
opacity: 0;
transform: scale(0);
}
.circles li {
margin-top: 10px;
}
.circles .circle{
animation: popin .25s forwards;
-webkit-animation-play-state: paused; /* Chrome, Safari, Opera */
animation-play-state: paused;
}
.hoverover:hover + .circles .circle {
-webkit-animation-play-state: running; /* Chrome, Safari, Opera */
animation-play-state: running;
}
#keyframes popin {
80% {
transform: scale(1.15);
}
100% {
opacity: 1;
transform: scale(1);
}
}
</style>
</html>
I am trying to do some transition/transform effect as you can see on this site, where the navigation switches halfway the page and kinda transfers into the other one.
I've created a jsfiddle, with two navs, the .mobilenav is the one that should be changed upon scrolling, and the .desktopnav is the one which slides out as you can see. But now I was wondering how I can make recreate that transition. (The changing nav is done in JQuery with a if, else statement and ($(window).scrollTop() > 500)
I've simulated that nav pretty close in my fiddle, with some simplifications of course: https://jsfiddle.net/pttsky/0anpeLj0/
There are couple of key concepts:
There is actually only one nav to which we add .full class to indicate state change.
There is a container of nav, actual nav and its child li elements
Each of above listed has own CSS transitions and animations that change their positioning, opacity and backgrounds.
Talking deeper on changing nav from collapsed to full-width like on that site.
The container block slightly pulling upwards the nav. It becomes non-transparent, which gives an illusion that border-radius disappeared from the nav, but actually if we'd animated border-radius, that would be ugly.
.nav-container {
display: block;
position: fixed;
width: 100%;
z-index: 2;
top: 0;
padding: 25px 25px 15px;
-webkit-transition: .8s;
transition: .8s;
}
.full {
background: #fff;
padding-top: 15px;
}
The child elements, except MENU link, have max-width: 0 by default. When menu is hovered, or when it is in full-width state, elements have max-width: 200px, and MENU has reversed behaviour:
.nav-main .item {
display: block;
float: left;
max-width: 0;
opacity: 0;
-webkit-transition: .8s;
transition: .8s;
/* limit width */
overflow: hidden;
line-height: 3em;
}
.nav-main .toggle {
max-width: 200px;
opacity: 1;
-webkit-transition: .6s .4s;
transition: .6s .4s;
}
.full .nav-main .item {
max-width: 200px;
opacity: 1;
}
.full .nav-main .item + .item {
margin-left: 12vw;
}
.full .nav-main .toggle {
max-width: 0;
opacity: 0;
-webkit-transition: .1s;
transition: .1s;
}
When changing state, all items of nav seems like fade out then fade in. I've added the appropriate animation to the whole nav:
/* nav full-width */
#keyframes blink {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
.full .nav-main {
animation: blink .8s;
}
Alternatively to Device's answer, you could also use css transitions on one nav to get the same effect, instead of using two navs.
By switching the class on the nav you can trigger the transition and place the navigation in its correct place.
JS:
$(document).ready(function() {
var nav = $('.desktopnav');
$(window).scroll(function() {
var scrolltop = $(window).scrollTop();
if (scrolltop > 500 && !nav.hasClass('scrolled')) {
nav.addClass('scrolled');
}
else if (scrolltop <= 500 && nav.hasClass('scrolled')) {
nav.removeClass('scrolled');
}
});
});
CSS:
.desktopnav {
/* ... snipped, unchanged ... */
transition: all 0.2s ease-out;
}
.desktopnav>ul {
transition: all 0.2s ease-out;
}
.desktopnav>ul>.dropdown {
/* ... snipped, unchanged ... */
transition: all 0.2s ease-out;
}
/* ... snipped unchanged styles for the unscrolled menu ... */
.desktopnav.scrolled {
top: 0px;
right: auto;
left: 0px;
width: 100%;
}
.desktopnav.scrolled>ul {
margin-top:0px;
background: #fff;
}
.desktopnav.scrolled>ul>.dropdown {
border-radius: 0px;
}
.desktopnav.scrolled>ul>.dropdown .dropdown-content {
max-width: 1000px;
float: none;
display: inline-block;
vertical-align: middle;
margin-left: 19px;
}
https://jsfiddle.net/q80k0y7v/1/
I have created a fullscreen overlay menu for my personal portfolio. It's working absolutely fine in Chrome / FF / IE on desktop and on my regular Android browser on my Galaxy S4. However, I cannot get it to work on Chrome for Android. It's as if the jQuery just isn't being toggled in that browser.
Code below. JSFiddle here. Live example here.
HTML:
<div class="button-container" id="toggle">
<span class="top"></span>
<span class="middle"></span>
<span class="bottom"></span>
</div>
<div class="overlay" id="overlay">
<nav class="overlay-menu">
<ul>
<li>Home</li>
<li>About</li>
<li>Portfolio</li>
<li>Resume</li>
<li>Contact</li>
</ul>
</nav>
</div>
JS:
$(document).ready(function(){
$("#toggle").on('click touchstart', function(event) {
event.preventdefault();
$("#overlay").toggleClass("open")
});
});
CSS:
.overlay {
position: fixed;
background: #FF5252;;
top: 0;
left: 0;
width: 0%;
height: 100%;
opacity: 0;
visibility: hidden;
-webkit-transition: opacity .35s, visibility .35s, width .35s ease-in-out;
transition: opacity .35s, visibility .35s, width .35s ease-in-out;
overflow: hidden;
z-index: 100;
}
.overlay.open {
opacity: .9;
visibility: visible;
width: 100%;
}
.overlay nav {
position: relative;
height: 60%;
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
font-size: 32px;
font-family: 'Montserrat', sans-serif;
font-weight: 400;
text-align: center;
}
.overlay nav ul {
list-style: none;
padding: 0;
margin: 0 auto;
display: inline-block;
position: relative;
height: 100%;
}
.overlay nav ul li {
display: block;
height: 20%;
height: -webkit-calc(100% / 5);
height: calc(100% / 5);
min-height: 32px;
position: relative;
opacity: 0;
}
.overlay.open nav ul li {
-webkit-animation: menuFade .5s ease forwards;
animation: menuFade .5s ease forwards;
-webkit-animation-delay: .35s;
animation-delay: .35s;
}
.overlay.open nav ul li:nth-of-type(2) {
-webkit-animation-delay: .4s;
animation-delay: .4s;
}
.overlay.open nav ul li:nth-of-type(3) {
-webkit-animation-delay: .45s;
animation-delay: .45s;
}
.overlay.open nav ul li:nth-of-type(4) {
-webkit-animation-delay: .5s;
animation-delay: .5s;
}
.overlay.open nav ul li:nth-of-type(5) {
-webkit-animation-delay: .55s;
animation-delay: .55s;
}
#-webkit-keyframes menuFade {
0% {
opacity: 0;
left: -25%;
}
100% {
opacity: 1;
left: 0;
}
}
#keyframes menuFade {
0% {
opacity: 0;
left: -25%;
}
100% {
opacity: 1;
left: 0;
}
}
.overlay nav ul li a {
display: block;
position: relative;
color: #FFF;
overflow: hidden;
}
.overlay nav ul li a:hover {
text-decoration: none;
}
.overlay nav ul li a:after {
content: '';
position: absolute;
bottom: 0;
left: 0%;
-webkit-transform: translateX(-105%);
-ms-transform: translateX(-105%);
transform: translateX(-105%);
height: 3px;
width: 100%;
background: #FFF;
-webkit-transition: .35s ease;
transition: .35s ease;
}
.overlay nav ul li a:hover:after {
-webkit-transform: translateX(0%);
-ms-transform: translateX(0%);
transform: translateX(0%);
}
Problem solved. My phone cached the old version of the JS file, which didn't jive with the new menu. Clearing the cache solved all problems.