CSS select first element with a certain class - css

What is the syntax for selecting the first element with a certain class? Please specify whether that method of selection is part of CSS3 or CSS2.1.

If you need the first element with a certain class among its siblings, you can use
.myclass {
/* styles of the first one */
}
.myclass ~ .myclass {
/* styles of the others (must cancel the styles of the first rule) */
}
Don't try to use .myclass:not(.myclass ~ .myclass) to do this in only one rule, it won't work since :not() only accepts simple selectors in the parentheses.
If you want the first .myclass in the whole document, there is no way to do it with CSS alone.
The :nth-of-type() or :nth-child() approaches posted are wrong, even if they coincidentally happen to match the elements you want in your page.
Browser support of sibling selector (~): IE7+ and all others.

This problem sucks as bad as the solutions. IMO you should just give the first element a class of .first{} programmatically.

Try this
.testparent .test:first-child {
color: red;
}
<div class="testparent">
<div class="test">test</div>
<div class="test">test</div>
<div class="test">test</div>
</div>
the first div 'test' has red color only.

.class-name:first-of-type {
⋮ declarations
}

Related

CSS - :target ~

That´s my html code:
test
<ul id="anchor"></ul>
Now I want to style my target, which isn´t a problem.
#anchor:target
{
}
But I want to select the sibling of the target (a).
#anchor:target ~ a{
background: blue;
}
It´s not working. How to select the sibling of the target?
Currently, there is no way to style the previous siblings with CSS. To achieve this, you'll have to use javascript.
You can get the next sibling with + or all <a>s after your <ul> with ~:
#anchor:target + a {
/*
<ul></ul>
<a>will get this one</a>
<a>but not this one</a>
*/
}
#anchor:target ~ a {
/*
<ul></ul>
<a>will get this one</a>
<a>and this one too!</a>
*/
}
In CSS there is no "previous" sibling selector (in CSS2 or CSS3).
The "Selectors Level 4" draft introduces the ! selector, which if I understand it correctly, allows for previous sibling selection.
https://drafts.csswg.org/selectors-4/#subject
However, this is still in draft form, and is far from being supported in all the major browsers.
Sorry, but it's not possible with the current CSS spec.
The only way to really achieve this would be to use JavaScript, or to change the order of your markup.
Currently, you cannot get previous siblings. But you can select a element with specific attribute like this:
a[href="#anchor"] {
color: #f00;
}
test
<ul id="anchor"></ul>
as per my previous answer, this isn't possible in the way you've written due to limitations in CSS.
However, you could always match the itself?
a[target|="#"] {
}
This would select all <a> tags within your document that point to local anchors.

CSS - First child without certain class

Is it possible to write a CSS rule to select the first child of an element without a specific class?
example:
<div>
<span class="common-class ignore"></span>
<span class="common-class ignore"></span>
<span class="common-class"></span>
<span class="common-class"></span>
</div>
In this case I would like to select the first span without class ignore.
I tried this, but didn't seem to work:
.common-class:first-child:not(.ignore) {
...some rules...
}
UPDATE:
If I add a class to the parent div named parent-class, a modified version of the selector suggested by Jukka works except when the first span with class ignore comes after the first one without. The above-mentioned selector is the following:
.parent-class > .common-class.ignore + .common-class:not(.ignore) {
...some rules...
}
This question is similar to CSS selector for first element with class, except for the first element without a class. As mentioned, :first-child:not(.ignore) represents an element that is the first child of its parent and does not have the class "ignore", not the first child matching the rest of the selector.
You can use the overriding technique with a sibling combinator that I've described in my answer to the linked question, replacing the class selector with the :not() pseudo-class containing a class selector:
.common-class:not(.ignore) {
/* Every span without class .ignore, including the first */
}
.common-class:not(.ignore) ~ .common-class:not(.ignore) {
/* Revert above declarations for every such element after the first */
}
This selects all span with a .common-class and without an .ignore class.
span.common-class:not(.ignore) {
color: blue;
}
But, because we want to select only the first one, you can override the siblings that follow with the ~ selector.
span.common-class:not(.ignore) ~ span {
color: black; /* or color: inherit; */
}
jsBin demo
If you are already using jQuery, this can also be done with
$("span.common-class:not(.ignore):first").css('color', 'blue');
No, it is not possible. The selector :first-child:not(.ignore) selects an element that is the first child of its parent and does not belong to class ignore. There is no “first of class” selector and no “first not of class” selector either.
You could use the selector .ignore + :not(.ignore), but it matches any element that is not in class ignore and immediately follows an element in that class. But it matches too much, not just the first one of such elements. Depending on the markup structure, this selector might still be suitable in a particular situation, even though it is not an answer to the general question asked.
You don't have to select the div using a class. What about other css solutions like nth-child etc.? Of course, this requires the knowledge of a document structure.

