Reputation: 110960
See the snippet below. Notice when you hover over an item, the item's background color changes but the transform: translateY(-5px)
is being ignored. The hover's transform style only works if the .list-item animation is not set.
How can I get the translateY(-5px)
on hover to work in the code?
.list {
display: flex;
flex-direction: column;
align-items: center;
margin: 24px 0;
}
.list-item {
cursor: pointer;
margin-bottom: 14px;
padding: 12px 16px;
border-radius: 50px;
background: #EFEFEF;
animation-name: popin;
animation-fill-mode: both;
animation-duration: .6s;
animation-iteration-count: 1;
animation-timing-function: ease;
animation-delay: 0.1s;
}
.list-item:hover {
background-color: yellow;
transform: translateY(-5px);
}
@keyframes popin {
0%{
transform:scale(0);
}
50%{
transform:scale(1.1);
}
100%{
transform:scale(1);
}
}
<div class="list">
<div class="list-item">item</div>
<div class="list-item">item</div>
<div class="list-item">item</div>
<div class="list-item">item</div>
<div class="list-item">item</div>
<div class="list-item">item</div>
</div>
UPDATE
I also need to have a transition when the translation is done.
Upvotes: 1
Views: 901
Reputation: 272806
Remove the last state from the animation since it's the default one and you will be able to override the transform. Basically the animation will consider the state of the element as the 100%
and when you change it on hover it will also change in the animation.
If a 100% or to keyframe is not specified, then the user agent constructs a 100% keyframe using the computed values of the properties being animated.ref
.list {
display: flex;
flex-direction: column;
align-items: center;
margin: 24px 0;
}
.list-item {
cursor: pointer;
margin-bottom: 14px;
padding: 12px 16px;
border-radius: 50px;
background: #EFEFEF;
animation-name: popin;
animation-fill-mode:both;
animation-duration: .6s;
/*animation-iteration-count: 1; also not needed */
animation-timing-function: ease;
animation-delay: 0.1s;
}
.list-item:hover {
background-color: yellow;
transform: translateY(-5px);
}
@keyframes popin {
0%{
transform:scale(0);
}
50%{
transform:scale(1.1);
}
}
<div class="list">
<div class="list-item">item</div>
<div class="list-item">item</div>
<div class="list-item">item</div>
<div class="list-item">item</div>
<div class="list-item">item</div>
<div class="list-item">item</div>
</div>
UPDATE
if you want the transition you can adjust the code slightly to be able to have two elements where it would be easy to apply transform independently:
.list {
display: flex;
flex-direction: column;
align-items: center;
margin: 24px 0;
}
.list-item {
cursor: pointer;
margin-bottom: 14px;
animation-name: popin;
animation-fill-mode:both;
animation-duration: .6s;
animation-timing-function: ease;
animation-delay: 0.1s;
}
.list-item:before {
content:attr(data-text);
display:block;
padding: 12px 16px;
border-radius: 50px;
background: #EFEFEF;
transition:1s all;
}
.list-item:hover:before {
background-color: yellow;
transform: translateY(-5px);
}
@keyframes popin {
0%{
transform:scale(0);
}
50%{
transform:scale(1.1);
}
}
<div class="list">
<div class="list-item" data-text="item"></div>
<div class="list-item" data-text="item"></div>
<div class="list-item" data-text="item"></div>
<div class="list-item" data-text="item"></div>
<div class="list-item" data-text="item"></div>
<div class="list-item" data-text="item"></div>
</div>
You can also consider an extra wrapper like below:
.list {
display: flex;
flex-direction: column;
align-items: center;
margin: 24px 0;
}
.list-item {
cursor: pointer;
margin-bottom: 14px;
animation-name: popin;
animation-fill-mode:both;
animation-duration: .6s;
animation-timing-function: ease;
animation-delay: 0.1s;
}
.list-item > div {
padding: 12px 16px;
border-radius: 50px;
background: #EFEFEF;
transition:1s all;
}
.list-item:hover > div {
background-color: yellow;
transform: translateY(-5px);
}
@keyframes popin {
0%{
transform:scale(0);
}
50%{
transform:scale(1.1);
}
}
<div class="list">
<div class="list-item"><div>item</div></div>
<div class="list-item"><div>item</div></div>
<div class="list-item"><div>item</div></div>
<div class="list-item"><div>item</div></div>
<div class="list-item"><div>item</div></div>
<div class="list-item"><div>item</div></div>
</div>
Upvotes: 1
Reputation: 882
I was actually facing a similar problem the other day. I can't tell you why it behaves like this but I can tell you how I solved it. I created another animation and activated it on hover
. I used animation-fill-mode: forwards
so the animation would only go back to its initial state after you hover somewhere else.
Give it a try and let me know what you think.
.list {
display: flex;
flex-direction: column;
align-items: center;
margin: 24px 0;
}
.list-item {
cursor: pointer;
margin-bottom: 14px;
padding: 12px 16px;
border-radius: 50px;
border-color: black;
border: 1px solid black;
background: #EFEFEF;
animation-name: popin;
animation-fill-mode: both;
animation-duration: .6s;
animation-iteration-count: 1;
animation-timing-function: ease;
animation-delay: 0.1s;
}
.list-item:hover {
animation: pull-up 0.3s ease-in-out forwards;
background-color: yellow;
}
@keyframes popin {
0%{
transform:scale(0);
}
50%{
transform:scale(1.1);
}
100%{
transform:scale(1);
}
}
@keyframes pull-up {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-5px);
}
}
<div class="list">
<div class="list-item">item</div>
<div class="list-item">item</div>
<div class="list-item">item</div>
<div class="list-item">item</div>
<div class="list-item">item</div>
<div class="list-item">item</div>
</div>
Upvotes: 0