CSS selector to select the first element after n elements - html

Is there a way to select the first element with a some class after n elements? For example in the following HTML, I want to be able to select only the first div that has CSS class apple after the 5th div, resulting in the 7th div element being selected.
<div>
<div class="data-class">1</div>
<div class="data-class">2</div>
<div class="data-class">3</div>
<div class="data-class apple">4</div>
<div class="data-class">5</div>
<div class="data-class">6</div>
<div class="data-class apple">7</div>
<div class="data-class apple">8</div>
<div class="data-class">9</div>
<div class="data-class apple">10</div>
</div>
This selector selects all the divs, but I only want the first: .data-class.apple:nth-child(n+5)
And this one doesn't even work: .data-class.apple:nth-child(n+5):first-child
I have put the HTML and CSS samples here.
UPDATE
Current CSS selectors
.data-class{
background-color: #0ea;
padding: 10px;
margin-bottom: 5px;
border: 1px solid #444;
}
.data-class:nth-child(n+5)+.apple{
background-color: #f0f;
}

To select an element appearing after some other element, use the ~ combinator:
.data-class:nth-child(5) ~ .data-class.apple {
background-color: #f0f;
}
You won't be able to match only the first .apple that occurs using just one selector. You will need to create another rule to undo the styles that you apply for subsequent .apple elements:
.data-class:nth-child(5) ~ .data-class.apple ~ .data-class.apple {
background-color: #0ea;
}
This technique is explained here.

it is better to say having css class, not having css.
I couldn't find the appropiate selector strictly.
Instead of this, you could use jquery and write javascript function which
use for loop from 5th child until it finds class containing apple. You may use jquery n-th-child to select child in loop and hasClass to determine if it contains apple.
Therefore select result by passing result to n-th-child function.

It uses this test:
div > .data-class.apple, .data-class{.....}
or another use:
div > .apple:not(.data-class){.....}

Related

How to use the :last-child selector?

I want to simply add a border-bottom to the last .slab
I tried a few things and I am unable to understand what is going on.
Case 1 - use .wrapper:last-child
If I try this on codepen.io or on Stackoverflow snippets, I don't get a border-bottom on last .slab
If I try this on JSFiddle or run the code separately in Chrome, I get a border-bottom on last .slab. However, if I uncomment <div class="something">New</div>, then the border-bottom on last .slab vanishes in both JSFiddle and on Chrome.
.wrapper {
width: 10em;
margin: 1em;
}
.wrapper:last-child {
border-bottom: 1px solid #999;
}
.slab {
background-color: #eee;
border-top: 1px solid #999;
padding: 1em;
}
<div class="wrapper">
<div class="slab">Hello</div>
<div class="slab">Hello</div>
<div class="slab">Hello</div>
</div>
<!--<div class="something">New</div>-->
Case 2 - use .slab:last-child
Turns out this works everywhere - JSFiddle, Chrome, codepen.io and on Stackoverflow. But I thought the selection was really for the last-child of .slab and not the last .slab
.wrapper {
width: 10em;
margin: 1em;
}
.slab {
background-color: #eee;
border-top: 1px solid #999;
padding: 1em;
}
.slab:last-child {
border-bottom: 1px solid #999;
}
<div class="wrapper">
<div class="slab">Hello</div>
<div class="slab">Hello</div>
<div class="slab">Hello</div>
</div>
Questions:
Does .slab:last-child mean the last child of .slab or the last occurrence of .slab ?
In case 1, why is the border-bottom vanishing after the introduction of an unrelated element .something ?
What is the best way to apply border-bottom to the last .slab ?
Does .slab:last-child mean the last child of .slab or the last occurrence of .slab ?
Neither. It matches an element that
has the "slab" class, and
is the last child of its parent.
The last .slab within its parent may not necessarily be its last child. .slab:last-child will match if and only if both conditions are true for the given element.
In case 1, why is the border-bottom vanishing after the introduction of an unrelated element .something ?
Because then the last child of the parent of .wrapper becomes that other element. This element isn't unrelated to .wrapper — it's related to it by way of being its next sibling.
The .slab elements within that wrapper never receive a border; the border is being applied to the .wrapper for as long as it is the last child of its parent. (Incidentally, the parent of .wrapper in your examples is implied to be body.)
What is the best way to apply border-bottom to the last .slab ?
You won't be able to do this reliably unless you can guarantee that the only possible children of .wrapper are .slab elements, in which case the class name then becomes quite irrelevant (but you can still include it in your selector so you avoid matching the last child of .wrapper when it's not a .slab).
last-child means exactly what is says...the very last element that is a child of a parent.
Not the last of class...the last element.
There is no last-of-class selector.
This: .slab:last-child means the last child that also has a class of .slab.
If it's not the last-child it won't apply and, equally, if it doesn't have a class of .slab it won't be selected.
The :last-child structural pseudo-class selector applies to siblings of a parent. It is equivalent to :nth-last-child(1),
In terms of your code, you would apply :last-child to .slab to select the last sibling of parent div.wrapper.
If the last child of div.wrapper did not have a slab class, then the selector wouldn't match. It would do nothing.
If the :last-child were applied to the div children of div.wrapper, like this:
.wrapper > div:last-child { ... }
... then the selector would match the last child regardless of the class, id or other attributes. It would match any div. If the last child was not a div, the selector would do nothing.
If you wanted to match the last child of div.wrapper, regardless of anything – meaning it just needs to be the last child – then you could do something like this:
.wrapper > *:last-child { ... }
Without the > child combinator, let's say .wrapper *:last-child { ... }, the last child of all descendant parent elements would be matched.
When you select .wrapper:last-child, you're targeting the element with class wrapper that is the last child of its parent (presumably body, in this case).
If div.wrapper is the only child of its parent, then :last-child, :first-child, :only-child and most other structural pseudo-class keyword selectors would match.
For a better understanding of these selectors (and all others), refer to this section of the CSS spec:
http://www.w3.org/TR/css3-selectors/#selectors

