Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two divs sharing one border and hover:after bug

I need four boxes in the corners of the div. When hovering on some div, I want to display:block a hidden div in the middle, sharing one border with the box being currently hovered.

Here is jsfiddle with my current solution

It almost works fine. However, there are some bugs regarding the corner area. I display there the block element with background using :after. It is to achieve the effect of one border for two elements.

The problem:

So in Chrome hovering that area gives some strange interlacing effect. Each mouse movement by 1px hides and shows content div. You can see it here in action

In newest Firefox it seems to be ok, but in created jsfiddle there's some other bug which you can test yourself.

I'm using grey background just for better visualization of the problem. It is also suppose to work for box 1 for now. Tried some jQuery with mouseover and hover with no success.

EDIT - Final solution:

The most important thing was to set pointer-events: none; to after block element. Since I got some votes up here's more advanced code on jsfiddle using SASS , and here's using plain css:

CSS:

.outer {
  width: 90%;
  height: 300px;
  position: relative;
}

.box-content {
  display: none;
  width: 80%;
  height: 80%;
  position: absolute;
  left: 10%;
  top: 13%;
  background: white;
  z-index: 1;
}

.box {
  width: 150px;
  height: 60px;
  position: absolute;
  border: 1px solid white;
  background: white;
}
.box:hover:after {
  content: '';
  background-color: white;
  z-index: 2;
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
}
.box:hover p {
  z-index: 3;
}
.box p {
  position: absolute;
  top: 23px;
  left: 13px;
  color: black;
  padding: 0;
  margin: 0;
}

.box-one {
  top: 0;
  left: 0;
}
.box-one:hover {
  border: 1px solid blue;
}
.box-one:hover ~ .content-one {
  border: 1px solid blue;
  display: inline-block;
  pointer-events: none;
}

.box-two {
  top: 0;
  right: 0;
}
.box-two:hover {
  border: 1px solid red;
}
.box-two:hover ~ .content-two {
  border: 1px solid red;
  display: inline-block;
  pointer-events: none;
}

.box-three {
  bottom: 0;
  left: 0;
}
.box-three:hover {
  border: 1px solid yellow;
}
.box-three:hover ~ .content-three {
  border: 1px solid yellow;
  display: inline-block;
  pointer-events: none;
}

.box-four {
  bottom: 0;
  right: 0;
}
.box-four:hover {
  border: 1px solid green;
}
.box-four:hover ~ .content-four {
  border: 1px solid green;
  display: inline-block;
  pointer-events: none;
}

HTML

<div class="outer">
  <div class="box box-one">
    <p>BOX NAME 1</p>
  </div>
  <div class="box box-two">
    <p>BOX NAME 2</p>
  </div>
  <div class="box box-three">
    <p>BOX NAME 3</p>
  </div>
  <div class="box box-four">
    <p>BOX NAME 4</p>
  </div>

  <div class="box-content content-one"></div>
  <div class="box-content content-two"></div>
  <div class="box-content content-three"></div>
  <div class="box-content content-four"></div>
</div>
like image 272
bdobry Avatar asked May 12 '16 12:05

bdobry


1 Answers

The reason it is "flickering" is unrelated to the pseudo-element; it's because you are partially overlaying the .box-content element over the .box elements so, when you move your mouse, it is no longer hovering over the .box element that triggered the .box-content element to display, rather it is hovering over the .box-content element itself so it disappears. Move your mouse again and it's hovering over the .box element once more, triggering .box-content to display again. To fix this, simply add a :hover pseudo-class to the .box-content element, like so:

.outer {
  width: 100%;
  height: 300px;
  position: relative;
}
.box {
  width: 150px;
  height: 60px;
  border: 3px solid black;
  position: absolute;
  z-index: 1;
}
.box:after {
  content: '';
  background-color: grey;
  z-index: -1;
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
}
.box:hover ~ .box-content {
  display: inline-block;
}
.box p {
  color: white;
  padding: 10px;
  z-index: 1000;
}
.box-content {
  display: none;
  width: 80%;
  height: 80%;
  border: 3px solid black;
  position: absolute;
  left: 10%;
  top: 11%;
}
.box-content:after {
  content: "";
  background-color: grey;
  z-index: 2;
  display: block;
  position: absolute;
  width: 20%;
  height: 30%;
  left: 0;
  top: 0;
}
.box-content:hover {
  display: inline-block;
}
.box-two {
  top: 0;
  right: 0;
}
.box-three {
  bottom: 0;
  left: 0;
}
.box-four {
  bottom: 0;
  right: 0;
}
<div class="outer">
  <div class="box">
    <p>BOX NAME 1</p>
  </div>
  <div class="box box-two">
    <p>BOX NAME 2</p>
  </div>
  <div class="box box-three">
    <p>BOX NAME 3</p>
  </div>
  <div class="box box-four">
    <p>BOX NAME 4</p>
  </div>
  <div class="box-content"></div>
</div>

Alternatively, if you do not wish .box-content to remain visible while hovering over it but not hovering over one of the .box elements then add the pointer-events property to .box-content, like so:

.outer {
  width: 100%;
  height: 300px;
  position: relative;
}
.box {
  width: 150px;
  height: 60px;
  border: 3px solid black;
  position: absolute;
  z-index: 1;
}
.box:after {
  content: '';
  background-color: grey;
  z-index: -1;
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
}
.box:hover ~ .box-content {
  display: inline-block;
}
.box p {
  color: white;
  padding: 10px;
  z-index: 1000;
}
.box-content {
  display: none;
  width: 80%;
  height: 80%;
  border: 3px solid black;
  position: absolute;
  left: 10%;
  top: 11%;
}
.box-content:after {
  content: "";
  background-color: grey;
  z-index: 2;
  display: block;
  position: absolute;
  width: 20%;
  height: 30%;
  left: 0;
  top: 0;
  pointer-events: none;
}
.box-two {
  top: 0;
  right: 0;
}
.box-three {
  bottom: 0;
  left: 0;
}
.box-four {
  bottom: 0;
  right: 0;
}
<div class="outer">
  <div class="box">
    <p>BOX NAME 1</p>
  </div>
  <div class="box box-two">
    <p>BOX NAME 2</p>
  </div>
  <div class="box box-three">
    <p>BOX NAME 3</p>
  </div>
  <div class="box box-four">
    <p>BOX NAME 4</p>
  </div>
  <div class="box-content"></div>
</div>

Note, though, that Opera Mini doesn't support pointer-events and IE only added support in v11.

like image 99
Shaggy Avatar answered Nov 17 '22 18:11

Shaggy