1

I'm trying to create an overlay effect when hovering on a <li> element inside a <ul>.
I want this element to be common to every <li>.

My first idea was to put an additional element, like a <div>, inside the list.
Sketchy example:

<ul>
    <li></li>
    <li></li>
    <li></li>
    <div></div>
</ul>
ul div {
   opacity: 0
}
li:hover ~ div {
   opacity: 1
}

However, we can't put any tag inside a <ul> other than a <li>, because it would be considered invalid markup.

Since there is no way to select the parent of an element, is there any way to resolve this issue using CSS only?

Azametzin
  • 4,342
  • 12
  • 22
  • 38
  • 1
    you can wrap the div into an li or use an empty li with and id or a class . li ~ li.myLast. it can also be a pseudo li:hover::after – G-Cyrillus Jan 10 '20 at 19:40
  • Would a tooltip effect serve your needs? Tooltip libraries are everywhere. I'm sorta curious if your use case is actually unique such that a tooltip wouldn't suffice. – Marc Jan 10 '20 at 19:42
  • 2
    But your HTML isn't valid. The `div` can't be a direct child of `ul`. – putvande Jan 10 '20 at 19:44
  • @G-Cyr I had also considered the last (empty) li, but that would cause a lot of changes to my CSS because it's using too many li selectors. But I consider this solution a lot to do what I need, I think probably in the end it will be this one. – Azametzin Jan 10 '20 at 19:52
  • @Marc Not really, but thank you. – Azametzin Jan 10 '20 at 19:58

2 Answers2

2

You can use :before and :after pseudo elements if your needs are simple.

If you are trying to use a child element to select a parent element, that is not curently possible: Is there a CSS parent selector?

Minimal Example:

li:hover:after{
  display:inline-block;
  content:"pseudo element";
  background-color:#ccc;
}
<ul>
    <li>aaa</li>
    <li>bbb</li>
    <li>ccc</li>
</ul>

Extended example with some attribute defined text:

ul li:hover:before, li:hover:after{
  display:inline-block;
  position:absolute;
  float:right;
  content:attr(data-myMessage);
  animation-duration: 250ms;
  animation-name: slidein;
  margin-left: 0;
  background-color:#bada55;
}

li:hover:after{
  animation-name: slideinleft;
  opacity:0%;
  margin-left: -1rem;
}

@keyframes slidein {
  from {
    margin-left: 10rem;
    opacity:0%;
  }

  to {
    margin-left: 0rem;
    opacity:100%;
  }
}

@keyframes slideinleft {
  from{
    margin-left: -10rem;
    opacity:0%;
  }
  
  to {
    margin-left: -1rem;
    opacity:100%;
  }
 
}
<ul>
    <li data-myMessage="message">aaa</li>
    <li data-myMessage="something">bbb</li>
    <li data-myMessage="bottle">ccc</li>
</ul>
Tank
  • 996
  • 6
  • 17
  • Not exactly what I'm trying to do, but thank you for the response. Yes, unfortunately it is not possible at the current state of CSS. – Azametzin Jan 11 '20 at 00:26
0

You can use background color on :hover pseudo class. You can also use :before and/or :after as well.

Abhijit Sil
  • 131
  • 3