How to cancel the inheritance of the "li:before {content: 'text'}" without reassigning it for each <li> element?

171 Views Asked by At

everyone!

The general goal is that all li elements for which a property is not explicitly declared use the standard value.

I don't understand why the content property can't be reset:

ul {
 position: relative;
 list-style: none;
 margin-left: 0;
 padding-left: 1.2em;
}

li:before {
 content: unset;
}

ul > li:before {
 content: "A";
 position: absolute;
 left: 0;
}

ul > ul > li:before {
 content: "B";
 position: absolute;
 left: 0;
}
<ul>
 <li>Level 1 Item 1</li>
 <ul>
  <li>Level 2 Item 1</li>
  <ul>
   <li>Level 3 Item 1</li>
   <li>Level 3 Item 2</li>
   <li>Level 3 Item 3</li>
  </ul>
 </ul>
</ul>

Result:

Actual result: level 3 content is not unset and still shown

But shouldn't the result be like this:

Expected result: level 3 content is unset and hidden

How can I fix this so that the result is the same as in the last picture?

3

There are 3 best solutions below

6
Mir entafaz Ali On

Try adding a class to your ul tags. I made a slight change in your second li selector by removing ul > li > li:before to ul.myClass > li:before. Run the code snippet and you will see your desired output

ul {
 position: relative;
 list-style: none;
 margin-left: 0;
 padding-left: 1.2em;
}

li:before {
 content: unset;
}

ul.myParentClass > li:before {
 content: "A";
 position: absolute;
 left: 0;
}

ul.myClass > li:before {
 content: "B";
 position: absolute;
 left: 0;
}
<ul class="myParentClass">
 <li>Level 1 Item 1</li>
 <ul class="myClass">
  <li>Level 2 Item 1</li>
  <ul>
   <li>Level 3 Item 1</li>
   <li>Level 3 Item 2</li>
   <li>Level 3 Item 3</li>
  </ul>
 </ul>
</ul>

20
BoltClock On

You're unsetting it with a simple li:before selector. That's going to be overridden by your other rules with ul >s, in particular the most specific ul > ul > li:before because it includes your level 3 items (children of the level 2 and level 1 ul elements). You'll need another one of these selectors, nested 3 levels, to unset it for those particular items:

ul {
 position: relative;
 list-style: none;
 margin-left: 0;
 padding-left: 1.2em;
}

ul > li:before {
 content: "A";
 position: absolute;
 left: 0;
}

ul > ul > li:before {
 content: "B";
 position: absolute;
 left: 0;
}

ul > ul > ul > li:before {
 content: unset;
}
<ul>
 <li>Level 1 Item 1</li>
 <ul>
  <li>Level 2 Item 1</li>
  <ul>
   <li>Level 3 Item 1</li>
   <li>Level 3 Item 2</li>
   <li>Level 3 Item 3</li>
  </ul>
 </ul>
</ul>

On a side note, I'd recommend either

  • (recommended) changing :before to ::before since you're writing CSS3 that's not going to work in CSS2-only browsers anyway, or
  • using content: none instead of content: unset, which will allow your code to be supported in CSS2-only browsers, if you care about that
0
isNaN On

This question is generated by my inheritance error. I shouldn't have blamed CSS for my problem. CSS did everything right...

Solution (use the check for the absence of the previous level:not(ul)):

*:not(ul) > ul > ul > li::before {
 content: "B";
 position: absolute;
 left: 0;
}