How to use first-child?

I would like to select the first div called "aProduct" but I'm a bit confused on how to do this. I already tried this:
<div id="kasticketProducts">
<div class="aProductHeader"></div>
<div class="aProduct"></div>
<div class="aProductHeader"></div>
<div class="aProduct"></div>
</div>
This is my current CSS:
#kasticketProducts:first-child .aProduct {
margin-top: 30px;
background: red;
}
#kasticketProducts:first-child .aProduct
Using above css means first it'll search for id with kasticketproducts in that first-child, here first child refer to aProductHeader from here you are trying to search aProduct but it is not there.
Actually from DOM hierarchy aProduct class div is at second child this will be referred in css as nth-child(2) here and no need of again .aProduct .So the final solution for this is write as #kasticketProducts div:nth-child(2)
First, whats the difference?
From MDN :
:first-child()
The :first-child CSS pseudo-class represents any element that is the first child element of its parent.
:first-of-type()
The :first-of-type CSS pseudo-class represents the first sibling of its type in the list of children of its parent element.
So inshort, :first-child() is somewhat a loose pseudo selector compared to :first-of-type()
Unfortunately :first-child or :first-of-type doesn't respect classes or ids, they are only concerned with the DOM elements. So if you do something like, will fail
#kasticketproducts div.aProduct:first-of-type {
color: red;
}
So in this case the best you can do with CSS is use :nth-of-type() with 2 as a value, now obviously it will fail if your element doesn't have a class of aProduct
#kasticketproducts div:nth-of-type(2) {
color: red;
}
Demo
OR
you can use adjacent selector with :first-of-type()
#kasticketproducts div:first-of-type + div {
color: red;
}
Demo
Second solution is MORE COMPATIBLE as far as IE is concerned
DEMO
Code is not working because aProductHeader class is before first occurrence of aProduct class.
See demo.
You can't target the first element of a class, but you can target the elements that come after, so you can set the styles on all the aProduct elements and then override it on all aProduct that comes after the first one using the ~ opreator:
#kasticketproducts .aProduct {
margin-top: 30px;
background: red;
}
#kasticketproducts .aProduct ~ .aProduct {
margin-top: 0;
background: none;
}
Demo: http://jsfiddle.net/a9W5T/
You can use
:first-child, :nth-of-type(1), :first-of-type or :nth-child(1n)
And why your code donst work, is because you use:
#kasticketProducts:first-child .aProduct
this will take the first element #kasticketProducts, use this instead: #kasticketProducts .aProduct:nth-child(2) {
color: red;
} <-- This will take the first element .aProduct inside your ID element
Another solution would be to style .aProduct, and then override the style for any succeeding occurrences of .aProduct using the general sibling combinator:
#kasticketProducts .aProduct {
// effectively becomes the style for the first occurrence of .aProduct
}
#kasticketProducts .aProduct ~ .aProduct {
// overrides the style set above for all occurrences of .aProduct,
// apart from the first
}
The biggest advantage of this approach is that it doesn't rely on the structure of the markup.
General sibling selectors on MDN
Here's an example
Check the #id, it's case sensitive
Also, be careful with quotes, you are not closing them.
<div id="kasticketProducts">
<div class="aProductHeader">aaa</div>
<div class="aProduct">aaa</div>
<div class="aProductHeader">aaaa</div>
<div class="aProduct">aaa</div>
For the first .aProduct get selected:
#kasticketProducts .aProduct:nth-child(2) {
/* your styles */
}
Sorry for that, thought was for getting the first kasticketProduct. Apologizes.

