Select recursive :last-child. Possible? - css

In CSS, is it possible to recursively select all :last-child from body?
Given this markup:
<body>
<div id="_1">
<div id="_2"></div>
</div>
<div id="_3">
<div id="_4">
<div id="_5"></div>
<div id="_6"></div>
</div>
</div>
</body>
I am looking for div no. 3, 4 and 6
Another way to put it is this:
body > :last-child,
body > :last-child > :last-child,
body > :last-child > :last-child > :last-child,
body > :last-child > :last-child > :last-child > :last-child {
/* My stuff here */
}
But obviously this is not a good approach.

No, unfortunately that's just about the only way to do it without modifying the HTML.
There has been at least one request for recursive versions of the :first-child and :last-child pseudo-classes, but it doesn't seem to have gained much favor. Notice it suggests nesting and repeating the pseudo-classes in the same way as in your question:
Currently, AFAIK, we can only match children up to some exact nesting level known in advance (3 in the example below):
.container > :first-child,
.container > :first-child > :first-child,
.container > :first-child > :first-child > :first-child {}
We cannot use just :first-child context selector since it would also select first children of blocks that are not first children themselves.
So we need a sort of recursive selector that matches not just first of last child, but recursively matches all first-most and last-most elements regardless of their nesting level.

body :last-child {
color:red;
}
body :not(:last-child) :last-child {
color:initial;
}
Any last-child element that's a descendant of one that's not a last-child will have the change reversed.

No need to chain all the way. It would be simply like this
div:last-child {
/* Your GREAT css */
}
Demo
Update: On that case, give the div2 a typical class and use :not() to push out of the selection
div:last-child:not(.nolist) {
border: 1px solid red;
}
Demo

Related

Selecting descendants with certain classes that are beneath an element

In css I know you can select elements beneath their parent with the > selector:
#myDiv > p {
line-height: 1;
}
Is it possible to do the same for elements with a certain set of classes beneath that element, eg:
#myDiv > .classA .classB {
line-height: 1;
}
So that any child element with classes .classA .classB will get the treatment?
I've tried this and it doesn't seem to be working, and am not sure if I'm going down the right path or if I'm close.
This is a limitation of CSS that you have to repeat your self by doing
#myDiv > .classA, #myDiv > .classB
as your selector. Most CSS preprocessors can make this less of a challenge to keep things DRY.
Yes, you can - but you have to follow the rules. A space character is also a descendant selector, and that's not what you want. If you want to select all descendants that have both classes, try:
#myDiv > .classA.classB {
line-height: 1;
}

pseudo selector for second child exact like first-child

Is there a identical psuedo selector that acts like :first-child but with second child of a parent element?
I used
:nth-child(2) but is that the only equivalent it seems it resolves slightly differently when styles are applied. I also like the legibility of :first-child
If that is the equivalent why use :first-child and not :nth-child(1) what is correct selectors with most support for accessing first and second child elements of div container?
No, there is no such selector. You should use :nth-child(2).
And :first-child is older browser compatible than :nth-child(1) so we use :first-child
And if you're using :nth-child(2), you shouldn't be confusing to use :nth-child(1) in your own.
In addition to :nth-child(2), you can use the combined selector
:first-child + *
which refers to the same elements, since it denotes any element that is the next sibling for any first child. More normally, you would be using something like p:nth-child(2), and then the equivalent selector is
:first-child + p
“Equivalence” means here that the selectors denotes the same sets of elements. They are different in specificity, so care needs to be taken when this matters.
The combined selector is slightly more cross-browser, since the constructs involved are supported by IE 8, which does not support :nth-child(2).
Example:
<style>
:first-child + p {
outline: solid red;
}
p:nth-child(2) {
background: gray;
}
</style>
<div>
<p>foo
<p>bar
<p>more
</div>

How do I hide only the first element of a type?

