JavaScriptDOM and events

Element.children

A live collection of an element’s direct children. Together with parentElement and nextElementSibling, it’s used for moving around the DOM tree.

Returns
A live HTMLCollection with the child elements (it can be empty). The other properties return an element, or null.
On this page

Example

#
JavaScript
const modules = document.querySelector('#modules')
const current = modules.querySelector('.current')

console.log(modules.children.length)
console.log(modules.children[0].textContent)
console.log(current.nextElementSibling.textContent)
console.log(current.parentElement)
console.log(modules.lastElementChild.nextElementSibling)
Console
3
Intro
Attributes
<ul id="modules">
null

Definition and usage

#

The children property returns an HTMLCollection with the element’s direct children, that is, elements nested one level down. It skips text nodes and comments, so whitespace and newlines from the HTML code don’t get in the way. You read the number of children from children.length, and a specific child by index, e.g. list.children[0].

The collection is “live”: when you add or remove a child, the change shows up in children right away. It has no array methods like map() or forEach(), but you can easily turn it into an array with Array.from() or [...element.children].

A whole family of properties is used for moving around the tree: parentElement points to the parent, firstElementChild and lastElementChild to the first and last child, and nextElementSibling and previousElementSibling to neighboring elements at the same level. When there’s no such element, you get null.

Watch out for similar names without the word “Element”: childNodes, firstChild, or nextSibling return every node, including text ones. That’s usually not what you’re looking for.

Syntax

#
Syntax
element.children
element.children.length
element.children[index]

element.parentElement
element.firstElementChild
element.lastElementChild
element.nextElementSibling
element.previousElementSibling

More examples

#
children versus childNodes
JavaScript
const tasks = document.querySelector('#tasks')

console.log(tasks.children.length)
console.log(tasks.childNodes.length)
console.log(tasks.firstChild.nodeName)
console.log(tasks.firstElementChild.nodeName)
Console
2
5
#text
LI

childNodes also counts three text nodes holding the newlines and indentation between tags. firstChild points to the first of them, and firstElementChild to the first <li> element.

A live collection and converting it to an array
JavaScript
const ranking = document.querySelector('#ranking')
const items = ranking.children

const newPlayer = document.createElement('li')
newPlayer.textContent = 'Mia'
ranking.append(newPlayer)

console.log(items.length)
console.log([...items].map((li) => li.textContent))
console.log(typeof items.map)
Console
3
['Emma', 'Jack', 'Mia']
undefined

The items variable was captured before Mia was added, yet it still sees three elements. The collection has no map() method, so we convert it to an array first.

Moving to the next tab
JavaScript
const tabs = document.querySelector('#tabs')

function move(step) {
  const active = tabs.querySelector('.active')
  const next =
    step > 0
      ? active.nextElementSibling ?? tabs.firstElementChild
      : active.previousElementSibling ?? tabs.lastElementChild

  active.classList.remove('active')
  next.classList.add('active')
  console.log('Active tab:', next.textContent)
}

move(1)
move(1)
move(-1)
Console
Active tab: JS
Active tab: HTML
Active tab: JS

Past the last tab, nextElementSibling returns null, so the ?? operator moves the selection back to the start. It works the same way in the other direction.

Browser support

#

Widely available

Works in all modern browsers, phones included. You can use it without worry.

  • Chrome
  • Edge
  • Firefox
  • Safari

Good practices

#
  • Choose properties with the word “Element” (firstElementChild, nextElementSibling). The versions without it (firstChild, nextSibling) often return a text node with whitespace.
  • When removing children in a loop over children, make a copy first: [...list.children]. The collection is live, and indexes shift after every removal, so some elements would get skipped.
  • closest() is more convenient than repeated parentElement for finding an ancestor that matches a selector.

Related entries

#

Spotted a mistake or missing an example? Write to us.