not:first-child selector
One of the versions you posted actually works for all modern browsers (where CSS selectors level 3 are supported):
div ul:not(:first-child) {
background-color: #900;
}
If you need to support legacy browsers, or if you are hindered by the :not
selector's limitation (it only accepts a simple selector as an argument) then you can use another technique:
Define a rule that has greater scope than what you intend and then "revoke" it conditionally, limiting its scope to what you do intend:
div ul {
background-color: #900; /* applies to every ul */
}
div ul:first-child {
background-color: transparent; /* limits the scope of the previous rule */
}
When limiting the scope use the default value for each CSS attribute that you are setting.
CSS select element with class, only if it is NOT first child of parent
Using the :not
and :first-child
selectors should do it.
.special:not(:first-child) {}
CSS First element that does not have a class
Use the "Adjacent sibling combinator": http://www.w3.org/TR/css3-selectors/#adjacent-sibling-combinators
li.featured + li:not([class="featured"])
Why CSS selector :first-child:not(.ignore) doesn't exclude `ignore` class from selection?
The first problem is that you made a spelling error. ingore
and ignore
don't match.
Aside from that, the html
element matches your selector, and the default background-color
for a div
is transparent
.
So the selector isn't matching the div and turning it blue, you can just see the blue background of the html
element through it.
body :first-child:not(.ignore){
background-color:lightblue;
}
<body>
<div>
<div>
should be blue and is blue
</div>
<div>
should also be blue as it's parent is blue due to being first child of 'body'
</div>
</div>
<div>
<div class="ignore">
should not be blue but is blue
</div>
<div>
should not be blue and is not blue
</div>
</div>
</body>
CSS selector for first element with class
This is one of the most well-known examples of authors misunderstanding how :first-child
works. Introduced in CSS2, the :first-child
pseudo-class represents the very first child of its parent. That's it. There's a very common misconception that it picks up whichever child element is the first to match the conditions specified by the rest of the compound selector. Due to the way selectors work (see here for an explanation), that is simply not true.
Selectors level 3 introduces a :first-of-type
pseudo-class, which represents the first element among siblings of its element type. This answer explains, with illustrations, the difference between :first-child
and :first-of-type
. However, as with :first-child
, it does not look at any other conditions or attributes. In HTML, the element type is represented by the tag name. In the question, that type is p
.
Unfortunately, there is no similar :first-of-class
pseudo-class for matching the first child element of a given class. At the time this answer was first posted, the newly published FPWD of Selectors level 4 introduced an :nth-match()
pseudo-class, designed around existing selector mechanics as I mentioned in the first paragraph by adding a selector-list argument, through which you can supply the rest of the compound selector to get the desired filtering behavior. In recent years this functionality was subsumed into :nth-child()
itself, with the selector list appearing as an optional second argument, to simplify things as well as averting the false impression that :nth-match()
matched across the entire document (see the final note below).
While we await cross-browser support (seriously, it's been nearly 10 years, and there has only been a single implementation for the last 5 of those years), one workaround that Lea Verou and I developed independently (she did it first!) is to first apply your desired styles to all your elements with that class:
/*
* Select all .red children of .home, including the first one,
* and give them a border.
*/
.home > .red {
border: 1px solid red;
}
... then "undo" the styles for elements with the class that come after the first one, using the general sibling combinator ~
in an overriding rule:
/*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
Now only the first element with class="red"
will have a border.
Here's an illustration of how the rules are applied:
.home > .red {
border: 1px solid red;
}
.home > .red ~ .red {
border: none;
}
<div class="home">
<span>blah</span> <!-- [1] -->
<p class="red">first</p> <!-- [2] -->
<p class="red">second</p> <!-- [3] -->
<p class="red">third</p> <!-- [3] -->
<p class="red">fourth</p> <!-- [3] -->
</div>
Related Topics
Differencebetween the Hidden Attribute (Html5) and the Display:None Rule (Css)
How to Horizontally Center a Floating Element of a Variable Width
How to Remove Border from Specific Primefaces P:Panelgrid
Rounded Side, Not Rounded Corners
CSS Cursor Pointer with Svg Image
CSS Background Image Url Failing to Load
Grid Styling - Overwrite Style of Ag-Grid
How to Center a Div with Bootstrap2
Immediate Child Selector in Less
Overflow to Left Instead of Right
How to Set the Height of a Div Based on a Percentage-Based Width
How to Remove All Default Webkit Search Field Styling
How to Fix Internet Explorer 7 Bug When Using Percentage Widths for Layout
Difference Between "-Webkit-Text-Fill-Color" and "Color"
Sass and Rounding Down Numbers. Can This Be Configured