How to hide the first element with a class name

I have twp elements inside my Div,both have same class name. I want to hide my first element with the class name .cart. I am using the below code.
.component-bottom .component-basket + .cart{
display:none;
}
<div class="component-bottom">
<div class="component-basket">
<div class="cart">
</div>
<div class="cart">
</div>
</div>
</div>
Am I using the correct code?
You can use a direct child selector for the .cart element:
.component-bottom .component-basket > .cart
{
display:none;
}
Now you only want the first element of this selector. There isn't an original selector for this, but you can make a overwrite selector for this.
You can overwrite all but the first one ElementA ~ ElementB:
.component-bottom .component-basket > .cart ~ .cart
{
display:block;
}
This search for all .cart elements inside .component-basket where ANY previous adjacent sibling is .cart. The first of the element doesn't have a previous sibling of this class, so it would not be selected.
This is called a general sibling selector.
jsFiddle
This should support IE7 and above:
Note Requires Windows Internet Explorer 7 or later.
source: http://msdn.microsoft.com/en-us/library/ie/aa358824(v=vs.85).aspx
an easier solution commented by #jrConway:
Make it display: block by default and use:
.component-bottom .component-basket > .cart:first-child
{
display: none;
}
Example
Note that this only work when you use ONLY .cart as child element. Whenever an other class is at the first 'place' it will not work.
Using adjacent sibling selector won't work here, as your element is nested inside .component-basket and hence it fails.. Simple way is to call a class on the element you want to hide, if you cannot change the DOM than you can use first-child or nth-of-type(1)
.component-bottom .component-basket div.cart:nth-of-type(1) {
display:none;
}
Demo
As #Vucko already commented, nth-of-type() is a CSS3 spec pseudo..
Hence if you want to support legacy browsers, you can use Selectivizr,
this will save you a lot of classes/ids.
Stick this in your CSS file:
.hide {
display: none;
}
Then add that class to whatever element you want hidden like so:
<div class="component-bottom">
<div class="component-basket">Foo</div>
<div class="component-basket cart hide">Foo</div>
</div>
The advantage of this method is that you get to re-use that "hide" class anywhere you want.
As understood, check this might help
CSS
.cart{
display:none;
}
.component-bottom .component-basket
{
//some common properties
}
HTML
<div class="component-bottom">
<div class="component-basket cart">component-basket Hidden div</div>
<div class="component-basket">component-basket visible div</div>
</div>
This will hide the div with the cart class (the First div)
Thanks,
Dhiraj

