nth-child based in element index - css

I want to use css3 nth-child to select matched elements based in their index in the whole document (like jquery :eq() selector) not based in the parent element.
<div id="container">
<div class="result">
<div class="active">content 1</div>
</div>
<div class="result">
<div class="active">content 2</div>
</div>
<div class="result">
<div class="active">content 2</div>
</div>
</div>
This css code select all elements because every .active is 1st child respective to the parent .result
.active:nth-child(1) {
background: red;
}
I tried also to make the body as parent
body > .active:nth-child(1) {
background: red;
}
But it can't do the job.
I want nth-child(1) selects content 1
and nth-child(2) selects content 2

I think you want to use nth-child on .result.
#container .result:nth-child(1) .active {
background: red;
}
JSBin

Related

Select a div that contains a div having specific attribute value or class [duplicate]

This question already has answers here:
Is there a CSS parent selector?
(33 answers)
Closed 2 months ago.
I want to select a div that contains another div with specific class or specific attribute value. I have tried these: (but it selects the child not the parent/container)
div div[data-value="hi"]
div>div[data-value="hi"]
div div.any
div>div.any
(example) the one with attribute value:
<div>
<div data-value="hi">example</div>
</div>
(example) or the one below with class:
<div>
<div class="any">example</div>
</div>
Please do not suggest nth-child as their will be couple of div and div position is random as the below example:
<div>
<div class="other">example</div>
</div>
<div>
<div class="any">example</div>
</div>
<div>
<div class="other">example</div>
</div>
<div>
<div class="other">example</div>
</div>
Please let me know if it even possible with only CSS, Thank you for your help.
If I've understood correctly and you want to target the PARENT should it contain a child with a given class or attribute, then you want the :has pseudo-selector. Note, that it isn't available in all browsers/versions yet but has good availability see: Can I Use :has selector
div {
height: 50px;
width: 100%;
}
div:has(div.other) {
background: red;
}
div:has(div[data-value="hi"]) {
background: orange;
}
<div>
<div class="other">example</div>
</div>
<div>
<div class="any">example</div>
</div>
<div>
<div class="other">example</div>
</div>
<div>
<div data-value="hi">example</div>
</div>
just directly select its class or data-value
div > .any {
background: red;
}
div > [data-value="other"] {
background: blue;
}
<div>
<div data-value="other">example</div>
</div>
<div>
<div class="any">example</div>
</div>
<div>
<div class="other">example</div>
</div>
<div>
<div class="other">example</div>
</div>

Is it possible to have scss selector that selects class only if it is last child of other element?

I have layout that is generated dynamically so order of elements could change. Each element that is part of this layout has its own different class. I want to be able to select element of certain class but only if it is last child of its parent to apply styling. If element with different class is last child of its parent, it should not be selected. Is it possible to have this kind of scss selector and achieve this functionality without using javascript?
Example:
<div class="parent">
<div class="child1">Hello!</div>
<div class="child2">Hello!</div>
<div class="child3">Hello!</div>
</div>
I want to select element with class child3 only if it is last child of div with class parent.
So if child2 class element is last child of div class parent it is not selected, for example here:
<div class="parent">
<div class="child1">Hello!</div>
<div class="child3">Hello!</div>
<div class="child2">Hello!</div>
</div>
Yes, and this is the normal CSS behaviour. You can do something like this:
.parent .child3:last-child {}
This is a rule that selects:
a .child3 element inside .parent.
.child3 element comes as the last, there's no other elements after that including text.
For SCSS, you can do something like this:
.parent {
.child3 {
&:last-child {
// Rules.
}
}
}
Example Snippet
.parent .child3:last-child {
background: #ccf;
}
<strong>Trial 1</strong>
<div class="parent">
<div class="child1">Hello!</div>
<div class="child2">Hello!</div>
<div class="child3">Hello!</div>
</div>
<hr />
<strong>Trial 2</strong>
<div class="parent">
<div class="child1">Hello!</div>
<div class="child3">Hello!</div>
<div class="child2">Hello!</div>
</div>
Preview
You can select elements by their attributes, so something like this would achieve your goal.
.parent div {
width: 50px;
height: 50px;
background-color: blue;
border: solid 1px black;
}
.parent div:last-of-type[class="child3"] {
background-color: red;
}
<div class="parent">
<div class="child1">Hello!</div>
<div class="child3">Hello!</div>
<div class="child2">Hello!</div>
</div>
<div class="parent">
<div class="child1">Hello!</div>
<div class="child2">Hello!</div>
<div class="child3">Hello!</div>
</div>
https://www.w3schools.com/cssref/css_selectors.asp

