Are nested HTML lists deprecated? - html

The HTML 4 spec treats the following as a deprecated example (search for "DEPRECATED EXAMPLE"):
<UL>
<LI> ... Level one, number one...
<OL>
<LI> ... Level two, number one...
<LI> ... Level two, number two...
<OL start="10">
<LI> ... Level three, number one...
</OL>
<LI> ... Level two, number three...
</OL>
<LI> ... Level one, number two...
</UL>
Why is this example deprecated?

The start attribute is deprecated in HTML 4 (it is un-deprecated in HTML 5). Everything else about the example is fine.

The spec details the proper way to nest ul and ol elements. They must be encased in an li element, as follows:
<ul>
<li>
<ol>
<li>Hello there</li>
</ol>
</li>
</ul>
However in your example, the lists are not wrapped in an li tag, meaning that it would fail HTML validation.

Related

CSS Nested Ordered Lists Counter Manipulation

I would like to start nested ordered lists with specific numbers while keeping numbering normal (based on the first starting number) for nested list items. Rather than send people down the wrong path and show the numerous versions of scripts I have tried thus far, I am just going to show my desired end state and ask how to get there.
toc.html which is a table of contents would look like (using nested ordered lists):
Table of Contents
1 Introduction
2 Assembly
2.1 Preparation
2.1.1 Space
2.1.2 Tools
2.1.3 Parts
2.2 Assembly
2.2.1 Build It
3 Use
3.1 Defaults
3.2 Customizations
3.2.1 Safety
3.2.1 Insanity
4 Trouble-Shooting
5 Reference
On the assembly.html page, which is what 2 Assembly would point to from the Table of Contents, I would like it to look like this:
Blah blah blah, fake latin goes here.
2 Assembly
2.1 Preparation
2.1.1 Space
2.1.2 Tools
2.1.3 Parts
2.2 Assembly
2.2.1 Build It
Body of this page, along with more fake latin, goes here.
And on use.html I would want it to look like:
Blah blah blah, fake latin goes here.
3 Use
3.1 Defaults
3.2 Customizations
3.2.1 Safety
3.2.1 Insanity
Body of this page, along with more fake latin, goes here.
How do I accomplish this using only HTML and CSS? I do not want javascript or anything other than HTML and CSS. My file structure is:
/css/main.css
/toc.html
/assembly.html
/use.html
/trouble-shooting.html
/reference.html
Declare the li elements as block-elements. Then you can make use of the conter-resetattribute and re-add the counter through pseudo-elements:
ol {
counter-reset: item;
}
li {
display: block;
}
li:before {
content: counters(item, ".") " ";
counter-increment: item;
}
<ol>
<li>Introduction</li>
<li>Assembly
<ol>
<li>Preparation
<ol>
<li>Space</li>
<li>Tools</li>
<li>Parts</li>
</ol>
</li>
<li>Assembly
<ol>
<li>Build It</li>
</ol>
</li>
</ol>
</li>
<li>Use
<ol>
<li>Defaults</li>
<li>Customizations
<ol>
<li>Safety</li>
<li>Insanety</li>
</ol>
</li>
</ol>
</li>
<li>Trouble-Shooting</li>
<li>Reference</li>
</ol>
It was my hope there would be some way to nest counters, or to force a counter to only reset the initial count item. Based on the answer from #tacoshy in which he states that a server-sided solution like PHP is required to call a counter listing from a database, and that there is no other easy HTML and CSS solution, I decided to just use a garbage workaround. For sure there is a more elegant way to do this:
I created items within CSS which I could use to hide things.
li.hideme {
visibility:hidden;
}
#coverup01 {
position:relative;
top: -60px;
}
#coverup02 {
position:relative;
top: -75px;
}
Then, I used the basic HTML CSS solution for nested ordered lists, and added the references to the above. On the assembly.html page I did this:
<ol>
<li class="hideme">Introduction</li>
<span id="coverup01">
<li>Assembly
<ol>
<li>Preparation
<ol>
<li>Space</li>
<li>Tools</li>
<li>Parts</li>
</ol>
</li>
<li>Assembly
<ol>
<li>Build It</li>
</ol>
</li>
</ol>
</li>
<li>Use
<ol>
<li>Defaults</li>
<li>Customizations
<ol>
<li>Safety</li>
<li>Insanity</li>
</ol>
</li>
</ol>
</li>
<li>Trouble-Shooting</li>
<li>Reference</li>
</span>
</ol>
And on the use.html page I did this:
<ol>
<li class="hideme">Introduction</li>
<li class="hideme">Assembly</li>
<span id="coverup02">
<li>Use
<ol>
<li>Defaults</li>
<li>Customizations
<ol>
<li>Safety</li>
<li>Insanity</li>
</ol>
</li>
</ol>
</li>
<li>Trouble-Shooting</li>
<li>Reference</li>
</span>
</ol>
The coverup01 and coverup02 ID selectors are just for my own use, to pull the visible list up. If you expect a solid responsive design with this, you will want to edit each screen size accordingly. This works for a small list. For a larger list, this may be cumbersome.
This returned the results I was trying to find. I did not want to use garbage code, but if there is no supported solution, then a workaround must suffice for now.
As I am typing this ... I may be able to put the coverup stuff into the li.hideme class, which would simplify things considerably. Not sure if CSS allows for positioning invisible objects, but we shall see [pun]....
This is the solution I have used, and it seems to be working just fine.

