Sean
Sean

Reputation: 1406

Styling list items that do not only contain other lists

I've made a table of contents generator based on the <h1>...<h6> tags within an HTML document. I'm trying to add custom bullet point icons before the resulting sets of lists-within-lists. I managed to get this to work for simple <h1>...<h2>...<h3> progressions by using the li:before CSS selector, but this falls apart for progressions that skip levels, e.g. <h1>...<h3>:

list with unwanted bullet point on empty line

Without the li:before property, the intermediate list doesn't produce a new line:

list without bullet points

This is what I'd like:

list with bullet points only on entries with text

Is there a way to do this, perhaps using some way to select only <li> elements whose first child is <a>? My experience with modern CSS trickery is limited.

Here is a minimal example:

.contents ul {
    list-style-type: none;
    padding: 0;
    margin-left: 15px;
}

.contents ul li:before {
    font-family: 'FontAwesome';
    content: '\f105';
}
<div class="contents">
  <ul> <!-- h1 level -->
    <li>
      <a href="#top-level">Top level</a>
      <ul> <!-- h2 level -->
        <li>
          <ul> <!-- h3 level -->
            <li>
              <a href="#third-level">Third level</a>
            </li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</div>

For reference, I'm using FontAwesome's angle-right icon (interestingly, the example snippet seems to load this font).

Upvotes: 0

Views: 43

Answers (2)

Friday Ameh
Friday Ameh

Reputation: 1684

Change .contents ul li:before to .contents ul li:first-child a:before like this

    
    .contents ul {
        list-style-type: none;
        padding: 0;
        margin-left: 15px;
    }
    
    .contents ul li:first-child a:before  {
        font-family: 'FontAwesome';
        content: '\f105';
    }
    
    
    
    <div class="contents">
      <ul> <!-- h1 level -->
        <li>
          <a href="#top-level">Top level</a>
          <ul> <!-- h2 level -->
            <li>
              <ul> <!-- h3 level -->
                <li>
                  <a href="#third-level">Third level</a>
                </li>
              </ul>
            </li>
          </ul>
        </li>
      </ul>
    </div>
    

Upvotes: 1

Paulie_D
Paulie_D

Reputation: 114990

Expanding on @FridayAmeh's answer to identify only the first li with an anchor and apply the styling to that.

You will require

.contents ul li:first-child > a:before 

Such as...

.contents ul {
  list-style-type: none;
  padding: 0;
  margin-left: 15px;
}

.contents ul li:first-child>a:before {
  font-family: "FontAwesome";
  content: "\f105";
  position: relative;
  margin-left: -.4em;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />
<div class="contents">
  <ul>
    <!-- h1 level -->
    <li>
      <a href="#top-level">Top level</a>
      <ul>
        <!-- h2 level -->
        <li>
          <ul>
            <!-- h3 level -->
            <li>
              <a href="#third-level">Third level</a>
            </li>
            <li>
              <a href="#third-level">Third level</a>
            </li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</div>

Upvotes: 1

Related Questions