Complex css to only select first instance of an element

I need to be able to apply a width to a div but only if any of it's parents have a class of grid.
Obviously the child selector allows me to select an element if it's a direct child of the grid div:
.grid > .test {
width: 300px;
}
<div class="grid">
<div class="test"></div>
</div>
I need a selector that allows me to select the .test div even if its not the direct child of grid:
<div class="grid">
<div class="another">
<div class="test"></div>
</div>
</div>
You'd imagine that I could just use a bog-standard selector like:
.grid .test
Problem with this is that I only want to match the first instance of the .test div. The above selector matches all instances even if they're nested. Any subsequent div's with a class of test should be ignored.
<div class="grid">
<div class="another">
<div class="test">
<div class="test"></div> <!-- this should be ignored somehow -->
</div>
</div>
</div>
http://jsfiddle.net/hs3G9/1/
Is there any way to do this with css or do I need to resort to JS?
There isn’t a way of excluding that inner .test element without JavaScript. If the two had been siblings, you could do something like:
.grid .test:first-of-type {}
edit: Right you are; you can cook something up with the :not selector.
Using the :first-child selector in css should work.
So for you case:
<style>
.grid .test:first-child {
background-color: rgba(0,0,0,.2);
}
</style>
<div class="grid">
<div class="another">
<div class="test">
<div class="test"></div> <!-- this should be ignored somehow -->
</div>
</div>
</div>

Alternate row colors between two divs

I'm not sure if this is possible in CSS, but if it is, I would appreciate some help.
I have HTML similar to the following:
<div class="group"></div>
<div class="group"></div>
<div class="group subgroup"></div>
<div class="row"></div>
<div class="row"></div>
<div class="group"></div>
<div class="group subgroup"></div>
<div class="row"></div>
Is it possible to alternate the background colors of the row classes? Always starting with the same color? I've been having trouble achieving this using nth-child and I'm assuming it's because of the group/subgroup classes.
Manual html markup in jsfiddle of an example data set that could be returned and how it is designed to be styled:
http://jsfiddle.net/Qr5Za/
'always starting with the same color' means that the first row after
group/subgroup starts with red
If so, you can set background-color of the first .row red and the others magenta by:
.group ~ .row { /* select all rows comes after each group */
background-color: magenta;
}
.group + .row { /* select and override the first row after each group */
background-color: red;
}
JSBin Demo
These selectors are called General sibling combinator ~ and Adjacent sibling combinator +, you can find more details here.
Update
All new CSS3 selectors like :nth-child(n), :nth-of-type(n) matches every element that is the nth child or type, of its parent.
So the only way to achieve this, is putting .rows in a wrapper for each block:
<div class="group">This is a group</div>
<div class="group subgroup">This is a subgroup</div>
<div class="wrap">
<div class="row">This is the first row</div>
<div class="row">This is the second row</div>
<div class="row">This is the third row</div>
<div class="row">This is the forth row</div>
</div>
And selecting odd and even rows based on their position in the .wraper (their parent):
.row:nth-child(odd) {
background-color: red;
}
.row:nth-child(even) {
background-color: magenta;
}
JSBin Demo #2
.row:nth-of-type(n) + .row:nth-of-type(even){
background: green;
}
.row:nth-of-type(n) + .row:nth-of-type(odd){
background: orange;
}
.group.subgroup + .row:nth-of-type(n) {
background: blue;
}
Updated Demo

How can I use hover in a child without the parent's hover being activated?

