Question
I have a div element that contains several ul elements.
If I want to apply CSS only to the first ul, this works:
div ul:first-child {
background-color: #900;
}
But when I try to apply CSS to every ul except the first one, I tried the following selectors:
div ul:not:first-child {
background-color: #900;
}
div ul:not(:first-child) {
background-color: #900;
}
div ul:first-child:after {
background-color: #900;
}
These do not seem to work as expected. How do I write a CSS selector that means: "select each element except the first"?
Short Answer
By the end of this page, you will understand how :first-child, :not(), and related CSS selectors work together. You will also learn why :not(:first-child) sometimes appears not to work, how child position is actually calculated, and which selector patterns are best for targeting all elements except the first.
Concept
In CSS, pseudo-classes like :first-child let you select elements based on their position in the DOM. The selector :first-child matches an element only if it is the very first child of its parent.
The :not() pseudo-class excludes elements that match a condition. So this selector:
ul:not(:first-child)
means:
- select every
ul - except those that are the first child of their parent
This is valid CSS.
The important detail is that :first-child does not mean "the first ul". It means "an element that is the first child among all siblings".
So if your HTML looks like this:
<div>
<h2>Title</h2>
<ul>...</ul>
<ul>...</ul>
<ul>...
Mental Model
Imagine children standing in a line inside a room.
:first-childmeans the person standing in position 1, no matter what type of person they are.:first-of-typemeans the first person wearing a specific uniform, such as the firstulamong its siblings.:not(...)means everyone except the people matching the rule inside it.
So:
ul:first-child= aulthat stands in the very first positionul:not(:first-child)= allulelements that are not standing in position 1ul:not(:first-of-type)= allulelements except the firstul
That last one is often what people really mean.
Syntax and Examples
The core selectors are:
/* A ul only if it is the first child of its parent */
ul:first-child {
background: #900;
}
/* Every ul that is not the first child */
ul:not(:first-child) {
background: #900;
}
/* Every ul except the first ul among siblings */
ul:not(:first-of-type) {
background: #900;
}
/* Every ul that directly follows another ul */
ul + ul {
background: #900;
}
Example 1: When :not(:first-child) works
<div>
<ul>First</ul>
<ul>Second</ul>
<ul>Third</ul>
</div>
Step by Step Execution
Consider this HTML:
<div>
<ul>One</ul>
<ul>Two</ul>
<ul>Three</ul>
</div>
And this CSS:
div ul:not(:first-child) {
background-color: #900;
}
Step-by-step
- CSS looks for every
ulinside adiv. - It checks the first
ul:- Is it the first child of its parent? Yes.
- Because of
:not(:first-child), it is excluded.
- It checks the second
ul:- Is it the first child? No.
- It matches, so the style is applied.
- It checks the third
ul:
Real World Use Cases
This selector pattern is common in real layouts where you want repeated items styled differently after the first one.
Common examples
- Add spacing between list sections except before the first one
- Add borders to repeated cards except the first card
- Style navigation items after the first item
- Apply margins to stacked form sections except the top section
- Add separators between content blocks
Example: add spacing between repeated blocks
.section + .section {
margin-top: 24px;
}
This avoids adding unnecessary spacing before the first section.
Example: style every menu except the first
.sidebar ul:not(:first-of-type) {
border-top: 1px solid #ddd;
padding-top: 12px;
}
Example: add a divider between items
.item + .item {
border-top: 1px solid #eee;
}
This is often more maintainable than styling everything and then trying to remove the style from the first item.
Real Codebase Usage
In real projects, developers usually choose the selector that best matches the document structure rather than forcing :not() everywhere.
Common patterns
1. Adjacent sibling selector for spacing
.card + .card {
margin-top: 16px;
}
This is extremely common because it naturally means "every card after the first card".
2. :not(:first-of-type) for repeated tags
article p:not(:first-of-type) {
margin-top: 1rem;
}
Useful when the repeated elements are the same tag type.
3. Utility classes in component systems
.menu-list + .menu-list {
border-top: 1px solid #ccc;
}
Teams often prefer class selectors over raw tag selectors because they are easier to maintain.
4. Guarding against fragile HTML structure
Instead of writing:
Common Mistakes
1. Writing :not:first-child instead of :not(:first-child)
This is invalid because :not must contain parentheses.
/* Broken */
ul:not:first-child {
color: red;
}
/* Correct */
ul:not(:first-child) {
color: red;
}
2. Confusing :first-child with :first-of-type
<div>
<h2>Title</h2>
<ul>A</ul>
<ul>B</ul>
</div>
() {
: pink;
}
Comparisons
| Selector | Meaning | Best used when | Example |
|---|---|---|---|
:first-child | Element is the very first child of its parent | Position among all siblings matters | ul:first-child |
:first-of-type | First element of that tag type among siblings | First ul, first p, first li, etc. matters | ul:first-of-type |
:not(:first-child) | Every matching element except those that are first child | You want all matching elements that are not in first position | ul:not(:first-child) |
Cheat Sheet
/* First child of parent */
selector:first-child
/* Not the first child */
selector:not(:first-child)
/* First element of this type */
selector:first-of-type
/* Not the first element of this type */
selector:not(:first-of-type)
/* Any selector directly after same sibling pattern */
selector + selector
Quick rules
:not()must use parentheses.:first-childchecks position among all siblings.:first-of-typechecks position among siblings of the same tag type.A + BmatchesBonly if it comes immediately afterA.
Useful examples
ul:not(:first-child) { ... }
ul:not(:first-of-type) { ... }
ul + ul { ... }
FAQ
Why does ul:not(:first-child) not work sometimes?
Because :first-child checks whether the element is the parent's first child overall. If another element appears before the first ul, then that ul is not :first-child, so it also gets matched.
What is the difference between :first-child and :first-of-type?
:first-child means first among all siblings. :first-of-type means first of a specific tag type among siblings.
How do I select every ul except the first ul?
Usually use:
ul:not(:first-of-type)
If the ul elements are consecutive siblings, you can also use:
ul + ul
Is valid CSS?
Mini Project
Description
Build a small stacked menu layout where only the menu sections after the first one get a top border and extra spacing. This demonstrates the difference between :first-child, :first-of-type, and the adjacent sibling selector in a practical UI pattern.
Goal
Create a menu page where repeated list blocks are styled only when they come after the first block.
Requirements
- Create a container with a heading and three
ulelements. - Keep the first
ulvisually plain. - Add spacing and a top border to the second and third
ulonly. - Use a selector that remains correct even when a heading appears before the first
ul.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
CSS :not() Selector for Elements Without a Class or Attribute
Learn how to use the CSS :not() selector to target elements that do not have a specific class or attribute, with examples and common pitfalls.
CSS Font Scaling Relative to Container Size: %, em, rem, vw, and Responsive Text
Learn how CSS font scaling really works and how to make text responsive using %, em, rem, vw, clamp(), and media queries.