How do you make nth-child work with descendant selectors?

I have this code.
<div class="myDiv">
<div>
I want to be red.
</div>
</div>
<p>I'm some other content on the page</p>
<div class="myDiv">
<div>
I want to be blue.
</div>
</div>
.myDiv div:nth-child(odd) {
color: red;
}
.myDiv div:nth-child(even) {
color: blue;
}
I see why it's not working. It's making every odd div within myDiv be red. What I want it to do is make every odd example of a div within myDiv be red. How can I write that?
Here's a JSFiddle.
There are a couple of problems here. The :nth-child is on the wrong element. The inner divs are always the first child, so the :nth-child(odd) selector works for both. Instead move to
.myDiv:nth-child(odd) div
...however this does not work either because of the <p>. A working solution with your sample is
.myDiv:nth-of-type(odd) div
http://jsfiddle.net/tvKRL/1/
NOTE that the nth-of-type only works because the .myDiv elements are all divs (it's based on the element, not the selector), so the selector ignores the <p>. If there can be another div between .myDivs I don't think any CSS will work for what you want to do.
You can't do this generically, for the reason given by Domenic. To put it simply: there's no selector that lets you filter an existing subset of matched elements.
On the off chance that among your p and div.myDiv siblings the only div elements are the ones with that class anyway, then you could use :nth-of-type() to have it look at those intermediate divs only:
div.myDiv:nth-of-type(odd) div {
color: red;
}
div.myDiv:nth-of-type(even) div {
color: blue;
}
Or if there are other divs without that class which should be excluded, then unless there is some sort of pattern in which they're laid out, you're out of luck.
This is not possible. There is no CSS selector that will do what you want, as you can see by perusing the complete list of selectors.
In general CSS selectors do not "reach out" to encompass elements above the DOM tree of the one selected. You are asking for something even more sophisticated than that, combining characteristics of parent elements with ordinal properties of the targeted elements, even though those targeted elements are distributed among entirely different places in the DOM tree.
Just applynth-childto the first member of the descendant selector, not the last one.
div:nth-of-type(odd) > div {
color: red;
}
div:nth-of-type(even) > div {
color: blue;
}
<div class="myDiv">
<div>
I want to be red.
</div>
</div>
<p>I'm some other content on the page</p>
<div class="myDiv">
<div>
I want to be blue.
</div>
</div>

Stop CSS hierarchy

I have a hierarchy as follows:
<div class="outer">
<h1>Heading</h1>
<p>Paragraph</p>
<p><a>Link</a></p>
<div class="inner">
<h1>Heading</h1>
<p>Paragraph</p>
<p><a>Link</a></p>
</div>
</div>
I want the elements within the outer div to be styled in a certain way, and the elements within the inner div to be styled in another.
However, I don't want to have to pollute my rules for inner elements with resets for every property the outer rules defined.
In the following example, I want to avoid margin: 0px. Note that, of course, my stylesheet is much more complex and resets would be significantly more numerous and annoying.
outer a { margin: 5px; }
inner a { margin: 0px; color: orange; }
My initial reflex is to use the direct child selector >, but that becomes cumbersome for, say, links, strong, spans, etc.
The following example:
outer > a { color: orange; }
Would not style:
<div class="outer"><p><a>Link</a></p></div>
<div class="outer"><strong><a>Link</a></strong></div>
<div class="outer"><ul><li><a>Link</a></li></ul></div>
<div class="outer"><table><tr><td><a>Link</a></td></tr></table></div>
...
I need to find some other way of either
Breaking the hierarchy at inner, without explicitly defining resets.
Limiting the scope of the outer styles to stop at inner.
Is this possible?
Note that rearranging my HTML structure is not possible in the present case.
Is CSS3 selectors an option for you? if yes, may this trick helps:
CSS:
.outer>:not(div) a { color: orange; }
EDIT:
.outer > a, .outer > :not(.inner) a { color: orange; }
jsBin demo
you can use the :not selector:
.outer > *:not(.inner) *