I want to achieve to have different transition for each transform when class is added/removed from element. Best solution would be not modifying HTML structure or even adding additional classes.
.navbar {
height: 60px;
transform: translate(0, 0);
transition: transform .5s ease; /* for transform: translate(0, -60px); */
transition: transform .2s linear; /* for transform: translate(200px, 0); */
}
.navbar.slide-up {
transform: translate(0, -60px);
}
.navbar.slide-left {
transform: translate(200px, 0);
}
You add the transition on the togglable classes
.navbar {
height: 60px;
transition: transform .35s; /* same for both when class is removed */
transform: translate(0, 0);
}
.navbar.slide-up {
transition: transform .5s ease; /* for transform: translate(0, -60px); */
transform: translate(0, -60px);
}
.navbar.slide-left {
transition: transform .2s linear; /* for transform: translate(200px, 0); */
transform: translate(200px, 0);
}
Updated, 2:nd
Note, based on how your script looks like, it might be possible to use the given transition and set it to the navbar on removal using cssText (and if, you won't need the extra classes)
Updated
If it will be possible to add 2 more classes, one can get a unique transition when resetting the elements position
With this, you first clear all classes, add one of them, and then, on removal add its reverse.
.navbar {
height: 60px;
transform: translate(0, 0);
}
.navbar.slide-up {
transition: transform .5s ease; /* for transform: translate(0, -60px); */
transform: translate(0, -60px);
}
.navbar.slide-left {
transition: transform .2s linear; /* for transform: translate(200px, 0); */
transform: translate(200px, 0);
}
.navbar.slide-up-reverse {
transition: transform .5s ease; /* for transform: translate(0, -60px); */
}
.navbar.slide-left-reverse {
transition: transform .2s linear; /* for transform: translate(200px, 0); */
}
Related
Trying to build an hamburger button with animation using css transitions/transforms. I would like the rotation to start only after the translation of the first and the third span is completed (they should overlap with the middle span). Thus I put the transforms chained in the css like so:
transform: translate(0, -28px) rotate(-45deg);
but it seems not working, rotation starts together with translation. Anyone knows how to fix?
$( window ).load(function() {
$("#hamburger").click(function(){
$(this).toggleClass("open");
});
});
*, *:before, *:after {
box-sizing: border-box;
}
body {
background-color: #333;
}
#hamburger {
margin: 2em;
position: relative;
width: 80px;
height: 60px;
cursor: pointer;
}
#hamburger span {
display: block;
position: absolute;
left: 0;
width: 100%;
height: 4px;
background: #fff;
-webkit-transition: transform .25s linear;
-moz-transition: transform .25s linear;
-o-transition: transform .25s linear;
transition: transform .25s linear;
&:nth-child(2) {
-webkit-transition: width 0s linear .25s;
-moz-transition: width 0s linear .25s;
-o-transition: width 0s linear .25s;
transition: width 0s linear .25s;
}
}
#hamburger span:nth-child(1) {
top: 0;
}
#hamburger span:nth-child(2) {
top: 28px;
}
#hamburger span:nth-child(3) {
bottom: 0;
}
#hamburger.open span:nth-child(1) {
-webkit-transform: translate(0, 28px) rotate(45deg);
-moz-transform: translate(0, 28px) rotate(45deg);
-o-transform: translate(0, 28px) rotate(45deg);
transform: translate(0, 28px) rotate(45deg);
}
#hamburger.open span:nth-child(2) {
width: 0;
}
#hamburger.open span:nth-child(3) {
-webkit-transform: translate(0, -28px) rotate(-45deg);
-moz-transform: translate(0, -28px) rotate(-45deg);
-o-transform: translate(0, -28px) rotate(-45deg);
transform: translate(0, -28px) rotate(-45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="hamburger">
<span></span>
<span></span>
<span></span>
</div>
You could split your transform into two different classes, one with translate() and one with rotate(), and then split up the transitions with .delay(), like so:
$("#hamburger").click(function(){
$(this).toggleClass("translateClass");
$(this).delay(250).toggleClass("rotateClass");
);
Solved following #Kadin Zhang suggestion splitting the animation in two transitions. I've substituted the translate transform with a simple change in the top property because in this way the transform-origin moves with the element (otherwise the origin remains in the previous coordinate system and the rotation will be wrong).
$( window ).load(function() {
var state = false;
$("#hamburger").click(function(){
self = $(this);
if (!state) {
self.addClass("open-translate");
setTimeout(function() {
self.addClass("open-rotate");
state = true;
}, 250);
}
else {
self.removeClass("open-rotate");
setTimeout(function() {
self.removeClass("open-translate");
state = false;
}, 250);
}
});
});
*, *:before, *:after {
box-sizing: border-box;
}
body {
background-color: #333;
}
#hamburger {
margin: 2em;
position: relative;
width: 80px;
height: 60px;
cursor: pointer;
}
#hamburger span {
display: block;
position: absolute;
left: 0;
width: 100%;
height: 4px;
background: #fff;
-webkit-transition: all .25s linear;
-moz-transition: all .25s linear;
-o-transition: all .25s linear;
transition: all .25s linear;
&:nth-child(2) {
-webkit-transition: width 0s linear .25s;
-moz-transition: width 0s linear .25s;
-o-transition: width 0s linear .25s;
transition: width 0s linear .25s;
}
}
#hamburger span:nth-child(1) {
top: 0;
}
#hamburger span:nth-child(2) {
top: 28px;
}
#hamburger span:nth-child(3) {
top: 56px;
}
#hamburger.open-translate span:nth-child(1) {
top: 28px;
}
#hamburger.open-rotate span:nth-child(1) {
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
#hamburger.open-translate span:nth-child(2) {
width: 0;
}
#hamburger.open-translate span:nth-child(3) {
top: 28px;
}
#hamburger.open-rotate span:nth-child(3) {
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="hamburger">
<span></span>
<span></span>
<span></span>
</div>
Can someone please tell me why my icon just moves to the right when it's supposed to rotate?
.rotate-icon{
display: inline-block;
-webkit-transition: -webkit-transform 0.6s ease-out;
-moz-transition: -moz-transform 0.6s ease-out;
-transition: -transform 0.6s ease-out;
}
.rotate-icon:hover{
display: inline-block;
-webkit-transform: rotate(-360deg);
-moz-transform: rotate(-360deg);
-transform: rotate(-360deg);
}
img{
position:absolute;
top: 95vh;
left:10%;
transform: translate(-50%, -50%);
}
JSfiddle
Since I am quite new to HTML I can't get it why I doesn't rotate even it should.
My goal is to get a icon on the lower left icon which rotates on hover.
Thanks for your answers.
You can't use this:
transform: translate(-50%, -50%);
It's override this: -transform: rotate(-360deg); so you doesn't have good position element.
You should move transform: translate(-50%, -50%); to parent element if you want rotate your element as you write in your question.
Your are applying two transition on single item, which ins't letting rotate work,
remove
transform: translate(-50%, -50%); from img style rule, and it works like you would expect.
Here is a fiddle for you
You're overwriting translate() when you redefine transform with rotate() on hover. Combine those two transform properties and set an initial rotate() to transition from.
.rotate-icon{
display: inline-block;
-webkit-transition: -webkit-transform 0.6s ease-out;
-moz-transition: -moz-transform 0.6s ease-out;
transition: transform 0.6s ease-out;
}
.rotate-icon:hover{
display: inline-block;
-webkit-transform: translate(-50%, -50%) rotate(-360deg);
-moz-transform: translate(-50%, -50%) rotate(-360deg);
transform: translate(-50%, -50%) rotate(-360deg);
}
img{
position:absolute;
top: 95vh;
left:10%;
transform: translate(-50%, -50%) rotate(0deg) ;
}
<img src="https://d30y9cdsu7xlg0.cloudfront.net/png/2149-200.png" class="rotate-icon">
I have two images (objects) set side by side in the middle of the page and I want them to move toward each other as if they are going to collide and stop as they are placed beside each one.
So, for the object at the right side I have written the following code, thinking that the object should move from left to right, but the result is far from what I expect. Is it possible to do it by transition? what I want is that one of the objects start moving from left side and the other start moving from the right and meet at the center as if they want to collide.
.one {
border: 3px solid #73AD21;
position: absolute;
}
.two {
top: 45%;
left: 44%;
}
.left1,
.right2 {
float: left;
}
#axis:hover .move-right {
transform: translate(-350px, 0);
-webkit-transform: translate(-350px, 0);
-o-transform: translate(-350px, 0);
-moz-transform: translate(-350px, 0);
}
.object1 {
position: absolute;
transition: all 2s ease-in;
-webkit-transition: all 2s ease-in;
-moz-transition: all 2s ease-in;
-o-transition: all 2s ease-in;
}
<div id="axis" class="one two">
<img class="object1 left1 move-right" src="http://placehold.it/50x50" />
<img class="object2 right2 move-left" src="http://placehold.it/75x75" />
</div>
I have two images [...] what I want is that one of the objects start moving from left side and the other start moving from the right and meet at the center as if they want to collide.
Is it possible to do it by transition?
Yes it is - if I have understood your question correctly.
An important consideration with CSS transitions is that you should explicitly set the start-state and the end-state, so the browser is clear what it is transitioning between.
So... in the example you post in your question, it's important to state the translateX position for the images when :hover applies, but also when :hover doesn't apply.
That way, the browser can be clear what two translateX co-ordinates it is transitioning between.
Example:
#axis {
border: 3px solid #73AD21;
position: absolute;
top: 45%;
left: 44%;
}
#axis img {
float: left;
transition: all 1s ease-in;
-webkit-transition: all 1s ease-in;
-moz-transition: all 1s ease-in;
-o-transition: all 1s ease-in;
}
#axis .move-left {
transform: translateX(200px);
-webkit-transform: translateX(200px);
-o-transform: translateX(200px);
-moz-transform: translateX(200px);
}
#axis .move-right {
transform: translateX(-200px);
-webkit-transform: translateX(-200px);
-o-transform: translateX(-200px);
-moz-transform: translateX(-200px);
}
#axis:hover .move-left, #axis:hover .move-right {
transform: translateX(0px);
-webkit-transform: translateX(0);
-o-transform: translateX(0);
-moz-transform: translateX(0);
}
p {
font-weight:bold;
}
<p>Hover over the green border box.</p>
<div id="axis">
<img class="move-right" src="http://placehold.it/50x50" />
<img class="move-left" src="http://placehold.it/75x75" />
</div>
Version 2 (move just once when the page loads)
function initialiseAxisImages() {
var axis = document.getElementById('axis');
var axisImages = axis.getElementsByTagName('img');
axisImages[0].classList.remove('move-right');
axisImages[1].classList.remove('move-left');
}
window.addEventListener('load', initialiseAxisImages, false);
#axis {
border: 3px solid #73AD21;
position: absolute;
top: 45%;
left: 44%;
}
#axis img {
float: left;
transition: all 1s ease-in;
-webkit-transition: all 1s ease-in;
-moz-transition: all 1s ease-in;
-o-transition: all 1s ease-in;
}
#axis .move-left {
transform: translateX(200px);
-webkit-transform: translateX(200px);
-o-transform: translateX(200px);
-moz-transform: translateX(200px);
}
#axis .move-right {
transform: translateX(-200px);
-webkit-transform: translateX(-200px);
-o-transform: translateX(-200px);
-moz-transform: translateX(-200px);
}
<div id="axis">
<img class="move-right" src="http://placehold.it/50x50" />
<img class="move-left" src="http://placehold.it/75x75" />
</div>
I'm not strong in javascript, so I generally lean on jQuery.
If I were solving it with jQuery I'd decide when I wanted my animation to start then use this code to animate my element:
$('#axis .move-right').addClass('animate');
Here's an example that adds the class .animate when you click on the #axis element.
//binds an anonymous function to the 'click' event on #axis
$('#axis').on('click',function(){
//adds your 'animation' class that triggers the CSS animation
$('#axis .move-right').addClass('animate');
});
.one {
border: 3px solid #73AD21;
position: absolute;
}
.two {
top: 45%;
left: 44%;
}
.left1,
.right2 {
float: left;
}
#axis .move-right.animate {
transform: translate(-350px, 0);
-webkit-transform: translate(-350px, 0);
-o-transform: translate(-350px, 0);
-moz-transform: translate(-350px, 0);
}
.object1 {
position: absolute;
transition: all 2s ease-in;
-webkit-transition: all 2s ease-in;
-moz-transition: all 2s ease-in;
-o-transition: all 2s ease-in;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="axis" class="one two">
<img class="object1 left1 move-right" src="http://placehold.it/50x50" />
<img class="object2 right2 move-left" src="http://placehold.it/75x75" />
</div>
See this updated fiddle for one of the boxes moving into the middle:
https://jsfiddle.net/fuce0x67/
//binds an anonymous function to the 'click' event on #axis
$('#axis').on('click',function(){
//adds your 'animation' class that triggers the CSS animation
$('#axis .move-right').addClass('animate');
});
.one {
border: 3px solid #73AD21;
position: absolute;
}
.two {
top: 45%;
left: 44%;
}
.left1,
.right2 {
float: left;
}
#axis .move-right { //removed animate class from here. This is now the 'default' (pre-animation) position for this element
transform: translate(-350px, 0);
-webkit-transform: translate(-350px, 0);
-o-transform: translate(-350px, 0);
-moz-transform: translate(-350px, 0);
}
#axis .move-right.animate {//added this block to reset the positions to ~center like I think you want
transform: translate(-70px, 0);
-webkit-transform: translate(-70px, 0);
-o-transform: translate(-70px, 0);
-moz-transform: translate(-70px, 0);
}
.object1 {
position: absolute;
transition: all 2s ease-in;
-webkit-transition: all 2s ease-in;
-moz-transition: all 2s ease-in;
-o-transition: all 2s ease-in;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="axis" class="one two">
<img class="object1 left1 move-right" src="http://placehold.it/50x50" />
<img class="object2 right2 move-left" src="http://placehold.it/75x75" />
</div>
<p>
click on the box in the center to activate animation
</p>
I have a left menu, and when I hover to a menu item a submenu open and when clicking on the submenu, the background covers my entire page if the internet is slow, and then goes back as it was.
CSS
#media (min-width: 478px) {
nav.main-menu {
position: absolute;
top: 72px;
left: 0;
z-index: 1010;
overflow: hidden;
width: 60px;
height: 100%;
background: #333333;
-moz-transform: translateZ(0) scale(1, 1);
-ms-transform: translateZ(0) scale(1, 1);
-o-transform: translateZ(0) scale(1, 1);
-webkit-transform: translateZ(0) scale(1, 1);
-moz-transition: width 0.05s linear;
-o-transition: width 0.05s linear;
-webkit-transition: width 0.05s linear;
transition: width 0.05s linear;
transform: translateZ(0) scale(1, 1);
}
nav.main-menu > ul {
margin: 7px 0;
}
nav.main-menu li {
position: relative;
display: block;
width: 250px;
}
}
How to fix this?
Deleted this part and it worked fine:
-moz-transform: translateZ(0) scale(1, 1);
-ms-transform: translateZ(0) scale(1, 1);
-o-transform: translateZ(0) scale(1, 1);
-webkit-transform: translateZ(0) scale(1, 1);
-moz-transition: width 0.05s linear;
-o-transition: width 0.05s linear;
-webkit-transition: width 0.05s linear;
transition: width 0.05s linear;
transform: translateZ(0) scale(1, 1);
Is there a way to slow down a hover effect? I have a hover effect on my site (removed) that displays text on hover of the images. I want to slow down the effect by a little. It's a tad jarring how quickly the picture switches over.
How would I do that?
You could add css3 transitions:
-webkit-transition: all 500ms ease;
-moz-transition: all 500ms ease;
-ms-transition: all 500ms ease;
-o-transition: all 500ms ease;
transition: all 500ms ease;
It depends on how you're displaying the text. If you're changing a CSS property you can do this with CSS3 transitions. Below is an example.
HTML:
<div id="A"></div><div id="B"></div>
CSS:
div {
height: 100px;
width: 100px;
position: absolute;
top: 0;
left: 0;
-moz-transition: opacity 4s; /* Firefox */
-webkit-transition: opacity 4s; /* Safari and Chrome */
-o-transition: opacity 4s; /* Opera */
transition: opacity 4s;
}
#A {
background: red;
opacity: 1;
z-index: 1;
}
#B {
background: blue;
opacity: 0;
z-index: 2;
}
#B:hover {
opacity: 1;
}
Demo
Edit: David Thomas has told me that you cannot change the display with transitions. I have updated the above to use opacity.
I know this is quite a bit late but look into CSS3 animations. I use an animation on one of my Garry's Mod loading screens.
/* Styles go here */
button {
margin-left: 50%;
margin-right: 50%;
}
button:hover {
-webkit-animation: breathing 5s ease-out infinite normal;
animation: breathing 5s ease-out infinite normal;
}
#-webkit-keyframes breathing {
0% {
-webkit-transform: scale(1);
transform: scale(1);
}
25% {
-webkit-transform: scale(1.5);
transform: scale(1.5);
}
50% {
-webkit-transform: scale(1);
transform: scale(1);
}
75% {
-webkit-transform: scale(1.5);
transform: scale(1.5);
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
}
}
#keyframes breathing {
0% {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
25% {
-webkit-transform: scale(1.5);
-ms-transform: scale(1.5);
transform: scale(1.5);
}
50% {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
75% {
-webkit-transform: scale(1.5);
-ms-transform: scale(1.5);
transform: scale(1.5);
}
100% {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<h1>Hello Plunker!</h1>
<p>Below I have a button that changes size on mouse hover useing CSS3</p>
<button>Hover over me!</button>
</body>
</html>
I know it's not quite the result your looking for but I'm sure you and others can find this useful.
If you'd like, you could use jQuery .fadeIn() http://api.jquery.com/fadeIn/
.fadeIn( [duration] [, callback] )
duration string or number determining how long the animation will run.
callback function to call once the animation is complete.