How the CSS :only-child Pseudo-Class Works

The CSS :only-child pseudo-class allows developers to apply styles to an element only when it has no sibling elements inside its parent container. This article explains how the :only-child selector functions, how it evaluates the Document Object Model (DOM), practical use cases for user interface design, and how it differs from related structural selectors.

Understanding the Mechanics of :only-child

The :only-child pseudo-class represents any element that is the sole child of its parent element. In terms of specificity and functional equivalence, selecting element:only-child produces the exact same result as writing element:first-child:last-child or element:nth-child(1):nth-last-child(1).

Consider the following HTML structure:

<div class="container">
  <p>I am all alone.</p>
</div>

<div class="container">
  <p>First paragraph.</p>
  <p>Second paragraph.</p>
</div>

With the following CSS rule:

p:only-child {
  color: crimson;
  font-weight: bold;
}

Only the paragraph in the first .container receives the crimson color and bold weight. The paragraphs in the second .container are ignored because they share a parent and are siblings to one another.

How :only-child Evaluates Siblings

To determine whether an element qualifies for :only-child, the browser checks for the presence of sibling element nodes.

  • Other Element Types Count as Siblings: If an element is surrounded by different HTML elements, it will not match :only-child. For example, in <div><h1>Title</h1><p>Text</p></div>, neither the <h1> nor the <p> matches :only-child because they are siblings of each other, despite being different tags.
  • Text Nodes and Comments Are Ignored: The selector exclusively counts element nodes. Plain text, empty whitespace, or HTML comments alongside the target element do not prevent it from matching.

Practical Use Cases

Using :only-child eliminates the need to apply extra helper classes via JavaScript or server-side templates when handling dynamic content. Common UI applications include:

  1. Auto-expanding Lonely Elements: In a responsive grid or card list, if an API returns only a single item, you can make that item take up the full container width:

    .card:only-child {
      grid-column: 1 / -1;
      max-width: 100%;
    }
  2. Hiding Unnecessary Separators: When rendering lists that use borders or bullets between items, :only-child can remove unnecessary spacing or dividers:

    .list-item:only-child {
      border-bottom: none;
      margin-bottom: 0;
    }
  3. Centering Solo Buttons: If a modal dialog or alert box contains two buttons, they might be spaced out across the dialog. If only one confirmation button is rendered, it can be automatically centered:

    .button-group .btn:only-child {
      margin: 0 auto;
    }

:only-child vs. :only-of-type

It is common to confuse :only-child with :only-of-type.

  • :only-child is strict about having no sibling elements whatsoever. If any other element shares the parent, the selector fails.
  • :only-of-type is element-type specific. It matches an element if no other siblings share the same HTML tag, even if other types of siblings are present.

For example, in <main><h1>Title</h1><p>Body</p></main>, the <p> does not match p:only-child because the <h1> is an element sibling. However, the <p> does match p:only-of-type because it is the only paragraph element inside <main>.