Emulate Inspector highlight on hover

Viewed 58

I am trying to emulate the Chrome/Firefox Inspector Highlighting effect using just CSS. I can achieve it relatively well but...

If a child element is hovered, its parent is highlighted aswell. Do you know how I can fix this? In the below example hover over the header and you will see pretty much everything is highlighted. Only the header should be red.

*:hover {
  position: relative;
}

*:hover::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255,0,0,0.25);
}
<main style="height: 600px; position: relative;">
  <header style="height: 100px;">Title</header>
  
  <footer style="height: 100px; position: absolute; bottom: 0; width: 50%;">Footer</footer>
</main>

1 Answers

One approximation is to consider the other pseudo element to hide the one of the parent element:

html *:hover {
  position: relative;
}

html *:hover::after {
  content: "";
  position: absolute;
  z-index:-99;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 0, 0, 0.25);
  opacity: .7;
}
html *:hover::before {
  content: "";
  position: fixed;
  z-index:-99;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #fff;
}
/* increase the order of each child to make it cover the parent*/
html *:hover *::before,
html *:hover *::after{
  z-index:-98;
}
html *:hover * *::before,
html *:hover * *::after{
  z-index:-97;
}
html *:hover * * *::before,
html *:hover * * *::after{
  z-index:-96;
}
html *:hover * * * *::before,
html *:hover * * * *::after{
  z-index:-95;
}
/* and so on ...*/
html * {
  outline: 1px solid red;
  padding:15px;
  box-sizing:border-box;
}
<main style="height: 600px; position: relative;">
  <header style="height: 100px;">Title</header>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a sollicitudin ligula. Phasellus ipsum tellus, interdum in nisl volutpat, vulputate aliquet massa. Ut non vulputate nisi, elementum faucibus mauris. Nam elementum non nisl sit amet mattis. Pellentesque consequat commodo rhoncus. Qu</p>
  <footer style="height: 100px; position: absolute; bottom: 0; width: 50%;">Footer</footer>
</main>

This is not a robust solution since any use of z-index or other properties in the document may break the trick:

html *:hover {
  position: relative;
}

html *:hover::after {
  content: "";
  position: absolute;
  z-index:-99;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 0, 0, 0.25);
  opacity: .7;
}
html *:hover::before {
  content: "";
  position: fixed;
  z-index:-99;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #fff;
}
/* increase the order of each child to make it cover the parent*/
html *:hover *::before,
html *:hover *::after{
  z-index:-98;
}
html *:hover * *::before,
html *:hover * *::after{
  z-index:-97;
}
html *:hover * * *::before,
html *:hover * * *::after{
  z-index:-96;
}
html *:hover * * * *::before,
html *:hover * * * *::after{
  z-index:-95;
}
/* and so on ...*/
html * {
  outline: 1px solid red;
  padding:15px;
  box-sizing:border-box;
}
<main style="height: 600px; position: relative;z-index:0;"> <!-- added a z-index here -->
  <header style="height: 100px;">Title</header>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a sollicitudin ligula. Phasellus ipsum tellus, interdum in nisl volutpat, vulputate aliquet massa. Ut non vulputate nisi, elementum faucibus mauris. Nam elementum non nisl sit amet mattis. Pellentesque consequat commodo rhoncus. Qu</p>
  <footer style="height: 100px; position: absolute; bottom: 0; width: 50%;">Footer</footer>
</main>

You can fix the z-index issue by forcing them to auto but you may have other side effects:

html *:hover {
  position: relative;
  z-index:auto!important;
}

html *:hover::after {
  content: "";
  position: absolute;
  z-index:-99;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 0, 0, 0.25);
  opacity: .7;
}
html *:hover::before {
  content: "";
  position: fixed;
  z-index:-99;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #fff;
}
/* increase the order of each child to make it cover the parent*/
html *:hover *::before,
html *:hover *::after{
  z-index:-98;
}
html *:hover * *::before,
html *:hover * *::after{
  z-index:-97;
}
html *:hover * * *::before,
html *:hover * * *::after{
  z-index:-96;
}
html *:hover * * * *::before,
html *:hover * * * *::after{
  z-index:-95;
}
/* and so on ...*/
html * {
  outline: 1px solid red;
  padding:5px;
}
html * {
  outline: 1px solid red;
  padding:15px;
  box-sizing:border-box;
}
<main style="height: 600px; position: relative;z-index:0;"> <!-- added a z-index here -->
  <header style="height: 100px;">Title</header>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a sollicitudin ligula. Phasellus ipsum tellus, interdum in nisl volutpat, vulputate aliquet massa. Ut non vulputate nisi, elementum faucibus mauris. Nam elementum non nisl sit amet mattis. Pellentesque consequat commodo rhoncus. Qu</p>
  <footer style="height: 100px; position: absolute; bottom: 0; width: 50%;">Footer</footer>
</main>

Related