CSS :last-child Pseudo Class
Learn how the CSS :last-child pseudo-class works, how it differs from :last-of-type, and see practical examples for lists, tables, and forms.
The CSS :last-child pseudo-class selects an element that is the last child of its parent — meaning the final sibling in its parent's child list. It is most often used to remove a trailing border between list items, reset a bottom margin on the last paragraph, or highlight the final row in a table.
This page covers how :last-child is evaluated, the critical rule that catches most developers off guard, how it compares with :last-of-type, and several runnable examples.
How :last-child works
The selector p:last-child does not mean "the last <p> in the parent." It means "a <p> that is also the very last child of its parent." Position is checked first; tag name is checked second.
/* Matches the <p> ONLY when it is the final child of its parent */
p:last-child {
font-weight: bold;
}Consider this markup:
<div>
<p>Paragraph — NOT selected.</p>
<span>I am the last child, so the rule above never fires.</span>
</div>Because <span> is the last child, p:last-child matches nothing here. To target the last <p> regardless of what follows it, use :last-of-type instead.
:last-child is the mirror image of :first-child. For counting from the end (e.g., second-to-last), use :nth-last-child().
In Selectors Level 3, the matched element was required to have a parent. Selectors Level 4 relaxes this: :last-child can now match a root element that has no parent.
Syntax
selector:last-child {
/* declarations */
}:last-child can be combined with any element selector, class, or ID:
li:last-child { border-bottom: none; } /* last <li> in its parent */
.card:last-child { margin-bottom: 0; } /* last element with class .card */
tr:last-child td { font-weight: bold; } /* cells in the last table row */Basic example: paragraphs
The two paragraphs below are both children of <body>. p:last-child matches only the second one because it is the final child of its parent.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
p:last-child {
background-color: #1c87c9;
color: #ffffff;
}
</style>
</head>
<body>
<h2>Last-child selector example</h2>
<p>Lorem ipsum is simply dummy text...</p>
<p>Lorem Ipsum is simply dummy text...</p>
</body>
</html>List example: styling the last <li>
li:last-child applies to the last <li> inside each <ul> or <ol> independently — nested lists each get their own last child.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
li:last-child {
background: #1c87c9;
color: #ffffff;
}
</style>
</head>
<body>
<h2>:last-child selector example</h2>
<ul>
<li>Paris</li>
<li>Moscow</li>
<li>Rome</li>
</ul>
<ol>
<li>Paris</li>
<li>Moscow</li>
<li>Rome</li>
</ol>
</body>
</html>Multiple paragraphs inside a container
When four <p> elements are siblings inside the same parent, only the fourth one matches p:last-child.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
p:last-child {
background: #8ebf42;
color: #ffffff;
}
</style>
</head>
<body>
<h2>:last-child selector example</h2>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<p>Paragraph 3</p>
<p>Paragraph 4</p>
</body>
</html>Nested lists
:last-child applies independently at each nesting level. In the example below, "List Item 3" is the last child of the outer <ul>, and "List Item 3.3" is the last child of the inner <ul>.
<!DOCTYPE html>
<html>
<head>
<style>
ul li {
color: #8ebf42;
}
ul li:last-child {
border: 1px dotted #8ebf42;
color: #1c87c9;
}
</style>
</head>
<body>
<h2>:last-child selector example</h2>
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>
List Item 3
<ul>
<li>List Item 3.1</li>
<li>List Item 3.2</li>
<li>List Item 3.3</li>
</ul>
</li>
</ul>
</body>
</html>Common use cases
Removing a trailing separator
A classic pattern: add a dividing border to every item, then remove it from the last one so the group doesn't end with a dangling line.
.menu li {
border-bottom: 1px solid #ccc;
padding: 8px 0;
}
/* Remove the bottom border from the final item */
.menu li:last-child {
border-bottom: none;
}This is more maintainable than adding a class manually to the last <li>, because the selector adapts automatically when items are added or removed.
Removing margin from the last paragraph
Content blocks often need spacing between paragraphs but not after the last one — otherwise the paragraph's margin doubles up with the container's padding.
.content p {
margin-bottom: 1rem;
}
.content p:last-child {
margin-bottom: 0;
}Styling the last row of a table
table tr:last-child td {
font-weight: bold;
border-bottom: 2px solid #333;
}This highlights the totals row in a summary table without adding a class to the HTML.
:last-child vs :last-of-type
These two selectors are frequently confused. The key difference:
| Selector | What it checks |
|---|---|
p:last-child | Is this <p> the last child of its parent (by position)? |
p:last-of-type | Is this <p> the last <p> among its siblings (by type, ignoring other elements)? |
<div>
<p>Paragraph 1</p>
<p>Paragraph 2</p> <!-- p:last-of-type matches here -->
<span>A span</span> <!-- this is the last child -->
</div>p:last-child→ matches nothing (the last child is a<span>, not a<p>).p:last-of-type→ matches "Paragraph 2" (the last<p>among siblings).
Use :last-child when position matters. Use :last-of-type when only the element type matters.
Specificity
:last-child is a pseudo-class, so it contributes 0-1-0 to specificity — the same as a class selector. Combined selectors stack normally:
li:last-child /* specificity: 0-1-1 (type + pseudo-class) */
.list li:last-child /* specificity: 0-2-1 (class + type + pseudo-class) */Browser support
:last-child is supported in every modern browser (Chrome, Firefox, Safari, Edge) and has been since IE 9. No vendor prefix or fallback is needed.
Specification
Related selectors
:first-child— selects the first child of its parent.:last-of-type— selects the last element of a given type, ignoring other element types between siblings.:only-child— selects an element that is the sole child of its parent.:nth-last-child()— selects elements counting from the end using a formula.:nth-child()— selects elements counting from the start using a formula.