Is the CSS :not() selector supposed to work with distant descendants?

Here is the official documentation for the CSS3 :not() pseudo-class:
http://www.w3.org/TR/css3-selectors/#negation
and the proposed CSS Selectors Level 4 enhancement:
http://dev.w3.org/csswg/selectors4/#negation
I've been searching the implementation and browser support for :not(), but the only examples I found were with a single element or with a direct child of an element, e.g.:
div *:not(p) { color: red; }
The example above works when <p> is a direct child of <div>, but it does not work when <p> is a more distant descendant of <div>.
div :not(p) {
color: red;
}
<div>
<ul>
<li>This is red</li>
</ul>
<p>This is NOT</p>
<blockquote><p>This is red but is not supposed to be!</p></blockquote>
</div>
If the answer is in the official documentation above, then I didn't find/understand it. As I said, I have searched this site and the web but couldn't find any discussion about the support or lack thereof of :not() as grand-children of another element.
Is this supposed to work like I think it should?
Is this supposed to work like I think it should?
No, the behavior you're seeing is correct.
In your last example, although the <blockquote> contains a <p>, it's the <blockquote> itself that's matching *:not(p), as well as the condition that it must be a descendant of the <div>, which it is. The style is applied only to the <blockquote>, but it is then inherited by the <p> inside it.
The <p> element itself still counts against the negation, so the <p> itself is still being excluded from your selector. It's just inheriting the text color from its parent, the <blockquote> element.
Even if none of its relatively close ancestors matched the selector, you have elements like html and body to worry about as well — although you could probably just tack on a body selector in the very beginning:
body div...
This is why I often strongly advise against using the :not() selector for filtering descendants, especially when not qualified with a type selector (like div in your example). It doesn't work the way most people expect it to, and the use of inherited properties like color only serves to compound the problem, on top of making it even more confusing for authors. See my answers to these other questions for more examples:
Why doesn't this CSS :not() declaration filter down?
CSS negation pseudo-class :not() for parent/ancestor elements
The solution to the problem described is to simply apply a different color to <p> elements. You won't be able to simply exclude them with a selector because of inheritance:
/* Apply to div and let all its descendants inherit */
div {
color: red;
}
/* Remove it from div p */
div p {
color: black;
}
On Selectors Level 4: yes, :not() has indeed been enhanced to accept full complex selectors that contain combinators. Essentially, this means (once browsers begin implementing it) you will be able to write the following selector and have it do exactly what you want:
p:not(div p) {
color: red;
}
In case anyone is interested, this works in jQuery today.
The color is assigned to the blockquote, and is then inherited by the p.
:not(p) just makes it so that the styles are not directly applied. They are still inherited though.

How to style parent when parent contains specific child?

