csscss-selectorscss-transitions

Problems imitating a sibling element's effect to the other sibling


I would like to imitate the effect and output that I have on my #boxLeft, but when I do so, and add a css3 transition, it fails. I had to use fix it with a -100px margin-top value to hide it. Could anyone help?

HTML and CSS:

body {
  padding: 0;
  margin: 0;
}
p, h1, h2, h3, h4, h5, h6 {
  padding: 0;
  margin: 0;
}
#box {
  width: 100%;
  height: 100px;
  background-color: #636363;
}
.boxLeft,
.boxRight {
  width: 50%;
  height: 100px;
  /*   display: inline-block;   */
  float: left;
  padding: 10px;
  box-sizing: border-box;
  z-index: 1;
  overflow: hidden;
}
.boxLeft {
  background-color: red;
}
.blHeader {
  text-align: right;
}
.boxLeft:hover {
  background-color: orange;
  width: 100%;
  transition: .5s;
}
.boxLeft:hover ~.boxRight {
  display: none;
}
.boxLeft:hover > .blHeader {
  text-align: left;
}
.boxLeft:hover > .blCon {
  display: block;
}
.blCon,
.brCon {
  display: none;
}
.boxRight {
  background-color: blue;
}
.boxRight:hover {
  background-color: green;
  width: 100%;
  transition: .5s;
  margin-top: -100px;
}
.boxRight:hover~.boxLeft {
  display: none;
}
.boxRight:hover > .brHeader {
  text-align: left;
}
.boxRight:hover > .brCon {
  display: block;
  transition: .5s;
}
<div id="box">
  <div class="boxLeft">
    <h2 class="blHeader">Left Header</h2>
    <p class="blCon">Left content Lorem ipsum dolor sit amet, consectetur adipisicing elit. Culpa harum recusandae perferendis animi, assumenda iste, repudiandae temporibus. Magni earum dicta perspiciatis tempore consequatur necessitatibus ullam recusandae dolore reiciendis,
      repudiandae cumque!</p>
  </div>
  <div class="boxRight">
    <h2 class="brHeader">RIght Header</h2>
    <p class="brCon">Right content Lorem ipsum dolor sit amet, consectetur adipisicing elit. Culpa harum recusandae perferendis animi, assumenda iste, repudiandae temporibus. Magni earum dicta perspiciatis tempore consequatur necessitatibus ullam recusandae dolore reiciendis,
      repudiandae cumque!</p>
  </div>
</div>

I'm sure I'm just missing out on something, but I've had a crack at it for hours. Thanks in advance. Here's a pen link: https://codepen.io/digiknowzone/pen/zrbjNj


