First Child

Master the CSS :first-child pseudo-class to target and style the first element among siblings without additional HTML classes

Introduction

The :first-child pseudo-class represents an element that is the first child of some other element. This fundamental CSS selector enables developers to target and style the initial element within a parent container without adding additional classes or IDs. Understanding how :first-child works is essential for creating polished, maintainable stylesheets that handle common layout patterns efficiently.

Unlike JavaScript-based approaches that require runtime DOM manipulation, :first-child operates entirely at the CSS level, allowing browsers to apply styles during the rendering process. This native CSS solution provides better performance and requires less code compared to manual class assignment for every first child element across a website. Efficient CSS selectors are a key component of web performance optimization, as they reduce the computational overhead of style calculations during page rendering.

The :first-child selector belongs to the structural pseudo-class family, which also includes :last-child, :nth-child(), :nth-last-child(), :first-of-type, :last-of-type, :nth-of-type(), and :nth-last-of-type(). These selectors provide powerful ways to target elements based on their position within their parent, reducing the need for presentational classes in HTML markup.

How :first-child Works

What Is a Pseudo-Class?

A pseudo-class is a keyword added to selectors that specifies a special state of the targeted element. Unlike regular classes that you define in CSS or add to HTML attributes, pseudo-classes are built into CSS and target elements based on their state, position, or relationship to other elements. The colon (:) notation distinguishes pseudo-classes from regular classes in CSS syntax.

Pseudo-classes enable dynamic styling based on user interaction (like :hover and :focus), element state (like :checked and :disabled), and structural position (like :first-child and :nth-child()). The :first-child pseudo-class specifically targets elements that are the first child of their parent container, regardless of what type of element they are.

Matching Behavior

The :first-child pseudo-class matches an element that is the first child element of its parent element. The matched element must literally be the first child, meaning no other elements (text nodes, comments, or elements) precede it within the parent container. This distinction is important: whitespace and text nodes do not count as elements, but they can affect whether another element is considered the "first" in some contexts.

Matching Example:

<div>
 <p>I am the first paragraph</p>
 <p>I am the second paragraph</p>
</div>

The first <p> element matches p:first-child because it is the first child of the <div>. The second <p> does not match because it has a sibling <p> before it.

Non-Matching Example:

<div>
 <h2>Title Heading</h2>
 <p>I am not first child</p>
</div>

The <p> element does not match p:first-child even though it is the first paragraph. It is the second child element, with the <h2> preceding it. To target this paragraph, you would use :first-of-type instead.

Text Node Consideration:

<div>
 Some text before the element
 <p>I am not first child</p>
</div>

The <p> is not a first child because the text node before it counts as preceding content. Modern browsers typically ignore whitespace-only text nodes, but actual text content can affect first-child matching.

Browser Evaluation Process

When the browser's CSS selector matching engine encounters a selector like .menu li:first-child, it first identifies all li elements within .menu, then filters to only those li elements that are the first child of their immediate parent. This filtering happens for every element on the page during both initial rendering and subsequent style recalculations. Optimizing CSS selector performance is a core aspect of professional web development services that deliver fast, responsive websites.

Syntax and Usage

The syntax for :first-child follows standard CSS pseudo-class conventions. You write the selector pattern followed by :first-child, then the declaration block containing your style rules.

Basic Syntax

/* Make the first paragraph in any container bold */
p:first-child {
 font-weight: 700;
}

/* Add a top border to the first list item */
ul li:first-child {
 border-top: 2px solid #333;
}

/* Style the first child of any div */
div > :first-child {
 padding-top: 1rem;
}

Complex Selector Patterns

Descendant Combinator: The space character (descendant combinator) matches elements anywhere within the specified ancestor. This approach is useful when you need to target first children within nested structures.

/* First list item in any unordered list within article */
article ul li:first-child {
 font-weight: bold;
 padding-top: 0.5rem;
}

/* First paragraph in any section */
section p:first-child {
 font-size: 1.25rem;
 color: #333;
}

Child Combinator (>): The child combinator (>) matches only direct children, not grandchildren or deeper descendants. This creates more specific targeting and can improve performance by limiting the search scope.

/* Direct first child of article */
article > :first-child {
 margin-top: 0;
}

/* First child paragraph directly inside card */
.card > p:first-child {
 background-color: #f5f5f5;
}