My code can add divs as child or sibling, I've created two classes and two :hover for each class but when I put the mouse on a child the parent hover is activated as well.
.Group {
background-color: white;
}
.Group2 {
background-color: white;
}
.Group:hover {
background-color: yellow;
}
.Group2:hover {
background-color: red;
}
<div class="Group">
root
<div class="Group">1st child
<div class="Group2">2nd child
<div class="Group">3rd child</div>
</div>
</div>
<div class="Group">1st child</div>
</div>
If you hover over a child element, you're also hovering over the parent, there's no way around that.
What you could do is set a different or additional class on the 1st child elements that don't have further children.
Highlighting background colors in nested blocks when hovering
If you are trying to activate the background colors of the nested div blocks, I think you might be looking for the following.
For the HTML, use distinct class names to identify each layer of nested div blocks:
<div class="Group">root
<div class="Group1">1st child
<div class="Group2">2nd child
<div class="Group3">3rd child</div>
</div>
</div>
<div class="Group1">1st child</div>
</div>
and the CSS:
.Group, .Group1, .Group2, .Group3 {
background-color:transparent;
}
.Group:hover {
background-color:yellow;
}
.Group1:hover {
background-color:pink;
}
.Group2:hover {
background-color:red;
}
.Group3:hover {
background-color:orange;
}
Demo fiddle: http://jsfiddle.net/audetwebdesign/Scr9G/
As you mouse over each nested div successively, the background color changes in sequence.
If you are trying to target a nested element with :hover without the effect bubbling up through the parent/ancestor blocks, you will need to use JavaScript/jQuery to create the selection rules that you need.
Quirky Hack Using <p> Tags
The following construction exhibits the behavior that the OP would like to see:
<p class="Group">root
<p class="Group">1st child
<p class="Group2">2nd child
<p class="Group">3rd child</p>
</p>
</p>
<p class="Group">1st child</p>
</p>
and the CSS is as before:
.Group {
background-color:white;
}
.Group2 {
background-color:white;
}
.Group:hover {
background-color:yellow;
}
.Group2:hover {
background-color:red;
}
Second demo fiddle: http://jsfiddle.net/audetwebdesign/cf2mn/
In this case, the OP was trying to nest <p> tags, which actually do not work like nesting other block elements like <div>.
When using <p> tags, the closing </p> tag is optional if followed by other flow elements like p, div, ul and so on.
In this case, the HTML snippet show above is equivalent to:
<p class="Group">root</p>
<p class="Group">1st child</p>
<p class="Group2">2nd child</p>
<p class="Group">3rd child</p>
<p class="Group">1st child</p>
which means that all the p tabs are siblings and there are no parent-child relationships, which is why the CSS appears to be working as the OP desired.
If div tags had been used instead of p tags, the resulting DOM would have exhibited the parent-child relationships and the CSS would have shown the original behavior that the OP did not want.
Using the p tags may give the desired effect for the CSS, but it works only because the DOM elements are siblings instead of parent-child. (In addition, the nested p tags will not validate.)
It is worth noting that:
CSS 2.1 does not define if the parent of an element that is ':active' or ':hover' is also in that state.
so it is better not to rely on the state of the parent element when apply a pseudo-element on a child element.
References:
About :hover: http://www.w3.org/TR/CSS2/selector.html#dynamic-pseudo-classes
About optional closing of p tag: http://www.w3.org/TR/html-markup/p.html#p
There's no way to prevent parent elements to get background color.. rather use this code
<div class="root">
Main Root
<div class="group">
First One
</div>
<div class="group2">
Second One
</div>
<div class="group">
Third One
</div>
.group:hover {
background: yellow;
}
.group2:hover {
background: red;
}
SEE THE DEMO HERE
Give separate ids to the divs and when a child div is hovered over, change its background image color and remove the background color of the parent all at the same time. I guess that is the only way around this
The simplest and best way is probably to use any other element, li for instance.
css:
.Group, .Group2, .Group3
{
background:white;
display: block;
list-style: none;
}
.parent
{
margin: 0;
display: block;
padding: 0;
}
.Group:hover
{
background: yellow;
}
.Group2:hover
{
background: red;
}
.Group3:hover
{
background: yellow;
}
html:
<ul class="parent" >
<li class="Group" >root
<li class="Group">1st child
<li class="Group2">2nd child
<li class="Group3">3rd child</li>
</li >
</li >
<li class="Group">1st child</li >
</li>
</ul>
You should add sub-element for content and use element+element pseudo selector.
.group-content:hover {
background-color: yellow;
}
.group-content:hover + .group {
background-color: red;
}
<div class="group">
<div class="group-content">1st child</div>
<div class="group">
<div class="group-content">2nd child</div>
<div class="group">
<div class="group-content">3nd child</div>
</div>
</div>
</div>
<div class="group">
<div class="group-content">1st child</div>
</div>

Resources