I have some html that looks like this:
<div id="parent">
<div id="child"></div>
</div>
I want to apply a default background color to #parent except for when it contains a #child.
So the CSS should end up looking something like this:
#parent {
background: red
}
#parent:contains(#child) {
background: none
}
However, I can't get the :contains pseudo selector to work that way. Is there a way to achieve this?
:contains() was only intended to match elements containing certain text, not elements containing certain other elements. It is because of the complications associated with matching elements by text that there were almost no browser implementations, leading to :contains() being dropped from the spec.
Since there is no parent selector in CSS, and :has() (which does look at elements) only exists in jQuery, you won't be able to achieve this with CSS yet.
For the record, jQuery implements :contains() as well, but it does so according to the old spec, so it uses the name :has() for elements instead.
With jquery
if($("#child").length>0) $("#parent").css("backgroundColor","#fff");
Its not possible with pure css.

What's the difference between `.class1.class2` and `.class1 .class2` CSS rule?

I have a table with some rows:
<table>
<tr class="even"><td>tr0</td></tr>
<tr><td>tr1</td></tr>
<tr class="even"><td>tr2</td></tr>
</table>
I have a CSS rule (rule1) for even rows:
.even{
background-color: blue;
}
I have another rule (rule2) for override the bgcolor of any row:
.override, .override.even{
background-color: green;
}
The weird thing is in IE9 all even rows (with no override class) are green!
Developer tools shows this for even rows:
In these two conditions IE do the job correctly:
If I rewrite rule2 like this:
.override, .override .even{ ... }
If I move rule2 above rule1:
.override, .override.even{ ... }
.even { ... }
Question is what's the difference between .override.even and .override .even?
EDIT:
Thanks for replies. Another question which I forgot to ask is why IE shows the even rows green?
Spacing in between class specifiers means a ascendant -> descendant relationship.
The rule:
.test .heading { font-weight: bold; }
Would apply to the <p> element here:
<span class="test"><p class="heading">Something</p></span>
The lack of space means that the element must have both classes for the rule to apply.
The rule:
.heading.major { color: blue; }
Would apply to the <p> element here:
<p class="heading major">Major heading</p>
Both answers are right, but they don't explain, why IE shows both rows green.
It's because IE has "standard" and "quirks" mode. To make multiple classes selectors work, you need to use proper DOCTYPE at the beginning of the file.
You are in "quirks" mode now and IE don't support multiple selectors, it sees only latest class. So it sees this and rows are green:
.even {
background-color: blue;
}
.override, .even {
background-color: green;
}
Put
<!DOCTYPE html>
(or another DOCTYPE) at the beginning of the file and both rows are going to be blue as expected.
See the W3C [CSS] Selector (Level 3) "Recommendation":
.override .even is two simple selectors separated by a space (which is the descendant combinator, CSS is whitespace-sensitive):
At times, authors may want selectors to describe an element that is the descendant of another element in the document tree (e.g., "an EM element that is contained within an H1 element"). Descendant combinators express such a relationship. A descendant combinator is whitespace that separates two sequences of simple selectors. A selector of the form "A B" represents an element B that is an arbitrary descendant of some ancestor element A.
This selector will match elements that have the class even if and only if there exists an ancestor -- not necessarily the parent! -- element with the class override. (Unlike characters in some movies, an element is never it's own ancestor ;-)
.override.even is a simple selector sequence:
A sequence of simple selectors is a chain of simple selectors that are not separated by a combinator. It always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence.
A simple selector sequence is evaluated as the conjunction of the individual simple selectors applied to the same element: that is, it will only match elements with both the override and even classes applied.
Happy coding.
.override .even is interpreted as "some element with an 'override' class, with another element with a .even class nested within. It's basically the same as ul li, but applying to CSS classes.
override.even is interpreted as "some single element with BOTH override AND even classes".
<div class="class1">
<div class="class2">
<p>test1</p>
</div>
</div>
If this type coded added than use space between to class like .class1 .class2
<div class="class1 class2">
<p>test2</p>
</div>
If this type coded added than don't use space between to class like .class1.class2

Resources