Is there any HTML element that I can use to wrap other elements to use as a placeholder? For example,
<ul>
<placeholder id="list-placeholder">
<li>item 1</li>
<li>item 2</li>
</placeholder>
<li>last item</li>
</ul>
Then I'd be able to access #list-placeholder via JavaScript and append children to it.
I don't think I can use <div> because divs aren't valid in all contexts (such as a list); furthermore, they may be inadvertently styled (I want my placeholder to be invisible).
Browsers don't render the contents of <template> whereas I do want to render what's inside my placeholder
Likewise, <script> tags with a custom type don't render their contents either
No, in HTML, there is no general wrapper element—which is what this is really about. What comes closest is ins and del elements, which can wrap both inline and block elements and have transparent content model. But even they are not allowed e.g. as a child of a ul element.
Instead of trying to use a wrapper e.g. for some li elements in order to apped children to it, set an id attribute on the last of the li elements in question and insert siblings after it. This is more natural in terms of DOM, since then all the li elements will be children of ul, instead of being partly children, partly grandchildren.
According to W3, only a <li> can be a child of a <ul>, therefore, the answer to your question is no. There is not a valid way to wrap two <li>s that are children of a <ul>.
If you have to, you could use a <span>. I have created an example, while not valid, this runs correctly in all modern browsers.
Example snippet and some proof below:
function showList(){
document.getElementById('list-placeholder').style.display = "block";
document.getElementById('showList').style.display = "none";
}
<ul>
<span id="list-placeholder" style="display:none;">
<li>item 1</li>
<li>item 2</li>
</span>
<li>last item</li>
</ul>
<input type="button" value="Show more list items!" onclick="showList()"/>
If you don't HAVE TO use a wrapper, you can and should use the following VALID code:
function showList(){
var hidden = document.getElementsByClassName('hidden')
for (i=0; i<hidden.length; i++){
hidden[i].style.display = "list-item";
}
document.getElementById('showList').style.display = "none";
}
.hidden
{
display:none;
}
<ul>
<li class="hidden">item 1</li>
<li class="hidden">item 2</li>
<li>last item</li>
</ul>
<input type="button" value="Show more list items!" id="showList" onclick="showList()"/>
Use a class to select hidden items instead of a wrapper. That's the correct syntax for your question.
Also, there are set <script> types, just like there are set <input> types (text, button, radio, checkbox, range, etc.). That is why you should specify the type, so the browser understands your code.
Hope this helps!
Related
Here is a simplified version of my code. It is not possible to place the fourth list item inside the "my_list" element in my project for some difficult to explain reason. Therefore, I need some other way to make HTML understand that it is supposed to be part of the same list.
Obviously the belongsTo attribute does not exist, but something like that would be nice in this case.
<ul id="my_list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
...
... (other content)
...
<li belongsTo="my_list">item 4</li>
EDIT:
to specify, I am looking for the same effect you would get from:
<form id="my_form">
<!-- (form content) -->
<form>
<input form="my_form">
you could technically do it exactly like you suggested inventing an attribute like that but if you want the dom to know that list item to be part of the above collection you are expected to run a javascript on document load that will append such element to the real list.
This is an example of page that will run a js on document ready and will move every element found with the attribute data-belongsto inside the expected parent:
document.addEventListener('DOMContentLoaded', ()=>{
const belongsToElements = document.querySelectorAll('*[data-belongsto]');
for(let el of belongsToElements){
const belongsTo = el.dataset.belongsto;
const parent = document.getElementById(belongsTo);
parent.appendChild(el);
}
})
<ul id="my_list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
...
... (other content)
...
<li data-belongsTo="my_list">item 4</li>
I try to tidy the following html code, and I get an strange result. li elements are not aligned.
Is it correct to have al ul tag and text inside an a
<a> Text Inside a
<ul>
<li>li1 content</li>
<li>li2 content</li>
<li>li3 content</li>
</ul>
</a>
Why It could happens?
ul tag is a block element tag - a tag is a inline-block element tag - it is not recommended to put block elements within inline-block elements.
If you had a basic navigation it would look like
<nav>
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
</nav>
As explained earlier - within the ul tag you can assign the a tags to navigate to other links/webpages.
The accepted ways of providing indentation to your code is by using 2-space or 4-space indentation (Every time you open a child tag in the next line give it 2/4 space ). Although in HTML indentation does not matter, your code will work perfectly fine with whatever way you wish to do indentation.
tidy code (2-space indentation):
<a href="Link_to_anything"> Text Inside a
<ul>
<li>li1 content</li>
<li>li2 content</li>
<li>li3 content</li>
</ul>
</a>
I have added href attribute , as the purpose of the <a> tag is to link the contents inside to another web page or part of a web page
DEFINITION:
The <a> tag defines a hyperlink, which is used to link from one page to another. The most important attribute of the element is the href attribute, which indicates the link's destination.
The anchor tag can hold most tags inside it like <img>, <p>, <h1> to <h6>,etc. You can perfectly add <ul> tag within the <a> tag
I have a two-sided mobile menu drawer that relies on a hidden checkbox for switching/toggling between its two sides.
There are two LABEL elements, one on each side of the menu drawer. Each LABEL, via its FOR attribute, references the ID of the hidden INPUT checkbox. Clicking a displayed LABEL thus checks the INPUT checkbox and causes the menu to switch sides (via CSS). A distillation of the HTML is:
<ul class=main-menu>
<li>
<input id=toggle-drawer type=checkbox title="hidden checkbox">
<label for=toggle-drawer>See Sub Menu</label>
<ul class=sub-menu>
<li>
<label for=toggle-drawer>See Main Menu</label>
</li>
<li>Sub-menu item 1</li>
<li>Sub-menu item 2</li>
<li>Sub-menu item 3</li>
</ul>
</li>
<li>Main Menu item 1</li>
<li>Main Menu item 2</li>
<li>Main Menu item 3</li>
</ul>
It is, in fact, perfectly valid HTML to have multiple labels that reference the same input item.
See https://www.w3.org/TR/html401/interact/forms.html#h-17.9.1 :
"More than one LABEL may be associated with the same control by
creating multiple references via the for attribute."
However, the WebAIM WAVE (Web Accessibility Evaluation Tool) browser extension flags the two labels as an error, stating,
"A form control should have at most one associated label element. If
more than one label element is associated to the control, assistive
technology may not read the appropriate label."
As a remedy, it goes on to state:
"If multiple form labels are necessary, use aria-labelledby."
aria-labelledby seems not to apply to my case, as it would be put on an INPUT item that is referenced by a DIV, etc.
Is there an ARIA or similar mark-up method I can use to satisfy this accessibility audit? I do not wish to alter my HTML structure.
Although it is perfectly valid HTML, having two labels will cause issues with NVDA and possibly other screen readers where it will only read one label.
This is why WAVE suggests you use aria-labelledby as that is designed to take multiple elements and can combine them (in the order you list them).
It is perfectly valid to use this on an input, also note that aria-labelledby will override any associated <label> elements using for="id"
One thing you could do is use the less often used aria-describedby to associate the second label and ensure that the reading order is correct.
In the example below it would read 'See Main Menu, See Sub Menu' as it will read the <label for="toggle-drawer"> first and then use the aria-describedby="toggle-drawer-label" to add additional information.
The only down side is that it may read the input information in between the <label> and the describedby label.
<ul class=main-menu>
<li>
<input id="toggle-drawer" aria-describedby="toggle-drawer-label" type=checkbox title="hidden checkbox">
<label id="toggle-drawer-label">See Sub Menu</label>
<ul class=sub-menu>
<li>
<label for="toggle-drawer">See Main Menu</label>
</li>
<li>Sub-menu item 1</li>
<li>Sub-menu item 2</li>
<li>Sub-menu item 3</li>
</ul>
</li>
<li>Main Menu item 1</li>
<li>Main Menu item 2</li>
<li>Main Menu item 3</li>
</ul>
The recommended way
I would recommend simply using aria-labelledby="label1 label2" as that is the accepted method and will result in the most consistent results, obviously it means you need to add id attributes to both labels so that is the trade off.
Note that using aria-labelledby="label1 label2" and associating the fields with for="toggle-drawer" on both labels has the added benefit of correctly linking the labels so that you can click on either label and it will focus the <input>.
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.
I know that <ul> is the common tag used to display <li> item, but when i read here, it shows how the <output> tag also can be used to display the <li> item.
Currently in my project, i'm using <output> tag to display list items instead of <ul>, and i want to know if that is a wrong thing to do? I've read the <output> description, and i understood that <output> tag was supposed to display mathematical result, yet it can be used to display list, as shown in the link above.
I worried that my approach of using <output> to display list is wrong, though the result i got from it is just the way i want it to be.. can someone enlighten me the the difference between <output> and <ul> in terms of displaying a list items on page?
The example you linked outputs the following:
<output id="list">
<ul>
<li>Something</li>
</ul>
</output>
The li are not direct children of the output element, which is where I think you may be getting confused.
The output element is merely meant for outputting the result of a form action (calculation, or in the case of the example you linked, a file upload).
On whatwg.org there is no mention of the output element being a list, so if you're going to be trying to output li eleemnts to it, make sure they're going inside a ul.
the <li> elements can be included anywhere, <output> and <ul> are just tags that are used to designate areas of the page used for various forms of content. In general, if it's a list, use a list with <ul> or <ol>.
Note: <output> is used for automatic calculations and would behave strangely in a <form>.
For <output>
It shows the results of the calculation
<form oninput="result.value=parseInt(a.value)+parseInt(b.value)">
0<input type="range" name="b" value="50" />100 +
<input type="number" name="a" value="10" /> =
<output name="result"></output>
</form>
While in <ul>
It is unordered list and it shows the list in unordered form i.e in meaningless form
<ul>
<li>first item</li>
<li>second item <!-- Look, the closing </li> tag is not placed here! -->
<ol>
<li>second item first subitem</li>
<li>second item second subitem</li>
<li>second item third subitem</li>
</ol>
</li>
<li>third item</li>
</ul>
This is a misunderstanding. The proposed output element in HTML drafts allows phrase content (text-level content) only, so it cannot contain a li element or a ul element, even syntactically.