CSS3 selector to find the 2nd div of the same class - css

I need a CSS selector that can find the 2nd div of 2 that has the same class. I've looked at nth-child() but it's not what I want since I can't see a way to further clarify what class I want. These 2 divs will be siblings in the document if that helps.
My HTML looks something like this:
<div class="foo">...</div>
<div class="bar">...</div>
<div class="baz">...</div>
<div class="bar">...</div>
And I want the 2nd div.bar (or the last div.bar would work too).

Selectors can be combined:
.bar:nth-child(2)
means "thing that has class bar" that is also the 2nd child.

My original answer regarding :nth-of-type is simply wrong. Thanks to Paul for pointing this out.
The word "type" there refers only to the "element type" (like div). It turns out that the selectors div.bar:nth-of-type(2) and div:nth-of-type(2).bar mean the same thing. Both select elements that [a] are the second div of their parent, and [b] have class bar.
So the only pure CSS solution left that I'm aware of, if you want to select all elements of a certain selector except the first, is the general sibling selector:
.bar ~ .bar
http://www.w3schools.com/cssref/sel_gen_sibling.asp
My original (wrong) answer follows:
With the arrival of CSS3, there is another option. It may not have been available when the question was first asked:
.bar:nth-of-type(2)
http://www.w3schools.com/cssref/sel_nth-of-type.asp
This selects the second element that satisfies the .bar selector.
If you want the second and last of a specific kind of element (or all of them except the first), the general sibling selector would also work fine:
.bar ~ .bar
http://www.w3schools.com/cssref/sel_gen_sibling.asp
It's shorter. But of course, we don't like to duplicate code, right? :-)

UPDATE: This answer was originally written in 2008 when nth-of-type support was unreliable at best. Today I'd say you could safely use something like .bar:nth-of-type(2), unless you have to support IE8 and older.
Original answer from 2008 follows (Note that I would not recommend this anymore!):
If you can use Prototype JS you can use this code to set some style values, or add another classname:
// set style:
$$('div.theclassname')[1].setStyle({ backgroundColor: '#900', fontSize: '1.2em' });
// OR add class name:
$$('div.theclassname')[1].addClassName('secondclass'); // pun intentded...
(I didn't test this code, and it doesn't check if there actually is a second div present, but something like this should work.)
But if you're generating the html serverside you might just as well add an extra class on the second item...

HTML
<h1> Target Bar Elements </h1>
<div class="foo">Foo Element</div>
<div class="bar">Bar Element</div>
<div class="baz">Baz Element</div>
<div class="bar">Bar Second Element</div>
<div class="jar">Jar Element</div>
<div class="kar">Kar Element</div>
<div class="bar">Bar Third Element</div>
CSS
.bar {background:red;}
.bar~.bar {background:green;}
.bar~.bar~.bar {background:yellow;}
DEMO
https://jsfiddle.net/ssuryar/6ka13xve/

What exactly is the structure of your HTML?
The previous CSS will work if the HTML is as such:
CSS
.foo:nth-child(2)
HTML
<div>
<div class="foo"></div>
<div class="foo">Find me</div>
...
</div>
But if you have the following HTML it will not work.
<div>
<div class="other"></div>
<div class="foo"></div>
<div class="foo">Find me</div>
...
</div>
Simple put, there is no selector for the getting the index of the matches from the rest of the selector before it.

And for people who are looking for a jQuery compatible answer:
$('.foo:eq(1)').css('color', 'red');
HTML:
<div>
<div class="other"></div>
<div class="foo"></div>
<div class="foo">Find me</div>
...

.parent_class div:first-child + div
I just used the above to find the second div by chaining first-child with the + selector.

Is there a reason that you can't do this via Javascript? My advice would be to target the selectors with a universal rule (.foo) and then parse back over to get the last foo with Javascript and set any additional styling you'll need.
Or as suggested by Stein, just add two classes if you can:
<div class="foo"></div>
<div class="foo last"></div>
.foo {}
.foo.last {}

First you must select the parent element and set :nth-of-type(n) for the parent and then select the element you want. something like this :
#topmenu li:nth-of-type(2) ul.childUl {
This will select the second submenu from topmenu. #topmenu li is the parent element.
HTML:
<ul id="topmenu">
<li>
<ul class="childUl">
<li></li>
<li></li>
<li></li>
</ul>
</li>
<li>
<ul class="childUl">
<li></li>
<li></li>
<li></li>
</ul>
</li>
<li>
<ul class="childUl">
<li></li>
<li></li>
<li></li>
</ul>
</li>

Related

How do i style two same class divs differently?