Why does this HTML not have a closing <li> tag? [duplicate]

This question already has answers here:
Does the <li> tag in HTML have an ending tag?
(4 answers)
Closed 4 years ago.
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 </p></li>
<li><p>< </p>Music Alphabet
<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?
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.
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:
The </li> tag is technically optional. You don't have to use it, but it's good practice to always close your HTML tags.
The presence of the anchor tags inside of the list items is irrelevant.
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.

displaying html lists in a tree-like row-like fashion

I have a list
<ul>
<li> first article </li>
<li> second article</li>
<ul>
<li> replies to second</li>
<li> different reply to second</li>
</ul>
<li> third article</li>
<ul>
<li> reply to third</li>
<ul>
<li> reply to the reply</li>
</ul>
</ul>
</ul>
Which begets something like
first article
second article
replies to second
different reply to second
third article
reply to third
reply3
reply3
reply to the reply
What i'm trying to achieve is basically make every inner level it's own row:
[first article]
[second article]
[rep2] [difrep2]
[third article]
[reply3] [reply3] [reply3]
[^3reply to the reply]
The problem is: when I put a box around list elements, the box contains the parent and all the descendent/inner elements. I want a box around the list element, and I would like the children to appear on a new "row"
Is there any way to "kick" the inner list elements out of their parent's css box so that they appear on a new "row" ?
https://jsfiddle.net/qjf6tsf8/1/
^Update: please check out this fiddle.
In the fiddle "yet another child" has children elements, and I'd like to put them in a new row below "yet another child" instead of recursively boxing them up.
For reference: https://jsfiddle.net/qjf6tsf8/ (js fiddle showing the tree structure with just li and ul elements, and then the upper link I've changed them to divs)
First off, according to W3C HTML Validator, any <ul> cannot be the direct child of a <ul>.
So this structure
<ul>
<li> first article </li>
<li> second article</li>
<ul>
<li> replies to second</li>
<li> different reply to second</li>
</ul>
...
Should actually be
<ul>
<li> first article </li>
<li> second article
<ul>
<li> replies to second</li>
<li> different reply to second</li>
</ul>
</li>
...
This actually makes your issue less difficult to resolve.
See https://jsfiddle.net/tae2e7ea/.
The important part is below. Use display: block to put the child <ul> on its own line, then display: inline-block for the <li> children.
/* <ul> that are children of <li> should be on their own line */
li > ul {
display: block;
}
/* And the children of those <ul> should be all on one line */
li > ul > li {
display: inline-block;
}
Edit for additional info: See the fiddle for some additional styles you may need to set on the <li> (like vertical-align: center) or <ul> (like padding-left: 0)
Edit after clarifications from asker: Since 100% width is desired and this control is being handled with JavaScript (AngularJS), I recommend organizing by levels in the tree instead of maintaining the tree-like structure you started with. See this Fiddle for that update. JavaScript can then be used to show/hide the necessary levels. Or rather, AngularJS should be used to only render the lists for the "chosen" level.
i think this will work
ul > ul
{
display : inline-flex ;
}
I think you have not decided to display items correctly yet. Because you have think of levels differently in a way that can not be common for all levels. For clarity pay attention to item replies to second. What if it had some children?! You can add a class name like .same-row to every item you want to be displayed in a same row and add fallowing style to your page:
.same-row{
display: inline;
}

Proper way to make HTML nested list?

