-1

I have been working on a dropdown menu that now works. Just one strange thing is happening that I can't explain/don't understand. Here is a relevant piece of the code:

<ul>
  <li><p>Music Theory 1&nbsp;&nbsp;&nbsp;</p></li>
  <li><p>&lt;&nbsp;&nbsp;&nbsp;&nbsp;</p><a href="#" id="lesson">Music Alphabet</a>
     <ul>
        <li><a id="l0" class="lesnitem" href="#">Piano Keyboard</a></li>
        <li><a id="l1" class="lesnitem" href="#">Note Types</a></li>
    ...

Notice the absence of the closing "li" tag on the second "li" If I put it in, the behavior changes drastically. the inner "ul" is no longer hidden and it is laid out differently (across instead of down), so the absence is affecting the CSS, but I don't see it.

I guess I'm Ok with leaving it out, but it grates on me. Could this have something to do with the inner "a" tag?

Can anyone help me understand this?

Liam
  • 27,717
  • 28
  • 128
  • 190
John Hard
  • 21
  • 4

2 Answers2

3

The end tag for a <li> is optional. If you don't put it in explicitly it will be automatically inserted before the next <li> or </ul> (or </ol>).

If you insert it manually before the <ul> then you are moving the nested <ul> so it is no longer inside the <li>.

Instead, you try to create the <ul> as a child element of another <ul> which is forbidden in HTML.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
2

You've got a nested list -- that is, a list inside of another list. The way you do this is that you create a new list inside of a list item of the parent list. This is commonly used for "sub menus" in CSS drop downs.

Example:

<ul>
  <li>First Item</li>
  <li>Second Item</li>
  <li>Third item with a sub list
    <ul>
      <li>Sub item 1</li>
      <li>Sub item 2</li>
    </ul>
  </li>
</ul>

What is commonly done with CSS menus is that the sub list is "hidden" using CSS (eg. by applying display: none) and then when you hover over the containing list item, it is displayed.

Here's an example of a very rudimentarily styled menu using this structure:

#submenu ul {
  display: none;
}

#submenu:hover ul {
  display: block;
}

ul li {
  cursor: pointer;
}
<ul>
  <li>First Item</li>
  <li>Second Item</li>
  <li id="submenu">Submenu (hover to show)
    <ul>
      <li>Submenu item 1</li>
      <li>Submenu item 2</li>
    </ul>
  </li>
</ul>

Note, of course, that </li> is an optional tag. You can create a list like this:

<ul>
  <li>First Item
  <li>Second Item
</ul>

What your browser will do is guess at where the closing tag should be and implicitly insert it there. In this case, it is inserting the closing tag after the word "item" in both of those list items.

It is, of course, considered good practice to explicitly close all of your tags.


To specifically answer your questions:

Could this have something to do with the inner "a" tag?

No. This has nothing to do with your "a" tags. As mentioned </li> is technically optional.

But in the case of the code you posted, you're using a nested list setup, not relying on the optional-ness of the closing tag. I can say this assertively because if you had actually closed that li tag that has the sub-list in it, you'd have a ul as a child of a ul, which is not allowed.

Can anyone help me understand this?

Hopefully the above did so. But to summarize:

  1. The </li> tag is technically optional. You don't have to use it, but it's good practice to always close your HTML tags.
  2. The presence of the anchor tags inside of the list items is irrelevant.
  3. In the specific example you posted, you have a nested list or sub-list; this is done by putting a new list inside of an <li> tag.
Roddy of the Frozen Peas
  • 14,380
  • 9
  • 49
  • 99