sol
sol

Reputation: 22949

How to target li:before and link when hover over link?

I have an ol with custom numbering using :before.

Each li contains an a.

CODEPEN DEMO

HTML

<ol>
  <li><a href="#">Sample text</a></li>
  <li><a href="#">Sample text</a></li>
  <li><a href="#">Sample text</a></li>
</ol>

When a user hovers over the link I want both the link and the custom number to change colour.

Problem:

Because the :before belongs to the parent (the li), hover events on the link can't target it.

Attempted solution:

I created a hover effect on the li instead. But this allows a hover that is outside of the link to cause a change in colour (i.e. not directly over it).

Changing the li to display: inline-block messes up the formatting.

Is there a simple way to change the colour of both the link and the pseudoelement when the link is hovered over?

The HTML can be easily amended if necessary.

Snippet

body {
  width: 700px;
  margin: 0 auto;
}
pre {
  background-color: lightgrey;
  padding: 4px;
}

ol {
  list-style: none;
  counter-reset: item;
}

ol li {
  margin-left: 2em;
}

.inline li{
  display: inline-block;
}

ol li:before {
  display: inline-block;
  content: counter(item) " ";
  counter-increment: item;
  margin-left: -2em;
  width: 2em;
}

a {
  color: #000;
  text-decoration: none;
}

li:hover {
  color: red;
}

li:hover a {
  color: red;
}
<p><pre>display: block</pre> - causes hover effect outside of link </p>
<ol>
  <li><a href="#">Sample text</a></li>
  <li><a href="#">Sample text</a></li>
  <li><a href="#">Sample text</a></li>
</ol>
<hr />
<p><pre>display: inline-block</pre> - organises list in a row
<ol class="inline">
  <li><a href="#">Sample text</a></li>
  <li><a href="#">Sample text</a></li>
  <li><a href="#">Sample text</a></li>
  <li><a href="#">Sample text</a></li>
  <li><a href="#">Sample text</a></li>
</ol>

Upvotes: 1

Views: 1019

Answers (2)

Kristen Vogler
Kristen Vogler

Reputation: 357

I would suggest moving the :before from your "ol li" css to your "a" selector. From:

ol li:before {
display: inline-block;
content: counter(item) " ";
counter-increment: item;
margin-left: -2em;
width: 2em;
}

To:

a:before {
display: inline-block;
content: counter(item) " ";
counter-increment: item;
margin-left: -2em;
width: 2em;
}

Then instead of worrying about selecting a part of the li on a hover you can simply use a:hover and it will change both the number and the text of your link.

Upvotes: 1

Banzay
Banzay

Reputation: 9470

You can use a little trick with li that has a display: block:

 width: 0;
 white-space: nowrap;

Look at snippet:

body {
  width: 700px;
  margin: 0 auto;
}
pre {
  background-color: lightgrey;
  padding: 4px;
}

ol {
  list-style: none;
  counter-reset: item;
}

ol li {
  margin-left: 2em;
  width: 0;
  white-space: nowrap;
}

ol li:before {
  display: inline-block;
  content: counter(item) " ";
  counter-increment: item;
  margin-left: -2em;
  width: 2em;
}

a {
  color: #000;
  text-decoration: none;
}

li:hover {
  color: red;
}

li:hover a {
  color: red;
}
<p><pre>display: block</pre> - doesn't cause hover effect outside of link </p>
<ol>
  <li><a href="#">Sample text</a></li>
  <li><a href="#">Sample text</a></li>
  <li><a href="#">Sample text</a></li>
</ol>

Upvotes: 1

Related Questions