CSS: Child combinator selector & :first-child? - css

I have a div with some other divs, some paragraphs and some images in it. It basically looks like this:
<div id="parent">
<div>
This image is inside a div.
<img src="http://www.placehold.it/100" alt="" />
</div>
<p>
And this inside a paragraph.
<img src="http://www.placehold.it/100" alt="" />
</p>
<img src="http://www.placehold.it/100" alt="" />
<img src="http://www.placehold.it/100" alt="" />
</div>
Now I only want to select the images that aren't nested inside another div or p. I am doing this using the child combinator selector:
#parent > img {
border: 1px solid red;
}
This works, but now I only want to select the first, non-nested image. I tried it like this, but without any result:
#parent > img:first-child {
border: 1px solid blue;
}
http://jsfiddle.net/vF2DU/
How do I do it? Is there a way without adding a class or id like #first?

You could use the first-of-type or the nth-of-type selectors.
In this case, first-of-type is probably more relevant, but I'll show you the syntax for both below:
About first-of-type:
"The :first-of-type selector matches every element that is the first
child, of a particular type, of its parent."
first-of-type example:
#parent > img:first-of-type {
border: 1px solid blue;
}
Here is a working jsFiddle for first-of-type in regard to your use case.
About nth-of-type:
"The :nth-of-type(n) selector matches every element that is the nth
child, of a particular type, of its parent.
n can be a number, a keyword, or a formula."
nth-of-type example:
#parent > img:nth-of-type(1) {
border: 1px solid blue;
}
Here is a working jsFiddle for nth-of-type in regard to your use case.
Support:
Both are supported in all major browsers - Chrome, Firefox, Opera and Internet Explorer (IE9 and above). If you're interested in getting them to work perfectly in IE8 and before, check out Selectivizr.

:first-child means first-child, not first encountered element of a type. What you need is :first-of-type selector. working example

Related

Why does nth-of-type not consider the class? [duplicate]

