Senjai
Senjai

Reputation: 1816

CSS Transition confusion when transitioning an element inside of its parent

Given the following HTML and CSS:

transitions2.html

<!DOCTYPE html>
<html>
  <head>
    <title>CSS Transformations</title>
    <link rel="stylesheet" href="transitions2.css">
  </head>
  <body>
    <div class="wrap">
      <div class="box"></div>
    </div>
  </body>
</html>

transitons2.css

.wrap {
  margin: 0 auto;
  padding: 15px;
  width: 850px;
  height: 300px;
  box-shadow: 0 0 20px rgba(0,0,0,.5);
}

.box {
  width: 25%;
  height: 200px;
  border-radius: 8px;
  background: #4682B4;
  -webkit-transition-duration: 1s;
}

.wrap:hover .box{
  background: #F08080;
  margin-left: 75%;
}

My issue is with the last declaration selecting .box in .wrap:hover. How does this work? Why isn't .wrap moved as well? When I mouse into .box's parent element, only the .box is moved. What causes this behaviour?

Upvotes: 1

Views: 739

Answers (2)

lloan
lloan

Reputation: 1403

.wrap:hover .box is just like saying

When I hover over .wrap, .box will do the following.

I actually find `.wrap:hover > .box a bit less obvious, but that's just me.

There is also SO POST - Different Example which also works.

ul:not(:hover)>li.active { background: black; }
ul>li.active:not(:hover) { background: none; }
This has a few conditions:

A browser which supports the :not pseudo-tag
The ul must not have too much padding or empty space, otherwise you could activate the :hover of the ul without hovering over any list.

Upvotes: 1

George Anthony
George Anthony

Reputation: 76

The reason the parent doesn't move is because you are in fact not selecting it. Your code selects a child class of wrap named box when the hover event fires and makes its changes to that element.

If you want the parent to move instead of the child, removing the selection for the child class box is necessary, but will produce ugly results. The code above is working as expected.

Incidentally, the code can also be written as:

.wrap:hover > .box 
{
    background: #F08080;
    margin-left: 75%;
}

Which in my opinion makes it clearer to see what's going on, but that's my preference.

Upvotes: 3

Related Questions