CSS :first-child Pseudo-Class
The CSS :first-child pseudo-class selects an element that is the first element child of its parent. It is commonly used to style the first item in a list, the first row in a group, or the first element inside a container without adding a separate class to the HTML.
:first-child Syntax
:first-child {
property: value;
}
The :first-child pseudo-class does not accept arguments. It matches an element when that element is the first element child of its parent.
Example Syntax
li:first-child {
font-weight: bold;
}
This rule makes the first list item in each list bold.
The :first-child pseudo-class has a specificity of 0-1-0. Combined with the li type selector, its specificity becomes 0-1-1.
Using a Parent Selector
.menu > li:first-child {
color: #0088cc;
}
This rule selects the first element child of .menu only when that child is an <li>. The child combinator (>) prevents the rule from selecting list items inside nested lists.
How :first-child Works
The browser examines the order of element children within a parent. The first element child matches :first-child, regardless of its HTML element type.
Text nodes, whitespace, and comments are not counted when determining which element is the first child.
Expected Matching Behavior
| Condition | Matches :first-child? |
|---|---|
| First element child of a parent | Yes |
| Second element child of a parent | No |
| Only element child of a parent | Yes |
| First paragraph after a heading sibling | No |
| First element after a comment | Yes |
| First element after whitespace text | Yes |
| First element hidden with display: none | Yes |
The selector responds to changes in the document structure. If JavaScript inserts a new element before the current first child, the new element becomes the matching element.
Important: The :first-child pseudo-class is based on the element's position among all element siblings, not only siblings of the same type.
Elements That Match :first-child
The :first-child pseudo-class can match any HTML element that is the first element child of its parent.
First List Item
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
li:first-child {
color: #0088cc;
font-weight: bold;
}
Only the HTML list item matches because it is the first element child of the list.
First Paragraph
<div class="content">
<p>First paragraph.</p>
<p>Second paragraph.</p>
</div>
.content p:first-child {
color: #27ae60;
}
The first paragraph matches because it is the first element child of the container.
Paragraph After a Heading
<article>
<h2>Introduction</h2>
<p>First paragraph.</p>
<p>Second paragraph.</p>
</article>
article p:first-child {
color: #0088cc;
}
Neither paragraph matches because the heading is the first element child of the article. The first paragraph is the second element child.
Comments and Whitespace
<div>
<!-- Section content -->
<p>First paragraph.</p>
<p>Second paragraph.</p>
</div>
The first paragraph still matches :first-child. The comment and whitespace do not affect the order of element children.
Nested Elements
<div class="groups">
<ul>
<li>HTML</li>
<li>CSS</li>
</ul>
<ul>
<li>JavaScript</li>
<li>PHP</li>
</ul>
</div>
.groups li:first-child {
font-weight: bold;
}
Both HTML and JavaScript become bold because each is the first element child of its own list. The selector is evaluated separately for each parent.
:first-child vs. :first-of-type
The :first-child and :first-of-type pseudo-classes differ in how they evaluate an element's position among siblings.
Comparison
| Pseudo-Class | Matching Behavior |
|---|---|
:first-child |
Matches an element only if it is the first element child of its parent. |
:first-of-type |
Matches an element if it is the first sibling of its element type. |
HTML
<article>
<h2>CSS Selectors</h2>
<p>First paragraph.</p>
<p>Second paragraph.</p>
</article>
CSS
article p:first-child {
color: #0088cc;
}
article p:first-of-type {
font-weight: bold;
}
The p:first-child rule matches nothing because the heading is the first element child. The p:first-of-type rule matches the first paragraph because it is the first <p> among its siblings.
Use :first-child when the element must appear first among all element children. Use :first-of-type when only its position among siblings of the same element type matters.
Related Selectors
Several structural pseudo-classes select elements based on their position within a parent.
Structural Selector Comparison
| Selector | Description |
|---|---|
:first-child |
Matches the first element child. |
:last-child |
Matches the last element child. |
:only-child |
Matches an element that has no element siblings. |
:nth-child(1) |
Matches the first element child, equivalent to :first-child. |
:first-of-type |
Matches the first sibling of the same element type. |
:nth-of-type(1) |
Matches the first sibling of the same element type. |
Equivalent First-Child Selectors
li:first-child {
color: #0088cc;
}
li:nth-child(1) {
font-weight: bold;
}
Both selectors match the first element child when that element is an <li>.
Selecting All Except the First Child
.menu > li:not(:first-child) {
border-top: 1px solid #ccc;
}
This rule adds a top border to every direct list-item child of .menu except the first one.
Practical Uses
The :first-child pseudo-class is useful when the first item in a group needs different styling.
Highlighting the First List Item
.feature-list > li:first-child {
font-weight: bold;
color: #0088cc;
}
This rule highlights the first direct list item in a feature list.
Removing Spacing from the First Item
.content-block > *:first-child {
margin-top: 0;
}
This rule removes the top margin from the first element child, regardless of whether it is a heading, paragraph, or another element.
Styling the First Navigation Link
<nav class="main-links">
<a href="#home">Home</a>
<a href="#about">About</a>
<a href="#contact">Contact</a>
</nav>
.main-links > a:first-child {
font-weight: bold;
text-decoration: underline;
}
The Home link receives the special styling because it is the first element child of the navigation container.
Removing the First Item's Border
.item-list > li {
border-top: 1px solid #ccc;
padding: 10px 0;
}
.item-list > li:first-child {
border-top: 0;
}
This pattern creates separators between list items without displaying a border above the first item.
Styling the First Table Row
tbody > tr:first-child {
background-color: #eaf6fc;
}
This rule highlights the first row inside each table body. It does not select rows in the table header.
Best Practices
- Use
:first-childwhen an element must be the first element child of its parent. - Remember that all element types count when determining the first child.
- Use
:first-of-typewhen you need the first sibling of a particular element type. - Use the child combinator (
>) when the rule should apply only to direct children of a specific container. - Remember that comments and whitespace do not affect
:first-childmatching. - Remember that elements hidden with
display: nonestill count as element children. - Use
:not(:first-child)when you need to style all but the first element in a group. - Keep selectors specific enough to avoid affecting nested lists or unrelated containers.
- Remember that JavaScript changes to element order can change which element matches.
- Use a class instead when an element must retain special styling regardless of its position.
:first-child Example
This example highlights the first list item with a blue background and border. Use the buttons to add or remove an item at the beginning of the list and observe how the matching element changes.
HTML
<div class="first-child-demo">
<ul id="demo-list">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
<button type="button" id="add-item">Add First Item</button>
<button type="button" id="remove-item">Remove First Item</button>
</div>
CSS
.first-child-demo ul {
list-style: none;
padding: 0;
margin: 0 0 12px;
}
.first-child-demo li {
padding: 9px 12px;
margin-bottom: 5px;
background-color: #f5f5f5;
border-left: 4px solid #ccc;
}
.first-child-demo li:first-child {
background-color: #eaf6fc;
border-left-color: #0088cc;
font-weight: bold;
}
.first-child-demo button {
padding: 7px 10px;
margin: 0 4px 5px 0;
cursor: pointer;
}
JavaScript
const list = document.querySelector("#demo-list");
let itemCount = 1;
document.querySelector("#add-item").addEventListener("click", () => {
const item = document.createElement("li");
item.textContent = "New Item " + itemCount++;
list.prepend(item);
});
document.querySelector("#remove-item").addEventListener("click", () => {
if (list.firstElementChild) {
list.firstElementChild.remove();
}
});
Browser Result
The first list item initially has a blue background and border. Adding a new item at the beginning transfers the styling to that item. Removing the first item transfers the styling to the next item automatically.
Browser Support
Baseline: Widely available. The :first-child pseudo-class has been supported across major browser engines for many years and works in modern versions of Chrome, Edge, Firefox, Safari, and other browsers.
It can be used with ordinary element selectors, class selectors, and combinators without requiring JavaScript.
For current compatibility information, visit Can I Use? .
Specifications
The :first-child pseudo-class is defined in Selectors Level 4 as a structural pseudo-class. It was also defined in earlier CSS selector specifications.