Is it possible to use the CSS3 selector :first-of-type to select the first element with a given class name? I haven't been successful with my test so I'm thinking it's not?
The Code (http://jsfiddle.net/YWY4L/):
p:first-of-type {color:blue}
p.myclass1:first-of-type {color:red}
.myclass2:first-of-type {color:green}
<div>
<div>This text should appear as normal</div>
<p>This text should be blue.</p>
<p class="myclass1">This text should appear red.</p>
<p class="myclass2">This text should appear green.</p>
</div>
No, it's not possible using just one selector. The :first-of-type pseudo-class selects the first element of its type (div, p, etc). Using a class selector (or a type selector) with that pseudo-class means to select an element if it has the given class (or is of the given type) and is the first of its type among its siblings.
Unfortunately, CSS doesn't provide a :first-of-class selector that only chooses the first occurrence of a class. As a workaround, you can use something like this:
.myclass1 { color: red; }
.myclass1 ~ .myclass1 { color: /* default, or inherited from parent div */; }
Explanations and illustrations for the workaround are given here and here.
The draft CSS Selectors Level 4 proposes to add an of <other-selector> grammar within the :nth-child selector. This would allow you to pick out the nth child matching a given other selector:
:nth-child(1 of p.myclass)
Previous drafts used a new pseudo-class, :nth-match(), so you may see that syntax in some discussions of the feature:
:nth-match(1 of p.myclass)
This has now been implemented in WebKit, and is thus available in Safari, but that appears to be the only browser that supports it. There are tickets filed for implementing it Blink (Chrome), Gecko (Firefox), and a request to implement it in Edge, but no apparent progress on any of these.
This it not possible to use the CSS3 selector :first-of-type to select the first element with a given class name.
However, if the targeted element has a previous element sibling, you can combine the negation CSS pseudo-class and the adjacent sibling selectors to match an element that doesn't immediately have a previous element with the same class name :
:not(.myclass1) + .myclass1
Full working code example:
p:first-of-type {color:blue}
p:not(.myclass1) + .myclass1 { color: red }
p:not(.myclass2) + .myclass2 { color: green }
<div>
<div>This text should appear as normal</div>
<p>This text should be blue.</p>
<p class="myclass1">This text should appear red.</p>
<p class="myclass2">This text should appear green.</p>
</div>
I found a solution for your reference. from some group divs select from group of two same class divs the first one
p[class*="myclass"]:not(:last-of-type) {color:red}
p[class*="myclass"]:last-of-type {color:green}
BTW, I don't know why :last-of-type works, but :first-of-type does not work.
My experiments on jsfiddle... https://jsfiddle.net/aspanoz/m1sg4496/
This is an old thread, but I'm responding because it still appears high in the list of search results. Now that the future has arrived, you can use the :nth-child pseudo-selector.
p:nth-child(1) { color: blue; }
p.myclass1:nth-child(1) { color: red; }
p.myclass2:nth-child(1) { color: green; }
The :nth-child pseudo-selector is powerful - the parentheses accept formulas as well as numbers.
More here: https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child
You can do this by selecting every element of the class that is the sibling of the same class and inverting it, which will select pretty much every element on the page, so then you have to select by the class again.
eg:
<style>
:not(.bar ~ .bar).bar {
color: red;
}
<div>
<div class="foo"></div>
<div class="bar"></div> <!-- Only this will be selected -->
<div class="foo"></div>
<div class="bar"></div>
<div class="foo"></div>
<div class="bar"></div>
</div>
As a fallback solution, you could wrap your classes in a parent element like this:
<div>
<div>This text should appear as normal</div>
<p>This text should be blue.</p>
<div>
<!-- first-child / first-of-type starts from here -->
<p class="myclass1">This text should appear red.</p>
<p class="myclass2">This text should appear green.</p>
</div>
</div>
Not sure how to explain this but I ran into something similar today.
Not being able to set .user:first-of-type{} while .user:last-of-type{} worked fine.
This was fixed after I wrapped them inside a div without any class or styling:
https://codepen.io/adrianTNT/pen/WgEpbE
<style>
.user{
display:block;
background-color:#FFCC00;
}
.user:first-of-type{
background-color:#FF0000;
}
</style>
<p>Not working while this P additional tag exists</p>
<p class="user">A</p>
<p class="user">B</p>
<p class="user">C</p>
<p>Working while inside a div:</p>
<div>
<p class="user">A</p>
<p class="user">B</p>
<p class="user">C</p>
</div>
I found something that works
If you have a bigger class which contains something like grid, all of elements of your another class
You can do like that
div.col-md-4:nth-child(1).myclass{
border: 1px solid #000;
}
Simply :first works for me, why isn't this mentioned yet?

CSS: Does the plus sign work with pseudo elements?

For markup similar to this:
<div>
<p>hello world</p>
</div>
<div>
<h4>hello world</h4>
</div>
Can you do something like this in CSS:
div:after {
content: "";
display: block;
border-bottom: 2px solid red;
}
p + div:after {
content: "";
display: block;
border-bottom: 2px solid blue;
}
...meaning to say "Give all :after pseudo elements immediately following a <p> a blue border. Give all others a red border".
This doesn't seem to work. I realize this is because the + sign is applying to the 'div' selector, not the 'div:after' selector as a whole. But is there another way to target these in CSS (without adding a new class specific to these instances and without manipulating the DOM)?
Basically, what Michael_B said:
You can't target a pseudo-element. A pseudo-element is added to a selector that has matched an element.
"Target" is a vague term, but the second sentence is on point here. Combinators only work with elements, because selectors match elements, not pseudo-elements. What you're really trying to do in selector nomenclature is to style the ::after pseudo-element of a div whose last child is a p element (in which case the ::after box immediately follows the p box in the formatting tree):
<div>
<p>hello world</p>
div::after <!-- Blue border -->
</div>
<div>
<h4>hello world</h4>
div::after <!-- Red border -->
</div>
And you can't do that, because there is no parent selector.
I imagine something like div:has(> p:last-child)::after from Selectors 4 will work, but it depends on whether :has() makes it into CSS in the first place. The only other good option is to figure out which of these div elements has a p as their last child and assign them a special class name.
See also:
Can I target a :before or :after pseudo-element with a sibling combinator?
Is there a CSS parent selector?

Using odd and even selectors on child elements pseudo css3

I am looking to using CSS3 pseudo selectors of Odd and Even to select every 2nd image in the HTML. However the images are nested inside P tags. And not every P tag has an image.
For example:
<p><img src="/example.jpg" /></p>
<p>text</p>
<p>text</p>
<p><img src="/example.jpg" /></p>
<p><img src="/example.jpg" /></p>
<p>text</p>
<p><img src="/example.jpg" /></p>
The placement of P tags inbetween without images inside is random.
I tried this solution, but it doesn't work as it targets the odd and even of the P tags (not the image)
p:nth-child(odd) img{
border:4px solid #000;
}
This isn't possible with CSS, as far as I am aware. 'Content aware' selectors have been proposed for the CSS specification, but have not been implemented.
The easiest solution would be to use Javascript to target the images in the <p> tags. I assume all your p's are in a containing element, such as a div? If so, the following solution is possible, using jQuery:
$('div.mycontainer img').each(function(index, element) {
if (index % 2 != 0) {
element.addClass('border');
}
});
The logical condition of the if statement targets even elements by using the modulus operator. border is a class which could contain your special styling rules, like so:
.border {
border:4px solid black;
}

CSS '>' selector; what is it? [duplicate]

This question already has answers here:
What does the ">" (greater-than sign) CSS selector mean?
(8 answers)
Closed 3 years ago.
I've seen the "greater than" (>) used in CSS code a few times, but I can't work out what it does. What does it do?
> selects immediate children
For example, if you have nested divs like such:
<div class='outer'>
<div class="middle">
<div class="inner">...</div>
</div>
<div class="middle">
<div class="inner">...</div>
</div>
</div>
and you declare a css rule in your stylesheet like such:
.outer > div {
...
}
your rules will apply only to those divs that have a class of "middle" since those divs are direct descendants (immediate children) of elements with class "outer" (unless, of course, you declare other, more specific rules overriding these rules). See fiddle.
div {
border: 1px solid black;
padding: 10px;
}
.outer > div {
border: 1px solid orange;
}
<div class='outer'>
div.outer - This is the parent.
<div class="middle">
div.middle - This is an immediate child of "outer". This will receive the orange border.
<div class="inner">div.inner - This is an immediate child of "middle". This will not receive the orange border.</div>
</div>
<div class="middle">
div.middle - This is an immediate child of "outer". This will receive the orange border.
<div class="inner">div.inner - This is an immediate child of "middle". This will not receive the orange border.</div>
</div>
</div>
<p>Without Words</p>
<div class='outer'>
<div class="middle">
<div class="inner">...</div>
</div>
<div class="middle">
<div class="inner">...</div>
</div>
</div>
Side note
If you, instead, had a space between selectors instead of >, your rules would apply to both of the nested divs. The space is much more commonly used and defines a "descendant selector", which means it looks for any matching element down the tree rather than just immediate children as the > does.
NOTE: The > selector is not supported by IE6. It does work in all other current browsers though, including IE7 and IE8.
If you're looking into less-well-used CSS selectors, you may also want to look at +, ~, and [attr] selectors, all of which can be very useful.
This page has a full list of all available selectors, along with details of their support in various browsers (its mainly IE that has problems), and good examples of their usage.
> selects all direct descendants/children
A space selector will select all deep descendants whereas a greater than > selector will only select all immediate descendants. See fiddle for example.
div { border: 1px solid black; margin-bottom: 10px; }
.a b { color: red; } /* every John is red */
.b > b { color: blue; } /* Only John 3 and John 4 are blue */
<div class="a">
<p><b>John 1</b></p>
<p><b>John 2</b></p>
<b>John 3</b>
<b>John 4</b>
</div>
<div class="b">
<p><b>John 1</b></p>
<p><b>John 2</b></p>
<b>John 3</b>
<b>John 4</b>
</div>
It is the CSS child selector. Example:
div > p selects all paragraphs that are direct children of div.
See this
As others have said, it's a direct child, but it's worth noting that this is different to just leaving a space... a space is for any descendant.
<div>
<span>Some text</span>
</div>
div>span would match this, but it would not match this:
<div>
<p><span>Some text</span></p>
</div>
To match that, you could do div>p>span or div span.
It is a Child Selector.
It matches when an element is the child of some element. It is made up of two or more selectors separated by ">".
Example(s):
The following rule sets the style of all P elements that are children of BODY:
body > P { line-height: 1.3 }
Example(s):
The following example combines descendant selectors and child selectors:
div ol>li p
It matches a P element that is a descendant of an LI; the LI element must be the child of an OL element; the OL element must be a descendant of a DIV. Notice that the optional white space around the ">" combinator has been left out.
It declares parent reference, look at this page for definition:
http://www.w3.org/TR/CSS2/selector.html#child-selectors
It means parent/child
example:
html>body
that's saying that body is a child of html
Check out: Selectors

Help with a pseudo-class, first-child

I am working on a CMS platform with limited access to the template files and want to try and control some of the layout with pseudo class but no luck yet. Can anyone see what is wrong with this structure and why my pseudo class is being ignored?
<div id="main">
<div class="someRandomDiv"></div>
<div class="block">
stuff
</div>
<div class="block">
more stuff
</div>
</div>
and i am trying something like this
#main .block {border: 1px solid blue}
#main .block:first-child {border: 1px solid red}
so with this example I would think the stuff block would have a red border and more stuff would have a blue but it is all just blue.
Thanks for any help with this.
It's not being ignored, there just aren't any matches :)
I realize it's a bit counter-intuitive, but :first-child literally means first child of the parent, not of the type, of the parent, so the only thing that matches :first-child in your code is <div class="someRandomDiv"></div>.
With .block:first-child you're saying elements that have a class of block and are the first child of their parent, it's not saying "the first one with class block"...they're independent selectors and don't overlap here. So, there are no matches since no element matches both conditions, that make more sense?
It won't support all browsers, but you could use :nth-child() or javascript to do what you want, for example in jQuery it would be:
$("#main .block:first").css({ border: '1px solid red' });

Resources