I am try to have the caret in the following rotate 180 degrees on click for my dropdown menu. In the solution Im trying to implement, it changes the class of the the caret to toggle-up or toggle-down on click. The first time I click on it rotates up, the second time it immediately goes back to its starting position and then rotates back up. I smell dirty code, whats the easiest way to add this toggle rotation animation. Thanks in advance for any help. Heres my current css:
.toggle-up {
animation-name: toggle-up;
animation-delay: 0.25s;
animation-duration: 0.75s;
animation-fill-mode: forwards;
}
.toggle-down {
animation-name: toggle-down;
animation-delay: 0.25s;
animation-duration: 0.75s;
animation-fill-mode: forwards;
}
/*animations*/
#keyframes toggle-up {
100% {
transform: rotate(180deg);
}
}
#keyframes toggle-down {
100% {
transform: rotate(180deg);
}
}
You don't really need a keyframe animation for something this simple. If you just add a class to your icon on click then remove it this will apply your rotation. Here is a working plunkr using font awesome and a simple rotation. This is just a simple example, you will want to make use of vendor prefixes and be aware that css transitions do not work in older browsers.
<div id="container">
<i id="icon" class="fa fa-arrow-down"></i>
</div>
.fa-arrow-down{
transform: rotate(0deg);
transition: transform 1s linear;
}
.fa-arrow-down.open{
transform: rotate(180deg);
transition: transform 1s linear;
}
(function(document){
var div = document.getElementById('container');
var icon = document.getElementById('icon');
var open = false;
div.addEventListener('click', function(){
if(open){
icon.className = 'fa fa-arrow-down';
} else{
icon.className = 'fa fa-arrow-down open';
}
open = !open;
});
})(document);
.square {
width: 100px;
height: 100px;
background-color: #ff0000;
transition: all 0.75s 0.25s;
}
.toggle-up {
transform: rotate(180deg);
}
.toggle-down {
transform: rotate(0);
}
You should have an initial state in order to complete your animation.
Here is the example: codepen
UPDATE
Here is the version without using javascript: codepen
<label for="checkbox">
<input type="checkbox" id="checkbox">
<div class="square toggle-down"></div>
</label>
#checkbox {
display: none;
}
.square {
width: 100px;
height: 100px;
background-color: #ff0000;
transition: all 0.75s 0.25s;
transform: rotate(0);
}
#checkbox:checked + .square {
transform: rotate(180deg);
}
The general idea is to change the block class using Adjacent sibling selectors and the checkbox checked state.
Related
An element has class slider-item:
.slider-item{
transform: translateY(100%);
transition: transform 100s ease;
transition-delay: 800ms;
}
When i click on a button ,i want the element to transition between translateY(-100%) and translateY(0).
I add classes prev-version and next by javascript respectively:
.slider-item.prev-version{
transform: translateY(-100%);
transition: none;
}
.slider-item.next{
transform: translateY(0);
transition: transform 100s ease;
transition-delay: 800ms;
}
But i see transition happens between translateY(100%) and translateY(0). next class overrides transform: translateY(-100%); in prev-version class. Please help me what should i do?
The best thing to try would probably be to use Vanilla JavaScript, jQuery, or some other type of framework to directly edit and change the CSS attributes.
So for example the jQuery version would be:
$("#slider-item.next").css("transform:translateY(0)");
Keep in mind you would need to add logic so that if the attribute was 100 it would change it back to 0 and then if it was 0 it would change it back to 100.
w3schools.com/jquery/jquery_css.asp
I might didn't understand your question but seems that you can use css animation for this:
document.querySelector('button').addEventListener('click', function () { document.querySelector('.slider-item').classList.add('example'); });
button {position: fixed; bottom: 10vh} /* just for demo */
.slider-item{
transform: translateY(100%);
transition: transform 100s ease;
transition-delay: 800ms;
}
.example {
animation: example 3s ease-in-out;
}
#keyframes example {
from {transform: translateY(-100%);}
to { transform: translateY(100%);} /* should be the same as the value declared initial on .slider-item */
}
<div class="slider-item">Slider Item</div>
<button>Click</button>
I'm working on a project that is using Intersection Observer to add animation to an element's style upon entry. However, what I'm noticing is that the : hover attribute no longer works when I apply the style. Am I doing this wrong, or, are these two not compatible? On the JS Fiddle, I've commented out the hover attribute by default. Try uncommenting it and see what happens.
I've tried banner.classList.add(/new class in here/) but that method also took away the :hover as well.
DEMO:
Demo
disable animation on hover because animations has a higher specificity
const options = {
root: null,
threshold: 1,
};
const banner = document.querySelector('.product-banner');
const observerAnim = new IntersectionObserver(function(entries, observer) {
entries.forEach(entry => {
if (!entry.isIntersecting) {
return;
}
banner.style.animation = '1s ease-in-out home-page-fade';
banner.style.animationFillMode = 'forwards';
observer.unobserve(banner);
});
}, options);
observerAnim.observe(banner);
body {
background-color: #fff;
min-height: 2000px;
}
img.product-banner {
opacity:0;
position: relative;
top: 1000px;
-moz-transition: all ease 0.3s;
-webkit-transition: all ease 0.3s;
transition: all ease 0.3s;
}
#keyframes home-page-fade {
0% {
transform: translateY(50%);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
img.product-banner:hover {
animation: none !important;
opacity: 0.8;
transform: scale(0.9);
-moz-transition: all ease 0.3s;
-webkit-transition: all ease 0.3s;
transition: all ease 0.3s;
}
<h1>
Scroll Effect
</h1>
<img class="product-banner" src="https://cdn.mos.cms.futurecdn.net/bQgcMwEnyhFu6ASuUFrtsn-1024-80.jpg" width="300">
I have worked on a searchbar that appears when user scrolls down the page, and disappears when they scroll up. I was able to get the animation working perfectly with position: fixed, however, the same styling is not working with position: absolute.
Apparently when the iOS keyboard appears, elements with position: fixed go haywire - so I must make this work with position: absolute. The problem now is that the behavior does not work at all. It is actually behaving almost in reverse, where it appears when the page load and immediately translates upward in a flickering manner. Can anyone come up with a solution?
My code below and is in ReactJS and Scss and you can find the sandbox version here: https://codesandbox.io/s/lxyx58jo4m?fontsize=14. If you are unfamiliar with React, isSearchBar is determining if the class is show-search-bar or hide-search-bar based on the scroll
<div className={`search-bar-mobile-container ${isSearchBar ? "show-search-bar" : "hide-search-bar"}`} >
<form>
</form>
</div>
#keyframes exit-up-search-bar {
from {
transform: translateY(0);
}
to {
transform: translateY(-76px);
height: 0;
}
}
#keyframes entrance-down-search-bar {
from {
transform: translateY(-100%);
}
to {
transform: translateY(0);
height: 76px;
}
}
.search-bar-mobile-container{
width: 100%;
height: 76px;
background-color: #00c0d1;
position: absolute;
z-index: 1000000001;
top:-76px;
transition: all 0.3s ease-out;
&.show-search-bar{
animation: entrance-down-search-bar 0.3s forwards;
animation-timing-function: ease-out;
top:0;
}
&.hide-search-bar{
animation: exit-up-search-bar 5s forwards;
animation-timing-function: ease-out;
top:-76px;
}
}
I have a codepen here: http://codepen.io/huwrowlands/pen/GgmjqX
HTML:
<div class="site-branding">
<a href="#">
<img alt="Land" class="site-logo site-logo-land" src="http://website-test-lab.com/sites/landchain/wp-content/themes/landchain/assets/img/land.png" />
</a>
</div>
CSS:
/* Basic Styles */
.site-logo {
visibility: hidden;
max-width: 127px;
margin: 0 auto;
display: block;
}
/* Animation CSS */
.slideRight{
animation-name: slideRight;
-webkit-animation-name: slideRight;
animation-duration: 1s;
-webkit-animation-duration: 1s;
animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out;
visibility: visible !important;
}
#keyframes slideRight {
0% {
transform: translateX(-150%);
}
50%{
transform: translateX(8%);
}
65%{
transform: translateX(-4%);
}
80%{
transform: translateX(4%);
}
95%{
transform: translateX(-2%);
}
100% {
transform: translateX(0%);
}
}
#-webkit-keyframes slideRight {
0% {
-webkit-transform: translateX(-150%);
}
50%{
-webkit-transform: translateX(8%);
}
65%{
-webkit-transform: translateX(-4%);
}
80%{
-webkit-transform: translateX(4%);
}
95%{
-webkit-transform: translateX(-2%);
}
100% {
-webkit-transform: translateX(0%);
}
}
/**/
.slideRightLeft{
animation-name: slideRightLeft;
-webkit-animation-name: slideRightLeft;
animation-duration: 1s ;
-webkit-animation-duration: 1s;
animation-iteration-count: infinite;
-webkit-iteration-count: infinite;
animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out;
visibility: visible !important;
}
#keyframes slideRightLeft {
0% {
transform: translateX(0%);
}
50% {
transform: translate(-50%);
}
100% {
transform: translateX(0%);
}
}
#-webkit-keyframes slideRightLeft {
0% {
-webkit-transform: translateX(0%);
}
50% {
transform: translate(-50%);
}
100% {
-webkit-transform: translateX(0%);
}
}
JS:
//Animations (Delay)
jQuery(function(){
setTimeout(function(){
jQuery('.site-logo-land').addClass("slideRight");
}, 1000);
});
jQuery( ".site-logo" ).hover(function() {
jQuery( this ).addClass( "slideRightLeft" );
});
On page load, the Land logo animates in by adding a class which is controlled by CSS keyframe animations.
I also have a jQuery snippet to add another class to animate he Land logo on hover.
What I require, is that the hover effect to work each time a user hovers over the Land logo. Currently, it only does this once.
Not sure, if this is something to do with my CSS keyframes animation code, or something I need to fix with my jQuery.
Thanks in advance
jQuery hover function doesn't work like the css :hover class where styles are just applied on hover, and removed after mouseout. You need to remove the class on mouseout again:
jQuery( ".site-logo" ).on('mouseout', function() {
jQuery( this ).removeClass( "slideRightLeft" );
});
You should add the following to the .slideRightLeft class:
-webkit-animation: slideRightLeft 1.3s infinite;
animation: slideRightLeft 1.3s infinite;
Check this link for a working demo.
Edit
You can find the implementation using jQuery's animate() function here. Note the added style to the img.
JS
jQuery( ".site-logo" ).hover(function() {
jQuery( this ).animate({
left: "-=50"
}, 1000)
.animate({
left: "+=50"
}, 1000);
});
I'm writing an answer since I cannot comment cause of my low rep (I need at least 50 to do so). But taking the suggestions from Mario A I resolved the issue of the jump on mouseout.
First of all I made some work on your css. I added a transition: 1s transform to the site-logo class, then I removed the keyframe animation for the .slideRightLeft class and added a simple transform: translate(-50%) since with I wasn't able to make the transition work with the keyframe animation. With these changes the text was sliding to the right on hover and if you took off your mouse at any point it would slide back into the original position, but if you left your mouse over the image it would remain at the -50% position until you took your mouse off. Here are the relevant CSS classes:
.site-logo {
max-width: 127px;
margin: 0 auto;
display: block;
transition: 1s transform;
-webkit-transition: 1s -webkit-transform;
}
.slideRightLeft{
transform: translate(-50%);
-webkit-transform: translate(-50%);
}
To resolve that I added a new setTimeout of 1s to your JS and have it remove the slideRightLeftclass, this way if you leave your mouse over the image it would return to the original position within 1s. Also having seen what Mario A had done with the JS I thought it would be simpler to have it all on the .hover function, hence I change the addClass to toggleClass and added the removeClass for the slideRight class on the hover function. Here's the updated JS:
//Animations (Delay)
jQuery(function(){
setTimeout(function(){
jQuery('.site-logo-land').addClass("slideRight");
}, 1000);
});
jQuery( ".site-logo" ).hover(function() {
var curObj = this;
jQuery( this ).toggleClass( "slideRightLeft" );
setTimeout(function(){
jQuery( curObj ).removeClass( "slideRightLeft" );
}, 1000);
jQuery( this ).removeClass( "slideRight" );
});
You can check it out here: http://codepen.io/anon/pen/PwmJRN
Hope I could help!
EDIT
After publishing this I found a bug on the code where if you leave the mouse until the animation finishes and then move it out the animation fires up again, to resolve this I added the following to the JS:
jQuery( ".site-logo" ).on('mouseout', function(){
jQuery( this ).removeClass( "slideRightLeft" );
});
This solves that issue and everything else working as before.
Why not use css:hover selector. You can do something like this:
.site-logo:hover
{
animation-name: slideRightLeft;
-webkit-animation-name: slideRightLeft;
animation-duration: 1s ;
-webkit-animation-duration: 1s;
animation-iteration-count: infinite;
-webkit-iteration-count: infinite;
animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out;
visibility: visible !important;
}
my context
HTML
<div class="cart">
<div class="black"></div>
</div>
JS
var whiteEl="<div class="white"></div>";
//I would like to replace black with white, flip animation.
$(".cart").empty().append(whiteEl);
whiteEl.addClass("flipanim");
css
#-webkit-keyframes flip{
from{
-webkit-transform: rotateY(0deg);
}
to {
-webkit-transform: rotateY(180deg);
}
}
/*
similar cross browser code*/
.flipanim{
-webkit-animation: flip 1s 1;
-moz-animation:flip 1s 1;
-o-animation:flip 1s 1;
animation:flip 1s 1;
-webkit-transition: all .5s;
-moz-transition: all .5s;
-o-transition: all .5s;
transition: all .5s;
}
I am using key frame animation for show transform animation.
and in javascript adding class to attached element.
my animation not working.
How can I add the new element with flip animation to ".cart"?
try this
$(".cart").html('').append(whiteEl);
//since you have already appended the created div here.. you can use class selctor.
$('.white').addClass("flipanim");
You don't need to remove any content for that and also don't need Javascript for it:
html-markup:
<div class="container">
<div class="cart">
<div class="black">Black side</div>
<div class="white">White side</div>
</div>
</div>
css:
.cart div {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
}
.cart .black {
background:#111;
color:white;
}
.cart .white {
-webkit-transform: rotateY(180deg);
color: black;
background: #eee;
}
Now you can apply your effects simply with:
.container:hover .cart {
-webkit-transform: rotateY(180deg);
}
See the Demo