The W3 docs have a nested list example prefixed by DEPRECATED EXAMPLE:, but they never corrected it with a non-deprecated example, nor explained exactly what is wrong with the example.
So which of these ways is the correct way to write an HTML list?
Option 1: the nested <ul> is a child of the parent <ul>
<ul>
<li>List item one</li>
<li>List item two with subitems:</li>
<ul>
<li>Subitem 1</li>
<li>Subitem 2</li>
</ul>
<li>Final list item</li>
</ul>
Option 2: the nested <ul> is a child of the <li> it belongs in
<ul>
<li>List item one</li>
<li>List item two with subitems:
<ul>
<li>Subitem 1</li>
<li>Subitem 2</li>
</ul>
</li>
<li>Final list item</li>
</ul>
Option 2 is correct.
The nested list should be inside a <li> element of the list in which it is nested.
Link to the W3C Wiki on Lists (taken from comment below): HTML Lists Wiki.
Link to the HTML5 W3C ul spec: HTML5 ul. Note that a ul element may contain exactly zero or more li elements. The same applies to HTML5 ol.
The description list (HTML5 dl) is similar,
but allows both dt and dd elements.
More Notes:
dl = definition list.
ol = ordered list (numbers).
ul = unordered list (bullets).
Official W3C link (updated).
Option 2
<ul>
<li>Choice A</li>
<li>Choice B
<ul>
<li>Sub 1</li>
<li>Sub 2</li>
</ul>
</li>
</ul>
Nesting Lists - UL
Option 2 is correct: The nested <ul> is a child of the <li> it belongs in.
If you validate, option 1 comes up as an error in html 5 -- credit: user3272456
Correct: <ul> as child of <li>
The proper way to make HTML nested list is with the nested <ul> as a child of the <li> to which it belongs. The nested list should be inside of the <li> element of the list in which it is nested.
<ul>
<li>Parent/Item
<ul>
<li>Child/Subitem
</li>
</ul>
</li>
</ul>
W3C Standard for Nesting Lists
A list item can contain another entire list — this is known as "nesting" a list. It is useful for things like tables of contents, such as the one at the start of this article:
Chapter One
Section One
Section Two
Section Three
Chapter Two
Chapter Three
The key to nesting lists is to remember that the nested list should relate to one specific list item. To reflect that in the code, the nested list is contained inside that list item. The code for the list above looks something like this:
<ol>
<li>Chapter One
<ol>
<li>Section One</li>
<li>Section Two </li>
<li>Section Three </li>
</ol>
</li>
<li>Chapter Two</li>
<li>Chapter Three </li>
</ol>
Note how the nested list starts after the <li> and the text of the containing list item (“Chapter One”); then ends before the </li> of the containing list item. Nested lists often form the basis for website navigation menus, as they are a good way to define the hierarchical structure of the website.
Theoretically you can nest as many lists as you like, although in practice it can become confusing to nest lists too deeply. For very large lists, you may be better off splitting the content up into several lists with headings instead, or even splitting it up into separate pages.
If you validate , option 1 comes up as an error in html 5, so option 2 is correct.
I prefer option two because it clearly shows the list item as the possessor of that nested list. I would always lean towards semantically sound HTML.
Have you thought about using the TAG "dt" instead of "ul" for nesting lists? It's inherit style and structure allow you to have a title per section and it automatically tabulates the content that goes inside.
<dl>
<dt>Coffee</dt>
<dd>Black hot drink</dd>
<dt>Milk</dt>
<dd>White cold drink</dd>
</dl>
VS
<ul>
<li>Choice A</li>
<li>Choice B
<ul>
<li>Sub 1</li>
<li>Sub 2</li>
</ul>
</li>
</ul>
What's not mentioned here is that option 1 allows you arbitrarily deep nesting of lists.
This shouldn't matter if you control the content/css, but if you're making a rich text editor it comes in handy.
For example, gmail, inbox, and evernote all allow creating lists like this:
With option 2 you cannot do that (you'll have an extra list item), with option 1, you can.

Is there a way to group `<li>` elements?

I need to divide into groups several <li> elements in a list, is it possible?
(I know I an give each element different class names/separate into different <ul>)
Have you considered nested UL's? I believe this would validate:
<UL>
<LI>
<UL>
<LI></LI>
<LI></LI>
<LI></LI>
</UL>
</LI>
<LI>
<UL>
<LI></LI>
<LI></LI>
<LI></LI>
<LI></LI>
<LI></LI>
</UL>
</LI>
</UL>
Your CSS trick was my first guess; too bad you can't use that.
According to the XHTML schema (or one the schema anyway), the only thing you put inside a <ul> is a <li>, as described at http://www.w3.org/TR/2006/WD-xhtml-modularization-20060705/abstract_modules.html#s_listmodule
You might tweak the appearance of the list items using CSS, by assigning different class values to the <li> elements.
<li class="group1"> ...
<li class="group1"> ...
<li class="group1"> ...
<li class="group2"> ...
<li class="group2"> ...
<li class="group2"> ...
Have you considered using multiple-inheritance of CSS classes? This can be a bit messy to maintain, but it will solve the case of the same entry in multiple groups. The HTML looks something like this:
<ul class="pizza-toppings">
<li class="meat">pepperoni</li>
<li class="meat">bacon</li>
<li class="vegetarian">cheese</li>
<li class="vegetarian vegan">mushrooms</li>
<li class="vegetarian vegan">onions</li>
</ul>
Here we have three groups (meat, vegetarian and vegan) and some toppings, like mushrooms and onions, are part of more that one group.
I believe your only options are the ones you've already identified, multiple lists or via classes, since for an li to be in the list defined by a ul or an ol, it must be the immediate child of that ul/ol (reference).
If you need to separate into different groups items from one unordered list than they should belong to different lists isn't it OR should be grouped in an ordered list (many ULs in one OL).
If this is for presentation needs (to display one list on many columns) and you can solve a few constraints, the second technique in https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5810687.html or explained also here : http://www.communitymx.com/content/article.cfm?page=2&cid=27F87
Such groups exist for select (optgroup) but obviously you can't separate the option elements because you must select only one of them so they should belong to the same element.