HTML <ul>, <ol>, <li> reference
Jump to this section
Common attributes Jump to this section
Basic list structures Jump to this section
HTML provides two main list types: unordered lists (<ul>) for items where order doesn't matter, and ordered lists (<ol>) for sequential or ranked items. Both contain list items (<li>).
- First item
- Second item
- Third item
<ul>
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
</ul>- First step
- Second step
- Third step
<ol>
<li>First step</li>
<li>Second step</li>
<li>Third step</li>
</ol>Ordered list attributes Jump to this section
type Jump to this section
Specifies the numbering style for an ordered list.
Values: 1 (decimal numbers, default), A (uppercase letters), a (lowercase letters), I (uppercase Roman numerals), i (lowercase Roman numerals)
Use when you need alternative numbering styles for different hierarchical levels or stylistic preferences.
- First item
- Second item
- Third item
<ol type="A">
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
</ol>
<!-- Other options -->
<ol type="1"> <!-- 1, 2, 3 (default) -->
<ol type="a"> <!-- a, b, c -->
<ol type="I"> <!-- I, II, III -->
<ol type="i"> <!-- i, ii, iii -->start Jump to this section
Specifies the starting value for an ordered list. Must be an integer, even when using letter or Roman numeral types.
Use when continuing a list after interrupting content, or starting from a specific number in rankings or steps.
- Fifth item
- Sixth item
- Seventh item
<ol start="5">
<li>Fifth item</li>
<li>Sixth item</li>
<li>Seventh item</li>
</ol>
<!-- Works with letter types too -->
<ol type="A" start="3">
<li>C. Third item</li>
<li>D. Fourth item</li>
</ol>reversed Jump to this section
Boolean attribute that reverses the numbering order. The list counts down instead of up.
Use for countdowns, reverse rankings (worst to best), or descending priority lists.
- Third
- Second
- First
<ol reversed>
<li>Third</li>
<li>Second</li>
<li>First</li>
</ol>
<!-- Displays as: 3. Third, 2. Second, 1. First -->List item attributes Jump to this section
value Jump to this section
Sets a specific number for an ordered list item. Subsequent items continue numbering from this value. Only works in <ol> lists.
Use when you need to skip numbers, restart numbering mid-list, or set specific values for individual items.
- First item
- Tenth item
- Eleventh item
- Twelfth item
<ol>
<li>First item</li>
<li value="10">Tenth item</li>
<li>Eleventh item</li>
<li>Twelfth item</li>
</ol>
<!-- Displays as: 1, 10, 11, 12 -->Nested lists Jump to this section
Lists can be nested inside list items to create hierarchical structures. The nested list must be placed inside an <li> element.
Use for table of contents, organizational hierarchies, category/subcategory structures, or multi-level navigation.
- Fruits
- Apples
- Oranges
- Bananas
- Vegetables
- Carrots
- Broccoli
- Spinach
<ul>
<li>Fruits
<ul>
<li>Apples</li>
<li>Oranges</li>
<li>Bananas</li>
</ul>
</li>
<li>Vegetables
<ul>
<li>Carrots</li>
<li>Broccoli</li>
<li>Spinach</li>
</ul>
</li>
</ul>You can also mix list types when nesting:
<ol>
<li>Main topic
<ul>
<li>Bullet point about topic</li>
<li>Another bullet point</li>
</ul>
</li>
<li>Second topic
<ul>
<li>Detail about second topic</li>
</ul>
</li>
</ol>
Accessibility attributes Jump to this section
role Jump to this section
Specifies the semantic role of the element. Lists have implicit roles (list and listitem), but these can be overridden if needed.
Note: Some CSS resets remove list semantics. Explicitly adding role="list" ensures accessibility is maintained.
<ul role="list">
<li role="listitem">Item 1</li>
<li role="listitem">Item 2</li>
</ul>
<!-- Use when list styling is removed -->
<ul style="list-style: none;" role="list">
<li>Item without bullet</li>
</ul>
aria-label Jump to this section
Provides an accessible label for the list when a visible heading isn't present or when you need to clarify the list's purpose.
<ul aria-label="Navigation menu">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
<ul aria-label="Social media links">
<li><a href="#">Twitter</a></li>
<li><a href="#">Facebook</a></li>
</ul>
aria-labelledby Jump to this section
References a heading or label element by its id to provide context for the list. Preferred over aria-label when a visible heading exists.
<h2 id="features-heading">Product Features</h2>
<ul aria-labelledby="features-heading">
<li>Feature 1</li>
<li>Feature 2</li>
<li>Feature 3</li>
</ul>
aria-describedby Jump to this section
References additional descriptive text to provide context or instructions for the list.
<p id="task-instructions">Click items to mark as complete</p>
<ul aria-describedby="task-instructions">
<li>Task 1</li>
<li>Task 2</li>
</ul>
data-* attributes Jump to this section
Custom attributes for storing application-specific data on list elements. Accessible via JavaScript's dataset property.
<ul data-list-type="tasks" data-filter="active">
<li data-task-id="1" data-priority="high" data-status="pending">
Complete project proposal
</li>
<li data-task-id="2" data-priority="low" data-status="completed">
Review meeting notes
</li>
</ul>
<script>
const list = document.querySelector('ul');
console.log(list.dataset.listType); // "tasks"
console.log(list.dataset.filter); // "active"
const firstItem = list.querySelector('li');
console.log(firstItem.dataset.taskId); // "1"
console.log(firstItem.dataset.priority); // "high"
console.log(firstItem.dataset.status); // "pending"
</script>
id Jump to this section
Unique identifier for the list element. Essential for linking with labels, JavaScript selection, and CSS targeting.
<h2>Shopping List</h2>
<ul id="shopping-list">
<li>Milk</li>
<li>Bread</li>
<li>Eggs</li>
</ul>
<script>
const list = document.getElementById('shopping-list');
console.log(list.children.length); // 3
</script>
class Jump to this section
Assigns CSS class names for styling or JavaScript selection. Multiple classes can be applied.
<ul class="feature-list highlighted-list">
<li class="premium-feature">Premium Feature</li>
<li class="basic-feature">Basic Feature</li>
</ul>
<style>
.feature-list { padding: 20px; }
.premium-feature { color: gold; }
</style>
title Jump to this section
Provides tooltip text on hover. Not accessible to keyboard-only users or touch devices, so avoid for critical information.
<ul title="List of available options">
<li>Option 1</li>
<li>Option 2</li>
</ul>
Styling basics Jump to this section
List elements offer extensive styling options. The list-style property controls marker appearance, while flexbox and grid enable modern layouts beyond traditional vertical lists.
List style types Jump to this section
Unordered list markers Jump to this section
- Disc (default)
- Circle
- Square
- None
ul { list-style-type: disc; } /* Default */
ul { list-style-type: circle; }
ul { list-style-type: square; }
ul { list-style-type: none; } /* No marker */Ordered list markers Jump to this section
- Decimal (1, 2, 3)
- Upper Alpha (A, B, C)
- Lower Alpha (a, b, c)
- Upper Roman (I, II, III)
- Lower Roman (i, ii, iii)
ol { list-style-type: decimal; } /* 1, 2, 3 */
ol { list-style-type: upper-alpha; } /* A, B, C */
ol { list-style-type: lower-alpha; } /* a, b, c */
ol { list-style-type: upper-roman; } /* I, II, III */
ol { list-style-type: lower-roman; } /* i, ii, iii */Custom markers Jump to this section
- Checkmark item
- Another item
- Arrow item
- Another item
- Star item
- Another item
ul { list-style-type: '✓ '; }
ul { list-style-type: '→ '; }
ul { list-style-type: '★ '; }
ul { list-style-type: '🎯 '; }List style position Jump to this section
Controls whether markers appear inside or outside the content flow.
- Outside - marker sits outside the content area (default)
- Inside - marker is part of the content flow
ul { list-style-position: outside; } /* Default */
ul { list-style-position: inside; }Reset default styling Jump to this section
- No bullets
- No padding
- No margin
.list-reset {
list-style: none;
padding: 0;
margin: 0;
}Horizontal lists Jump to this section
Basic horizontal list Jump to this section
- Item 1
- Item 2
- Item 3
.horizontal-list {
list-style: none;
padding: 0;
display: flex;
gap: 20px;
}With separators Jump to this section
- Item 1
- Item 2
- Item 3
.separated-list {
list-style: none;
padding: 0;
display: flex;
}
.separated-list li {
padding: 0 15px;
border-right: 1px solid #d1d5db;
}
.separated-list li:last-child {
border-right: none;
}Grid layout Jump to this section
- Item 1
- Item 2
- Item 3
- Item 4
.grid-list {
list-style: none;
padding: 0;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}Styled list examples Jump to this section
Modern checklist Jump to this section
- ✓ Completed task
- ○ Pending task
- ○ Another pending task
.checklist {
list-style: none;
padding: 0;
}
.checklist li {
padding: 12px;
margin-bottom: 8px;
border-left: 3px solid #9ca3af;
border-radius: 4px;
background: #f3f4f6;
}
.checklist li.completed {
background: #f0fdf4;
border-left-color: #16a34a;
}Numbered steps Jump to this section
- 1 First step description
- 2 Second step description
- 3 Third step description
.steps {
list-style: none;
padding: 0;
counter-reset: step;
}
.steps li {
padding: 15px 15px 15px 50px;
margin-bottom: 10px;
background: #eff6ff;
border-radius: 6px;
position: relative;
counter-increment: step;
}
.steps li::before {
content: counter(step);
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
width: 28px;
height: 28px;
background: #3b82f6;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}Card-style list Jump to this section
- Card Item 1 Description text goes here
- Card Item 2 Description text goes here
- Card Item 3 Description text goes here
.card-list {
list-style: none;
padding: 0;
}
.card-list li {
padding: 16px;
margin-bottom: 12px;
background: white;
border: 1px solid #e5e7eb;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
transition: all 0.2s;
}
.card-list li:hover {
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
transform: translateY(-2px);
}Tag/pill list Jump to this section
- JavaScript
- React
- CSS
- HTML
.tag-list {
list-style: none;
padding: 0;
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.tag-list li {
padding: 6px 14px;
background: #dbeafe;
color: #1e40af;
border-radius: 20px;
font-size: 14px;
font-weight: 500;
}Icon list Jump to this section
- ✓ Feature one included
- ✓ Feature two included
- ✓ Feature three included
.icon-list {
list-style: none;
padding: 0;
}
.icon-list li {
padding: 10px 0;
display: flex;
align-items: center;
gap: 12px;
}
.icon-list li::before {
content: '✓';
width: 24px;
height: 24px;
background: #3b82f6;
color: white;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}Divided list Jump to this section
.divided-list {
list-style: none;
padding: 0;
border: 1px solid #e5e7eb;
border-radius: 6px;
overflow: hidden;
}
.divided-list li {
padding: 12px 16px;
border-bottom: 1px solid #e5e7eb;
}
.divided-list li:last-child {
border-bottom: none;
}Custom counters Jump to this section
- Step 1: First instruction
- Step 2: Second instruction
- Step 3: Third instruction
.custom-counter {
list-style: none;
padding: 0;
counter-reset: custom;
}
.custom-counter li {
counter-increment: custom;
padding-left: 60px;
position: relative;
}
.custom-counter li::before {
content: "Step " counter(custom) ":";
position: absolute;
left: 0;
font-weight: bold;
color: #3b82f6;
}Spacing utilities Jump to this section
/* Increase space between items */
.list-spaced li {
margin-bottom: 16px;
}
/* Compact list */
.list-compact li {
line-height: 1.4;
}
/* Add padding to items */
.list-padded li {
padding: 8px 0;
}
JavaScript patterns Jump to this section
List elements are commonly manipulated with JavaScript for dynamic content, filtering, sorting, and interactive features.
Adding list items Jump to this section
Dynamically create and append new items to a list.
- Existing item
const list = document.getElementById('my-list');
// Create new list item
const li = document.createElement('li');
li.textContent = 'New item';
// Add to end of list
list.appendChild(li);
// Add to beginning
list.insertBefore(li, list.firstChild);
// Add at specific position (e.g., 3rd position)
list.insertBefore(li, list.children[2]);
// Add with HTML content
li.innerHTML = '<strong>Bold</strong> item';Removing list items Jump to this section
Remove items individually or clear the entire list.
- Item 1
- Item 2
- Item 3
const list = document.getElementById('my-list');
// Remove specific item
const item = list.children[0];
item.remove();
// Remove all items
list.innerHTML = '';
// Remove with event delegation
list.addEventListener('click', (e) => {
if (e.target.classList.contains('remove-btn')) {
e.target.closest('li').remove();
}
});Toggle completed state Jump to this section
Toggle classes to mark items as complete or incomplete.
- Click to toggle completion
- Another task to complete
- Third task
const list = document.getElementById('task-list');
list.addEventListener('click', (e) => {
if (e.target.tagName === 'LI') {
e.target.classList.toggle('completed');
}
});
// CSS for completed state
// .completed {
// text-decoration: line-through;
// opacity: 0.6;
// background: #dcfce7;
// }Filter list items Jump to this section
Show or hide items based on search input.
- Apple
- Banana
- Cherry
- Date
- Elderberry
- Fig
const input = document.getElementById('filter-input');
const list = document.getElementById('filter-list');
input.addEventListener('input', (e) => {
const filter = e.target.value.toLowerCase();
const items = list.getElementsByTagName('li');
Array.from(items).forEach(item => {
const text = item.textContent.toLowerCase();
if (text.includes(filter)) {
item.style.display = '';
} else {
item.style.display = 'none';
}
});
});Sort list items Jump to this section
Sort items alphabetically or by custom criteria.
- Zebra
- Apple
- Mango
- Banana
- Cherry
function sortList(listId, direction = 'asc') {
const list = document.getElementById(listId);
const items = Array.from(list.children);
items.sort((a, b) => {
const textA = a.textContent.trim();
const textB = b.textContent.trim();
if (direction === 'asc') {
return textA.localeCompare(textB);
} else {
return textB.localeCompare(textA);
}
});
// Re-append sorted items
items.forEach(item => list.appendChild(item));
}
// Sort by custom criteria
function sortByDataAttribute(listId, attribute) {
const list = document.getElementById(listId);
const items = Array.from(list.children);
items.sort((a, b) => {
return a.dataset[attribute] - b.dataset[attribute];
});
items.forEach(item => list.appendChild(item));
}Drag and drop reordering Jump to this section
Enable users to reorder items by dragging.
- ⋮⋮ Drag item 1
- ⋮⋮ Drag item 2
- ⋮⋮ Drag item 3
- ⋮⋮ Drag item 4
const list = document.getElementById('drag-list');
let draggedItem = null;
list.addEventListener('dragstart', (e) => {
draggedItem = e.target;
e.target.style.opacity = '0.5';
});
list.addEventListener('dragend', (e) => {
e.target.style.opacity = '';
});
list.addEventListener('dragover', (e) => {
e.preventDefault();
const afterElement = getDragAfterElement(list, e.clientY);
if (afterElement == null) {
list.appendChild(draggedItem);
} else {
list.insertBefore(draggedItem, afterElement);
}
});
function getDragAfterElement(container, y) {
const draggableElements = [
...container.querySelectorAll('li:not(.dragging)')
];
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect();
const offset = y - box.top - box.height / 2;
if (offset < 0 && offset > closest.offset) {
return { offset: offset, element: child };
} else {
return closest;
}
}, { offset: Number.NEGATIVE_INFINITY }).element;
}Count list items Jump to this section
Track and display the number of items in a list.
- Item 1
- Item 2
- Item 3
const list = document.getElementById('count-list');
const display = document.getElementById('count-display');
function updateCount() {
const count = list.children.length;
display.textContent = `Total items: ${count}`;
}
// Update whenever list changes
const observer = new MutationObserver(updateCount);
observer.observe(list, { childList: true });
// Or manually trigger updates
updateCount(); // Initial countGenerate list from array Jump to this section
Create list items dynamically from data.
- Click button to generate list...
const data = ['Apple', 'Banana', 'Cherry', 'Date'];
const list = document.getElementById('my-list');
// Method 1: createElement
list.innerHTML = ''; // Clear existing
data.forEach(item => {
const li = document.createElement('li');
li.textContent = item;
list.appendChild(li);
});
// Method 2: Template literals
list.innerHTML = data
.map(item => `<li>${item}</li>`)
.join('');
// With data attributes
const items = [
{ id: 1, name: 'Item 1', priority: 'high' },
{ id: 2, name: 'Item 2', priority: 'low' }
];
list.innerHTML = items
.map(item => `
<li data-id="${item.id}" data-priority="${item.priority}">
${item.name}
</li>
`)
.join('');Select/highlight items Jump to this section
Allow users to select items by clicking.
- Click to select item 1
- Click to select item 2
- Click to select item 3
const list = document.getElementById('select-list');
list.addEventListener('click', (e) => {
if (e.target.tagName === 'LI') {
// Remove selected class from all
list.querySelectorAll('li').forEach(item => {
item.classList.remove('selected');
});
// Add to clicked item
e.target.classList.add('selected');
}
});
// Get selected item
function getSelected() {
return list.querySelector('li.selected');
}
// CSS
// .selected {
// background: #dbeafe;
// font-weight: bold;
// }Multi-select with checkboxes Jump to this section
Enable multiple item selection with checkboxes.
- Item 1
- Item 2
- Item 3
- Item 4
const list = document.getElementById('checkbox-list');
// Get all checked items
function getSelected() {
const checkboxes = list.querySelectorAll('input:checked');
return Array.from(checkboxes).map(cb => {
return cb.closest('li').textContent.trim();
});
}
// Select all
function selectAll() {
list.querySelectorAll('input[type="checkbox"]')
.forEach(cb => cb.checked = true);
}
// Deselect all
function deselectAll() {
list.querySelectorAll('input[type="checkbox"]')
.forEach(cb => cb.checked = false);
}
// Toggle all
function toggleAll() {
list.querySelectorAll('input[type="checkbox"]')
.forEach(cb => cb.checked = !cb.checked);
}Pagination Jump to this section
Display large lists across multiple pages.
const data = Array.from({length: 50}, (_, i) => `Item ${i + 1}`);
const itemsPerPage = 5;
let currentPage = 1;
const list = document.getElementById('page-list');
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
const pageInfo = document.getElementById('page-info');
function renderPage() {
const start = (currentPage - 1) * itemsPerPage;
const end = start + itemsPerPage;
const pageData = data.slice(start, end);
list.innerHTML = pageData
.map(item => `<li>${item}</li>`)
.join('');
const totalPages = Math.ceil(data.length / itemsPerPage);
pageInfo.textContent = `Page ${currentPage} of ${totalPages}`;
// Update button states
prevBtn.disabled = currentPage === 1;
nextBtn.disabled = currentPage === totalPages;
}
prevBtn.onclick = () => {
if (currentPage > 1) {
currentPage--;
renderPage();
}
};
nextBtn.onclick = () => {
const totalPages = Math.ceil(data.length / itemsPerPage);
if (currentPage < totalPages) {
currentPage++;
renderPage();
}
};
// Initial render
renderPage();Iterate over items Jump to this section
Loop through list items to read or modify them.
const list = document.getElementById('my-list');
// Using forEach
Array.from(list.children).forEach((item, index) => {
console.log(`Item ${index}: ${item.textContent}`);
});
// Using for...of
for (const item of list.children) {
item.style.color = 'blue';
}
// Using querySelectorAll
list.querySelectorAll('li').forEach(item => {
item.addEventListener('click', () => {
console.log('Clicked:', item.textContent);
});
});
Find specific items Jump to this section
Search for items matching specific criteria.
const list = document.getElementById('my-list');
// Find by text content
const item = Array.from(list.children)
.find(li => li.textContent === 'Search term');
// Find by data attribute
const itemByAttr = list.querySelector('[data-id="123"]');
// Find all matching a condition
const completedItems = Array.from(list.children)
.filter(li => li.classList.contains('completed'));
// Find by custom criteria
const highPriorityItems = Array.from(list.children)
.filter(li => li.dataset.priority === 'high');