So basically I've got a setup that spits out the code in the following fashion..
<div class="parent">
<div class="subparent">
<div class="TARGETCLASS"></div>
</div>
<div class="subparent">
<div class="TARGETCLASS"></div>
</div>
</div> //close for the parent class
Now what I'm trying to do is to style "TARGETCLASS" that comes above one way and the "TARGETCLASS" that comes second in another way. I tried n-th child, but unable to achieve the result I'm looking for. There's no way to add additional classes or ID to the existing "TARGETCLASS" class. Otherwise I wouldn't be posting this question :)
Also, the "subparent" class also is same. for both the targetclass classes. That's the issue
Thanks in advance for taking your time to answer this question for me.
Cheers!
Looks like you've got some mal-formed tags in your html. And nth-child should work just fine. Also, make sure you place the nth-child selector on the subparent class, and not TARGETCLASS. It's common to mis-place the child selector. Try this:
<div class="parent">
<div class="subparent">
<div class="TARGETCLASS">
first-child
</div>
</div>
<div class="subparent">
<div class="TARGETCLASS">
second-child
</div>
</div>
</div>
<style>
.parent .subparent .TARGETCLASS {
background-color:#f00;
}
.parent .subparent:nth-child(1) .TARGETCLASS {
background-color:#0f0;
}
</style>
fiddle: https://jsfiddle.net/8ejxokuj/
I would use nth-of-type selector like so:
.parent{}
.parent > .subparent {} //targets both subparents
.parent > .subparent:nth-of-type(2) {} //targets the second subparent
.parent > .subparent:nth-of-type(2) > .TARGETCLASS{} //targets the child of the second subparent
The nth-of-type() selector enables you to style a specific element amongst a series, in this case we targeted the second .subparent then specified the child we needed.
I hope this helps!
It seems, it is working by the nth child.
it is about how childrens are called. Not like "Ask parent to find nth child, but ask child, how far is he from parent"
.parent .subparent:nth-child(1) {background: #FEE; color:RED;}
.parent .subparent:nth-child(2) {background: #EEF; color:blue;}
<div class="parent">
<div class="subparent">
<div class="TARGETCLASS">aaa</div>
</div>
<div class="subparent">
<div class="TARGETCLASS">bbb</div>
</div>
//close for the parent class
</div>

CSS Select Sibling of An Element with A Specific Sub-Element?

The snippet below is a part of a much larger structure with many .step elements.
I need to match all .stepText elements that are next to .stepTitleAndImages ul.standard
In other words, match all .stepText elements that have .step parent that has .stepTitleAndImages child that has .stepImages.standard child
<div class="step">
<div class="stepTitleAndImages">
<h3 class="stepTitle"></h3>
<ul class="stepImages standard"></ul>
<div class="clearer"></div>
</div>
<div class="stepText "></div> **HOW TO SELECT ALL ELEMENTS LIKE THIS ONE?**
<div class="clearer"></div>
</div>
<div class="step">
<div class="stepTitleAndImages">
<h3 class="stepTitle"></h3>
<ul class="stepImages medium"></ul>
<div class="clearer"></div>
</div>
<div class="stepText "></div>
<div class="clearer"></div>
</div>
PS: I cannot modify the HTML. Cannot use anything other than pure CSS.
Just use this for selecting first case
.step:nth-child(1) .stepText {
... Your CSS here
}
For second one use
.step:nth-child(2) .stepText {
... Your CSS here
}
For selecting both use
.step .stepText {
... Your CSS here
}
Then you should require jquery for that
Selecting Parents sibling is not possible only with pure CSS yet, You can achieve this by a single line of jquery:
$('ul.standard').parent().siblings(".stepText").css(...your CSS here);
This cannot be done with your HTML structure and with pure CSS. The closest solution to your problem, changing the HTML structure and with pure CSS, would be to move the standard class to its parent tag:
<div class="stepTitleAndImages standard">
<h3 class="stepTitle"></h3>
<ul class="stepImages"></ul>
<div class="clearer"></div>
</div>
This would allow you to use the adjacent sibling selector (+), which matches the second selector if it's the direct next sibling of the first, like this:
.stepTitleAndImages.standard + .stepText {
/* Styles */
}
A more flexible approach would be to use the general sibling selector which would match any sibling preceded by the first selector, not only the direct next one:
.stepTitleAndImages.standard ~ .stepText {
/* Styles */
}
The :has pseudo-class is in development by Mozilla, but it hasn't hit any stable browsers yet. With it, and with your HTML structure, you could go:
.stepTitleAndImages:has(.standard) + .stepText {
/* Styles */
}
Unfortunately, currently you can't solve this in any other way with CSS (and with your HTML structure) only.

Hovering and changing div lower down in DOM with css only?

If I have tabs like this in html:
<ul class="qtabs">
<li>tab 1 title</li>
<li class="active">tab 2 title</li>
<li>tab 3 title</li>
</ul>
<div class="tab-container">
<div id="tab1">
<div class="tab-content">text, text, text, text....</div>
</div>
<div id="tab2" style="display:none;">
<div class="tab-content">text, text, text, text....</div>
</div>
<div id="tab2" style="display:none;">
<div class="tab-content">text, text, text, text....</div>
</div>
</div>
Is it possible with CSS only to make hover-effect (change textcolor of .tab-content for the tab that user is hovering over ? (it's ok if it only works with css3)
Possible duplciate?
Is there any way to hover over one element and affect a different element?
Kind of, but nothing has happened in 4 years then? :-)
You can't get exactly what you want unfortunately, but perhaps this is close enough for what you need.
If you allow the hover to work on .qtabs instead of each individually li. Then you can use a combination of the sibling selector and the standard descendant selector to meet your needs:
.qtabs:hover ~ .tab-container .tab-content {
color:red;
}
Here is a working example
The benefit of this approach is that it requires no changes to your existing HTML structure, and without JavaScript which I assume you are trying to avoid for whatever reason.
Need each tab page to have a different colour?
Then why not try our new and improved version
The problem is that you need to check the children of ul to see which is active and then reverse back up the DOM to get to tab-content. This is how you could write that rule...
ul li.active:hover + .tab-container #tab1 .tab-content {color:#f00;}
HOWEVER it is not currently possible to do this in CSS.
This behaviour is frequently requested and is more commonly known as a "parent selector" however, .
If you can change your markup and maybe include something on the ul which will enable you to identify the tab then you could do something like this:
ul.activeTab1:hover + .tab-container #tab1 .tab-content {color:#f00;}
ul.activeTab2:hover + .tab-container #tab2 .tab-content {color:#f00;}
which would be almost what I think you are after..
http://jsfiddle.net/qdgtx4jc/

css target first li in a div of many divs

so I have been trying all this stuff with first-child and everything and none seem to be working. If I have a div set up as such:
<div class="content">
<div class="thing">
abd
</div>
<div class="thing">
</div>
<div class="thing">
123
</div>
<div class="thing">
<li class="list" goal="target">
1
</li>
</div>
<div class="thing">
<li class="list">
2
</li>
</div>
<div class="thing">
<li class="list">
3
</li>
</div>
<div class="thing">
<li class="list">
4
</li>
</div>
</div>
what line of css that will be able to target only the first li element in the .content div (the one with the attribute goal="target")
now this can be fairly messy and there can be anywhere from 0 to 10 divs without a li before the first that contains one.
I have tried nearly anything with first-child, but it always targets every single li because they are in divs.
here is a jsfiddle if you want to try things
In CSS the format is grandparent parent element child... and :nth-child gives you the element the number specified down, so for your case that would be
.content .thing:nth-child(4) li {
/* CSS goes here */
}
In your example .content is the grandparent, .thing (the fourth one) is the parent, and of course the li is the element. Spaces are required for distinguishing in between levels in CSS.
Here is a working jsFiddle
Edit Without it being hard coded it's impossible to select the first li no matter who it's parent is without javascript.
Here is a jQuery fix:
$('.content').find("li").eq(0).css({ /* CSS goes here */});
Here is a straight javascript fix:
var elems = document.getElementsByTagName('li')[0];
elems.style.property="value";
OK first things first, goal is an invalid attribute so you shouldn't be using it. If you need custom attributes you should be using data-attributes
In order to target an element by attribute you should be using an attribute selector in your case the following selector would work.
li[goal="target"]{
/* Your styles go here.*/
}

selecting adjacent elements in CSS

In CSS,
Is it possible to match the elements which have a certain property followed by an element which has another property, ie.
Let's consider
<div my-custom-attribute="0">
</div>
<div my-custom-attribute="1">
</div>
I want to select all elements which have my-custom-attribute equal 0 that are followed by elements which have my-custom-attribute equals 1
You can do this in reverse order by attribute selectors
div[my-custom-attribute="0"] > div[my-custom-attribute="1"]
or
<div id="parent">
<div my-custom-attribute="0">
</div>
<div my-custom-attribute="1">
</div>
</div>
#parent > div[my-custom-attribute]:not(:first-child)
I think this is what you want :
div[my-custom-attribute="0"] + div[my-custom-attribute="1"] {
color:red;
}
DEMO
Refer to this link for more info on selectors.
Thank you for your answers. I ended up using jQuery selectors instead of CSS.
For my case, the jQuery prev() worked
$($('div[my-custom-attribute="1"]').prev('div[my-custom-attribute="0"]'))

Resources