Solution

  • The selector .boxRight:hover ~ .boxLeft isn't working as expected because the general sibling combinator, ~, only selects following sibling elements. Since the element .boxLeft precedes the element .boxRight, nothing is selected and the element .boxLeft isn't hidden when hovering over the element .boxRight.

    To work around this, one option is to hide the first element when hovering over the parent #box element.

    #box:hover .boxLeft {
      display: none;
    }
    

    Then you can override this when actually hovering over the first element:

    #box .boxLeft:hover {
      display: block;
    }
    

    This works because there are only two elements. If you're not hovering over the first element, you can assume that you are otherwise hovering over the second element (which means that imitate the general sibling combinator since you can style the first element when hovering over the parent).

    Updated Snippet:

    body {
      padding: 0;
      margin: 0;
    }
    p, h1, h2, h3, h4, h5, h6 {
      padding: 0;
      margin: 0;
    }
    #box {
      width: 100%;
      height: 100px;
      background-color: #636363;
    }
    .boxLeft,
    .boxRight {
      width: 50%;
      height: 100px;
      /*   display: inline-block;   */
      float: left;
      padding: 10px;
      box-sizing: border-box;
      z-index: 1;
      overflow: hidden;
    }
    .boxLeft {
      background-color: red;
    }
    .blHeader {
      text-align: right;
    }
    .boxLeft:hover {
      background-color: orange;
      width: 100%;
      transition: .5s;
    }
    .boxLeft:hover ~.boxRight {
      display: none;
    }
    .boxLeft:hover > .blHeader {
      text-align: left;
    }
    .boxLeft:hover > .blCon {
      display: block;
    }
    .blCon,
    .brCon {
      display: none;
    }
    .boxRight {
      background-color: blue;
      float: right;
    }
    .boxRight:hover {
      background-color: green;
      width: 100%;
      transition: .5s;
    }
    #box:hover .boxLeft {
      display: none;
    }
    #box .boxLeft:hover {
      display: block;
    }
    .boxRight:hover > .brHeader {
      text-align: left;
    }
    .boxRight:hover > .brCon {
      display: block;
      transition: .5s;
    }
    <div id="box">
      <div class="boxLeft">
        <h2 class="blHeader">Left Header</h2>
        <p class="blCon">Left content Lorem ipsum dolor sit amet, consectetur adipisicing elit. Culpa harum recusandae perferendis animi, assumenda iste, repudiandae temporibus. Magni earum dicta perspiciatis tempore consequatur necessitatibus ullam recusandae dolore reiciendis,
          repudiandae cumque!</p>
      </div>
      <div class="boxRight">
        <h2 class="brHeader">RIght Header</h2>
        <p class="brCon">Right content Lorem ipsum dolor sit amet, consectetur adipisicing elit. Culpa harum recusandae perferendis animi, assumenda iste, repudiandae temporibus. Magni earum dicta perspiciatis tempore consequatur necessitatibus ullam recusandae dolore reiciendis,
          repudiandae cumque!</p>
      </div>
    </div>


    However, a more flexible option would be to remove the elements .boxLeft and .boxRight from the normal flow by absolutely position them. In doing so, you can avoid hiding the corresponding sibling elements on hover:

    Updated Snippet:

    body {
      padding: 0;
      margin: 0;
    }
    p, h1, h2, h3, h4, h5, h6 {
      padding: 0;
      margin: 0;
    }
    #box {
      width: 100%;
      height: 100px;
      background-color: #636363;
    }
    .boxLeft,
    .boxRight {
      width: 50%;
      height: 100px;
      position: absolute;
      top: 0;
      padding: 10px;
      box-sizing: border-box;
      z-index: 1;
      overflow: hidden;
    }
    .boxLeft {
      background-color: red;
    }
    .blHeader {
      text-align: right;
    }
    .boxLeft:hover {
      background-color: orange;
      width: 100%;
      transition: .5s;
    }
    .boxLeft:hover ~ .boxRight {
      z-index: auto;
    }
    .boxLeft:hover > .blHeader {
      text-align: left;
    }
    .boxLeft:hover > .blCon {
      display: block;
    }
    .blCon,
    .brCon {
      display: none;
    }
    .boxRight {
      background-color: blue;
      right: 0;
    }
    .boxRight:hover {
      background-color: green;
      width: 100%;
      transition: .5s;
    }
    .boxRight:hover > .brHeader {
      text-align: left;
    }
    .boxRight:hover > .brCon {
      display: block;
      transition: .5s;
    }
    <div id="box">
      <div class="boxLeft">
        <h2 class="blHeader">Left Header</h2>
        <p class="blCon">Left content Lorem ipsum dolor sit amet, consectetur adipisicing elit. Culpa harum recusandae perferendis animi, assumenda iste, repudiandae temporibus. Magni earum dicta perspiciatis tempore consequatur necessitatibus ullam recusandae dolore reiciendis,
          repudiandae cumque!</p>
      </div>
      <div class="boxRight">
        <h2 class="brHeader">RIght Header</h2>
        <p class="brCon">Right content Lorem ipsum dolor sit amet, consectetur adipisicing elit. Culpa harum recusandae perferendis animi, assumenda iste, repudiandae temporibus. Magni earum dicta perspiciatis tempore consequatur necessitatibus ullam recusandae dolore reiciendis,
          repudiandae cumque!</p>
      </div>
    </div>