So I have this arrow that rotates when the .collapse class is applied:
then
The css is:
.my-arrow {
background: url('arrow.svg');
transition: transform ease 0.2s;
transform: rotate(0deg);
&.collapse {
transform: rotate(90deg);
}
}
I also wanted to add a hover effect, for better user feedback.
But if I add:
.my-arrow {
&:hover {
rotate(90deg);
}
&.collapse {
&:hover {
rotate(0deg);
}
}
}
It works on hover, but when I click (= add the .collapse class), it rotates back to 0deg, because the mouse is still hovering the div, which is even more confusing.
Is there any way to tackle this issue? I guess I could do this is JS with an extra class that would toggle onmouseleave, but this is way too complicated for my use case.
I tried with CSS animations:
#keyframes rotate {
0% {
transform: rotate(0);
}
100% {
transform: rotate(90deg);
}
}
#keyframes rotate-back {
0% {
transform: rotate(90deg);
}
100% {
transform: rotate(0);
}
}
.my-arrow {
&:hover {
animation: rotate .2s ease 1;
}
.collapse {
&:hover {
animation: rotate-back .2s ease 1;
}
}
without success, and I'm very n00b in CSS animations. Maybe with a delay?
Cheers
.hover-rotate{
transition: transform .3s; /* Apply the transition property. Enables the animation */
}
.hover-rotate:hover{
transform: rotate(90deg); /* Rotate if mouse is hovered */
}
.hover-rotate.collapse{
transform: rotate(90deg); /* Rotate if collapse class is present */
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet"/>
<i class="hover-rotate fa fa-chevron-right"></i>
You can use the CSS transition property to make this animation. The above code animates if either mouse hovers over the icon or the class .collapse is applied.
Related
I'm doing some CSS animations inside a modal dialog. Here's the pertinent SCSS:
#keyframes grow {
from {
transform: scale(1);
}
to {
transform: scale(1.1);
}
}
#keyframes shrink {
from {
transform: scale(1.1);
}
to {
transform: scale(1);
}
}
$duration: 0.5s;
$animationFillMode: both;
&:not(.active):hover, &.active {
img {
animation: grow $duration $animationFillMode;
}
}
&:not(.active) {
img {
animation: shrink $duration $animationFillMode;
}
}
This works well but the problem is, when I open the modal, the animations kick in immediately. For example, because when the modal is first open I'm not hovering on one of the elements, the element instantly shrinks from big to small. I want the element to start in the small state when the modal is open.
Is is possible? TIA
Yes it is, use reverse tag.
Example: animation-direction: reverse;
I have read a tutorial on how to perform the following effect, it does it correctly, but when I take the mouse out of it what it doesn't do is to do the same in reverse, and the tutorial doesn't explain it.
What am I doing wrong?
.contenedor-efecto:hover img {
transition: 1.5s;
-webkit-transform:scale(1.3);
transform:scale(1.3);
}
.contenedor-efecto {
overflow: hidden;
}
The transition: 1.5s; needs to be applied at a higher level.
At the moment, when you stop hovering, the transition style is no longer applied, so the change is immediate. If you apply it to the un-hovered selector, it will apply in both directions:
.contenedor-efecto img {
/* This is now applied here, outside of the hover selector */
transition: 1.5s;
}
.contenedor-efecto:hover img {
/* The transition style has been removed from here */
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
.contenedor-efecto {
overflow: hidden;
}
/* This is not part of the solution, but it makes the example work well */
.contenedor-efecto {
display: inline-block;
}
<div class="contenedor-efecto">
<img src="https://picsum.photos/seed/picsum/200/200" />
</div>
To run transitions in both direction needs two classes: the original-(not hover)-class and the hover-class. The property which changes has to be described in both classes with the different states. Then the element can change between the states.
To your example it means:
// add class to describe original state for scale
// note transition time here
.contenedor-efecto img {
transform: scale(1);
-webkit-transform: scale(1);
transition: all 1.5s;
}
.contenedor-efecto:hover img {
-webkit-transform: scale(1.3);
transform: scale(1.3);
/* optional: transition: all 1.5s; */
}
I have an icon that initially has a box shadow set. I am animating the icon and scaling it, but I would also like to remove the shadow while I am doing it. I have tried it like this:
.loading-icon {
width: 80px;
height: 80px;
animation-name: earth;
animation-timing-function: ease-in-out;
animation-duration: 3s;
}
#keyframes earth {
0% {
transform: scale(1);
}
100% {
transform: scale(1.5) { box-shadow: none; };
}
}
But, this is not working, how can I do that?
In keyframes you've extra {} surrounding box-shadow which is not needed.
#keyframes earth {
0% {
transform: scale(1);
}
100% {
transform: scale(1.5);
box-shadow: none;
}
}
I am rotating an object with CSS upon hovering, and would like for it to remain in it's new position as you unhover it. I have searched around, but the only thing I could find is css :hover rotate element and keep the new position, which seems to go above and beyond.
Is this effect possible to achieve purely with CSS? I want the icon to remain at the 180 position once you stop hovering.
I used this code:
i.fa.fa-globe:hover {
color: #e9204f;
transition: 0.9s;
transform: rotatey(180deg);
}
Also it's a font-awesome icon if this makes any difference.
Edit - The easy CSS solution for everyone else who needs it (taken from the comments):
.lovernehovermarket i.fa.fa-rocket {
transform: rotate(0deg);
transition: transform 999s;
}
I had a circular icon that I wanted to rotate on every hover, not just the first, and not rotate when un-hovered.
Original
I saw this problem when I had CSS that looked like this
.icon {
transition: transform 0.5s;
}
.icon:hover {
transform: rotate(90deg);
}
Solution
The simple solution was to put the transition inside the :hover psuedo class
.icon:hover {
transition: transform 0.5s;
transform: rotate(90deg);
}
Boom, done!
This works because I was originally setting the transition to be 0.5s by default. In this case, that means both forward and backward. By putting the transition property inside the hover, I have a 0.5s transition when hover is activated, but a 0s transition (the default) when the icon is un-hovered. Having a 0s hover means it just instantly snaps back to position, invisibly to the viewer.
I you want a pure CSS solution, you can set a transtion time to go back to the base state quite high.
It's not for ever, but it's pretty close for most users:
.test {
display: inline-block;
margin: 10px;
background-color: tomato;
transform: rotate(0deg);
transition: transform 999s 999s;
}
.test:hover {
transform: rotate(90deg);
transition: transform 0.5s;
}
<div class="test">TEST</div>
You also need an initial transform state in the regular CSS of your element, so that it can transform between two defined states:
.rotate {
width: 20px;
height: 100px;
background: blue;
transition: 0.9s;
transform: rotate(0deg);
}
.rotate:hover {
transform: rotate(180deg);
}
body {
padding: 100px;
}
<div class="rotate"></div>
If you want to maintain the rotated state, you may have to use a little JQuery to check when the transition ends and change the class so it doesn't revert back to its original state on blur.
This way the div is rotated once and then its class is changed to maintain the rotated state.
$('.rotate').hover(function () {
$(this).addClass("animate");
$(this).one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',
function(e) {
$(this).removeClass('rotate').addClass('rotated');
});
});
.rotate {
width: 100px;
height: 100px;
background: gold;
transition-property: transform;
transition-duration: 1.5s;
transition-timing-function: linear;
}
.animate {
animation: rotate 1s linear;
transform: rotate(180deg);
animation-play-state: running;
}
.rotated
{
width: 100px;
height: 100px;
background: gold;
transform: rotate(180deg);
}
body {
padding: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="rotate">some text</div>
Use an animation, and apply it using JS event listener, when the element is hovered (mouseover event). When the element is hovered for the 1st time, remove the event listener:
var rect = document.querySelector('.rectangle')
function rotate() {
this.classList.add('rotate');
rect.removeEventListener('mouseover', rotate);
}
rect.addEventListener('mouseover', rotate);
.rectangle {
width: 100px;
height: 100px;
background: gold;
}
.rotate {
animation: rotate 0.5s linear;
}
#keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(180deg);
}
}
body {
padding: 30px;
}
<div class="rectangle"></div>
What worked for me was to put the transform not on hover but on the main css.
not:
#gear {
width: 3vh;
height: auto;
cursor: pointer;
&:hover {
transform: rotate(45deg);
transition: transform 200ms;
}
}
but
#gear {
width: 3vh;
height: auto;
cursor: pointer;
transition: transform 200ms;
&:hover {
transform: rotate(45deg);
}
}
I'm using react and I have a button, when the button is clicked I want to rotate it by 180 deg, and when its clicked again, to rotate it again by 180 deg.
What I've managed to do is rotate it at the first time by 180, and in the second time by-180 deg.
jsx:
export default class SomeComponent extends React.Component {
render () {
let classes = 'icon';
if (this.props.isSelected) {
classes += ' selected';
}
return (
<IconButton className={classes}>expand_more</IconButton>
)
}
}
css:
.icon {
transition-duration: .5s;
transition-property: all;
transition-timing-function: cubic-bezier(.4,0,.6,0);
}
.icon.selected {
transform: rotate(180deg);
}
How can I achieve that in the best way?
By using a transition on the default state and an animation on the selected state, you can achieve the effect:
.icon {
transform: rotate(360deg);
transition: 300ms transform;
}
.icon.selected {
animation: spin 300ms;
transform: rotate(180deg);
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
I found that (at least in react-native) the CSS needed to rotate an element is defined as:
transform: [{rotate: '360deg'}]