htmlcssz-indexpseudo-element

Unexpected z-order of <div> and its ::before


I have two overlapping dots from a div and its ::before and want the left/main dot to appear ON TOP of the right/pseudo dot.

div, div::before {
  width: 12px;
  height: 12px;
  border: 2px solid white;
  border-radius: 100%;
  background-color: red;
}
div {
  position: relative;
  z-index: 1;
  left: -11px;
  transform: translateX(5px);
}
div::before {
  content: '';
  position: absolute;
  z-index: -1;
  top: -2px;
  left: 9px;
  background-color: blue;
}
<div></div>

Due to both being positioned relative or absolute, I would have expected the different z-index values to cause the left/main dot to appear ON TOP of the right/pseudo dot (which is what I want).

(There is a reason I need the main dot to be on the left, so I'd rather not switch main/pseudo.)


Solution

  • What about using transform-style: preserve-3d on the div and transform: translateZ(-1px)on the before?

    div, div::before {
      width: 12px;
      height: 12px;
      border: 2px solid white;
      border-radius: 100%;
      background-color: red;
    }
    div {
      position: relative;
      left: -11px;
      transform: translateX(5px);
      transform-style: preserve-3d;
    }
    div::before {
      content: '';
      position: absolute;
      top: -2px;
      left: 9px;
      background-color: blue;
      transform: translateZ(-1px);
    }
    <div></div>