Adjacent Sibling Combinator (+): The adjacent sibling combinator (+) matches an element that immediately follows another element. Combined with :first-child, this creates patterns for styling elements that follow the first child.

/* Element that follows a first-child paragraph */
p:first-child + p {
 margin-top: 1rem;
}

/* List item that follows the first list item */
li:first-child + li {
 border-top: 1px solid #ddd;
}

Combining with Classes and IDs:

/* First child with specific class */
.card-list .card:first-child {
 border-left: 3px solid #0066cc;
}

/* First child with ID */
#main-content > :first-child {
 padding: 1.5rem;
}

Universal Selector Combination

The universal selector (*) combined with :first-child targets any element that is the first child of its parent, regardless of element type:

/* Any first child element */
.container > :first-child {
 background-color: #f9f9f9;
}

Related Pseudo-Classes

:first-of-type Explained

The :first-of-type pseudo-class targets the first element of its type among siblings, which differs from :first-child in a crucial way. While :first-child requires the element to be the absolute first child regardless of type, :first-of-type selects the first occurrence of each element type within a parent container.

In a container with headings and paragraphs mixed together, :first-child would only match whichever element appears first (heading or paragraph), while :first-of-type would match both the first heading and the first paragraph separately. This allows for different styling of different element types at the "top" of a content section.

:first-child vs :nth-child()

The :nth-child() pseudo-class extends the concept of position-based selection by accepting arguments that specify which child elements to target. You can use keywords like even and odd, or mathematical expressions like 2n+1 to create patterns. The :first-child selector is essentially equivalent to :nth-child(1), though :first-child is more readable and semantically clear for this common case.

:last-child

The :last-child pseudo-class mirrors :first-child but targets the final element among siblings rather than the first. Together, these two selectors enable common patterns like removing borders or spacing from the first and last items in a list.

Comparison Table

SelectorMatchesExample ScenarioHTML ExampleMatches
:first-childFirst element regardless of typeFirst child in container<div><p>First</p><p>Second</p></div><p>First</p>
:first-of-typeFirst element of each typeFirst paragraph in mixed content<div><h2>Title</h2><p>First</p></div>Both <h2> and <p>
:last-childLast element regardless of typeFinal item in list<ul><li>First</li><li>Last</li></ul><li>Last</li>
:last-of-typeLast element of each typeLast paragraph in section<section><p>First</p><p>Last</p></section>Both <p> elements
:nth-child(1)Same as :first-childPosition-based equivalent<div><p>First</p></div><p>First</p>
:nth-child(2)Second child elementEvery second element<div><p>1</p><p>2</p></div><p>2</p>
:nth-of-type(1)Same as :first-of-typeType-based equivalent<div><h2>Title</h2><p>First</p></div>Both <h2> and <p>

When to Use Each Selector

  • Use :first-child when you need the absolute first element, regardless of type
  • Use :first-of-type when you want the first paragraph (or heading, etc.) even if other element types precede it
  • Use :nth-child(n) for patterns involving multiple positions (every 2nd, 3rd, etc.)
  • Use :last-child for styling the final element in a container
  • Combine selectors like li:first-child and li:last-child for comprehensive list styling

Performance Considerations

How Browsers Evaluate Selectors

Modern browsers evaluate CSS selectors right-to-left, meaning they start with the right-most selector (the key selector) and work backward through the chain to determine matches. For a selector like ul li:first-child, the browser first identifies all li elements that are first children of their parents, then checks if those elements are contained within ul elements. This right-to-left evaluation makes selector performance dependent primarily on the key selector's specificity and efficiency.

The key selector's efficiency determines much of the overall selector performance. ID selectors are the most efficient because they can quickly resolve to a single element. Class selectors follow, matching a potentially larger set but still relatively efficient. Type selectors (like div or li) are less efficient because they must match every element of that type in the document. Pseudo-classes like :first-child fall somewhere in the middle of the efficiency spectrum--they are generally more expensive than simple class or ID selectors because they require the browser to evaluate the element's position relative to its siblings.

Optimizing Selector Performance

While :first-child is generally performant, avoiding overly complex selector chains involving multiple pseudo-classes can improve rendering speed. The most efficient approach is to use the simplest selector that achieves your styling goals.

