NateW
NateW

Reputation: 2121

Hide only direct text children, not element children in CSS

I have a ul list and would like to hide all the text that is not inside an anchor. This is markup from a CMS so I can't add in additional selectors...

<ul class="list">
  <li class="sub">
    <a href="#">link</a> not linked
  </li>
</ul>

I have tried using the following css but it doesn't work.

.list .sub:not(a) {
  display: none;
}

Why doesn't this work?

Jsfiddle: http://jsfiddle.net/9tg0g44e/

Upvotes: 0

Views: 996

Answers (1)

BoltClock
BoltClock

Reputation: 724142

.sub:not(a) matches any element with the class .sub if it's not an a element.

Since the .sub here is a li, it's not an a, so that hides the li and all its contents.

Normally, to select any children of .sub that aren't a elements, you'd use .sub > :not(a) instead, but since the other text is a direct sibling of the a element you won't be able to target it with a selector.

Instead of using display: none, you can use the visibility property instead:

.list .sub {
  visibility: hidden;
}

.list .sub a {
  visibility: visible;
}

But note that this will also hide the bullet because it's part of the li element and cannot be targeted separately. If you need the bullet to be shown, you can replace it with a :before pseudo-element, which works slightly differently from an actual list marker:

.list .sub {
  list-style: none;
  visibility: hidden;
}

.list .sub:before, .list .sub a {
  visibility: visible;
}

.list .sub:before {
  content: '\2022';
}

Upvotes: 7

Related Questions