I have the following markup:
<div class="ctr-1">
<h3>Title</h3>
<div class="ctr-2">
<h3>Title</h3>
</div>
</div>
And the following CSS
.ctr-1 h3:first-child{ display:none; }
Both <h3> tags are hidden, I only want the first one hidden. How?
This is what the first-of-type and nth-of-type selectors are for.
For example:
.ctr-1 h3:first-of-type { display:none; }
/* - Or - */
.ctr-1 h3:nth-of-type(0) { display:none; }
This would hide the first h3 descendant of .ctr-1, regardless of its location inside the parent element.
Granted, in your specific example, the h3 is indeed also the immediate (>) and first (:first-child) descendant of .ctr-1 . But if this is a coincidence, you might not be able rely on it. In that case, nth-of-type is the way to go.
You have a few different options:
Use the :first-of-type pseudo class to select the first element of type:
.ctr-1 > h3:first-of-type {
display: none;
}
Or use the :nth-of-type(n) pseudo class and specify the index of the first element:
.ctr-1 > h3:nth-of-type(0) {
display: none;
}
If type doesn't matter, and you always want to select the first child, use the :first-child pseudo class:
.ctr-1 > h3:first-child {
display: none;
}
They are both technically the first-child.
In your example, you could do:
.ctr-1 > h3:first-child { display:none; }
You have wrong, ctr doesn't exist, and you need to tell with > to select the first element level in your page selector try this:
.ctr-1 > h3:first-child{ display:none; }
You can use:
.ctr-1 > h3 { display: none; }

CSS Selecting First Child

Im still trying to figure out how to properly use my nth, first, and last child selectors. Thanks for your patience.
If my markup is like this:
<div class="the-wrapper">
<table class="the-table">
<!-- the table -->
</table>
<table class="the-table">
<!-- the table -->
</table>
</div>
How can I select the last <table class="the-table"> to apply a margin?
I thought I could select it like this: .the-wrapper .the-table:last-child { /* css */ } but this does not work. What am I missing? Thank you!
EDIT
Sorry everyone I printed my markup incorrectly... The correct markup is above
The + is used to select "siblings" elements. (siblings in the sense of being childs of the same parent) http://jsfiddle.net/Lhmjq/
You can't use nth-child or last-child for this; as the name say, is for childs, and unless you put a parent, you can't do it.
Here is an example with a parent: http://jsfiddle.net/Lhmjq/2/ In this case, is done with last-child
(updated to your new code)
Here is a tiddle: http://jsfiddle.net/Lhmjq/4/
.the-wrapper .the-table:last-child {
color: blue;
}
Updated with your new code: http://jsfiddle.net/Lhmjq/4/
.the-wrapper .the-table:last-child { /* css */ }
The previous code should select the last table in the wrapper. The targeting for structural pseudo classes can be confusing. The pseudo classes are defined in regards to it's direct parent. For instance, say you have a list of elements:
<ul class="target-me">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
and you want to target the last li in the list. Your CSS would be:
.target-me > li:last-child { color: red; }
You can also use the pseudo selectors to target numbered items from the position in the DOM, say I want to target the second element:
.target-me > li:nth-child(2) { color: red; }
You can also use these pseudo selectors in a selector hierarchy.
.target-me > li:first-child span { ... }
You can also chain pseudo selectors:
.target-me > li:first-child:hover { ... }
In conjunction with a polyfill like Selectivizr you can use these selectors on all browsers. I hope this helps!
Your code ".the-wrapper .the-table:last-child " will return the last-child elements of ALL your ".the-wrapper" classes. What you want to do is select the last ".the-wrapper" element. The code below will select the last-child table of the last ".the-wrapper" element, which is what you are looking for...
$('.the-wrapper .the-table:last-child').last().css("border","1px solid #b5b5b5")
Cheers!

CSS wildcards with :first-child

I have an unwieldy chunk of css that I am using to set the margin-top of the first child of an element. The first child can be any tag.
.comment-description p:first-child,
.comment-description ol:first-child,
.comment-description ul:first-child,
.comment-description pre:first-child,
.comment-description blockquote:first-child
{
margin-top:0px;
}
I'm sure that I can chop this down, but since I don't get to design too often, I can't remember a better way. Can I use something like:
.comment-description *:first-child
{
margin-top:0px;
}
Unfortunately this doesn't work.
You may be interested in:
.comment-description > :first-child {} - select only immediate children
or
.comment-description :first-child - select first child of all children elements
See:
http://jsfiddle.net/9VqsW/1/
To clarify things a little:
.element selector - selects all descendants that match selector. It doesn't matter if selector is a class, pseudo-class or ID.
.element > selector - selects only on the direct children that match selector
It looks like you want:
.comment-description > :first-child{
....
}
.comment-description :first-child
{
margin-top:0px;
}
Has the same effect as
.comment-description *:first-child
{
margin-top:0px;
}
Have a look here.

Resources