Performance Tips:

  1. Keep selector chains short. A selector like div.container ul.menu li:first-child requires the browser to perform multiple checks. Each additional level of specificity adds processing overhead.

  2. Use classes for frequently targeted elements. If you style first children in specific contexts repeatedly, adding a descriptive class like .menu-item-first may be more performant and more explicit.

  3. Avoid the universal selector with :first-child. Selectors like *:first-child force the browser to check every element in the document as a potential first child.

  4. Consider specificity carefully. Higher specificity selectors take longer to match. Balance the need for specificity against performance implications.

  5. Profile before optimizing. Use browser developer tools to identify slow selectors. Most :first-child usage will have negligible performance impact.

When to Use Classes Instead

While :first-child is excellent for many scenarios, there are situations where explicit classes provide better outcomes:

  • Dynamic content: If elements are frequently reordered or added dynamically, :first-child may cause styles to jump around unexpectedly. Classes provide stable targeting.

  • Complex layouts: In layouts with many nested containers, :first-child might match more elements than intended. A class provides explicit control.

  • Maintenance clarity: When other developers work on the codebase, a class like .featured-card is clearer than .card:first-child.

  • Animation transitions: If you want smooth transitions when an element becomes (or ceases to be) the first child, JavaScript class manipulation offers more control than CSS pseudo-classes.

Impact on Rendering Performance

The :first-child pseudo-class has minimal impact on rendering performance in most typical web pages. Modern browsers have highly optimized selector matching engines that can evaluate simple pseudo-class selectors quickly. The performance cost is typically measured in microseconds and is imperceptible to users on standard websites.

The impact becomes more significant when :first-child is combined with other selectors or used extensively throughout a large stylesheet. However, for most practical purposes, using :first-child freely is the recommended approach, with optimization efforts focused on clearly inefficient selectors rather than well-supported standard pseudo-classes. Efficient CSS practices like these contribute to the technical SEO foundation that helps websites achieve better search rankings through faster page load times.

Common Use Cases

Practical applications of the :first-child pseudo-class in modern web design

List Styling Patterns

Remove left padding from first navigation items, add top spacing to first list items, or create visual hierarchy in vertical lists. Essential for navigation menus and breadcrumb trails.

Card and Container Patterns

Style featured cards differently, remove top borders from first sections, or create visual hierarchy in article layouts. Common in grid-based card designs.

Form and Input Patterns

Style the primary submit button differently, remove top borders from first fieldsets, or handle edge cases in form groups for consistent spacing.

Navigation Patterns

Apply special styling to the first navigation item, hide separators before the first item, or create breadcrumb trail styles with proper visual alignment.

List Styling with :first-child
1/* Remove left border from first navigation item */2.nav-links li:first-child {3 border-left: none;4}5 6/* Add top spacing to first list item only */7.feature-list li:first-child {8 margin-top: 2rem;9}10 11/* Style the featured card differently */12.cards .card:first-child {13 grid-column: span 2;14 font-size: 1.1em;15}16 17/* Remove top border from first section */18.section-group > section:first-child {19 border-top: none;20}

Frequently Asked Questions

Conclusion

The :first-child pseudo-class is a fundamental CSS tool that enables position-based styling without requiring additional HTML classes. By targeting the first element among siblings, developers can create polished, professional designs with minimal code. The selector's universal browser support and straightforward syntax make it suitable for production use across all modern websites.

Understanding how :first-child differs from related selectors like :first-of-type and :nth-child() helps developers choose the right tool for each styling challenge. Performance considerations, while generally favorable for :first-child, should inform decisions about selector complexity in large-scale applications.

The :first-child selector exemplifies CSS's power to create adaptive, maintainable styles based on document structure. As web development continues to evolve, selectors like :first-child remain essential tools for creating refined user experiences through pure CSS.

For teams building high-performance websites, mastering :first-child and other structural pseudo-classes is a foundational skill that contributes to clean, efficient stylesheets. Combined with proper web performance optimization techniques, effective use of CSS selectors helps create fast, maintainable websites that deliver excellent user experiences. Our web development services include comprehensive CSS optimization to ensure your website performs at its best.

Ready to Optimize Your Web Performance?

Our team of expert developers can help you implement efficient CSS patterns and build high-performance websites.