Reputation: 327
I am trying to have a card element move up on hover and then back down when it is no longer hovered. I am currently achieving this by using transform
and translate
in CSS. However, I have noticed that this can affect the children elements as well as the element that I want this animation affected by. Here is the HTML and CSS for the card that I have at the moment:
.server :hover {
-moz-transform: translate(0, -2px);
-ms-transform: translate(0, -2px);
-o-transform: translate(0, -2px);
-webkit-transform: translate(0, -2px);
transform: translate(0, -2px);
transition-duration: 0.3s;
transition-timing-function: ease-in-out;
}
<div class="server">
<div class="card m-2 p-1 text-center">
<p>Child element</p>
</div>
</div>
Upvotes: 0
Views: 4896
Reputation: 601
You've used a compound selector when what you probably want is a chain selector. Just add the :hover
pseudo selector, without a space, directly to the element you want to affect.
.card {
/* transitions are needed when hover state ends, so set up rules here */
transform: translate(0, 0);
transition-property: transform;
transition-duration: 0.3s;
transition-timing-function: ease-in-out;
}
.card:hover { /* note: no space */
transform: translate(0, -2px);
}
<div class="server">
<div class="card m-2 p-1 text-center">
<p>Child element</p>
</div>
</div>
Upvotes: 1
Reputation: 11533
Since children elements would always move with their parent element (same applies to opacity
), you can set the opposite transform on all children.
I added a red background on the card
and set > *
all children to have the opposite transform.
.server :hover {
-moz-transform: translate(0, -2px);
-ms-transform: translate(0, -2px);
-o-transform: translate(0, -2px);
-webkit-transform: translate(0, -2px);
transform: translate(0, -2px);
transition-duration: 0.3s;
transition-timing-function: ease-in-out;
}
.server :hover > * {
transform: translate(0, 2px);
transition-duration: 0.3s;
transition-timing-function: ease-in-out;
}
.card {
background: red;
}
<div class="server">
<div class="card m-2 p-1 text-center">
<p>Child element</p>
</div>
<div class="card m-2 p-1 text-center">
<p>Child element</p>
<p>Child element</p>
<p>Child element</p>
<p>Child element</p>
<p>Child element</p>
<p>Child element</p>
</div>
</div>
Since I'm not sure what your card
element is actually showing, you could also use a pseudo ::before
or ::after
and assign the transform to that:
.server :hover::after {
transform: translate(0, -2px);
transition-duration: 0.3s;
transition-timing-function: ease-in-out;
}
.card {
position: relative;
z-index: 1;
}
.card::after {
content: '';
position: absolute;
top: 0;
left: 0;
background: red;
width: 100%;
height: 100%;
z-index: -1;
}
.card>* {
z-index: 5;
}
<div class="server">
<div class="card m-2 p-1 text-center">
<p>Child element</p>
<p>Child element</p>
<p>Child element</p>
<p>Child element</p>
<p>Child element</p>
</div>
</div>
Upvotes: 3
Reputation: 4015
You can specify by using :not
.server :hover :not(p) {
-moz-transform: translate(0, -2px);
-ms-transform: translate(0, -2px);
-o-transform: translate(0, -2px);
-webkit-transform: translate(0, -2px);
transform: translate(0, -2px);
transition-duration: 0.3s;
transition-timing-function: ease-in-out;
}
<div class="server">
<div class="card m-2 p-1 text-center">
<p>Child element</p>
<div>Child element</div>
</div>
</div>
Upvotes: 2