Reputation: 677
I have the following structure that I've simplified down, the goal here was to set the span with the class "partA" background color to pink because the input has the class "state".
The internal structure of the "container" cannot change.
So the end result for this example would be the first "Content" label would be highlighted pink.
Note that there can be any number of "container"s in any order throughout the page structure, so just selecting the first container isn't a suitable solution.
<span class="container">
<span class="item">
<span class="partA">Content</span>
<span class="partB">A</span>
</span>
<input class="element state" />
</span>
<span class="container">
<span class="item">
<span class="partA">Content</span>
<span class="partB">B</span>
</span>
<input class="element" />
</span>
I thought the general sibling selector may be the solution, but it doesn't seem to work - I believe because it's a sibling of the parent, not the element itself. I tried both ways round in case I had made a mistake:
.partA ~ .state { background-color: pink; }
.state ~ .partA { background-color: pink; }
I've created a JSFiddle with this structure.
Can anyone provide me a selector which will accomplish this? I would like to avoid JS if at all possible.
Upvotes: 0
Views: 2271
Reputation: 206636
Since it's not possible to back-track selectors using pure CSS
let's find a solution adding the minimal effort:
Place this before the closing </body>
tag:
<script>
// Add PINK background to the first `.partA` element whose uncle has `.state`
var stateClass = document.getElementsByClassName("state");
for(var i=0; i<stateClass.length; i++){
stateClass[i].parentElement.getElementsByClassName("partA")[0].style.background = "pink";
}
</script>
var stateClass = document.getElementsByClassName("state");
for(var i=0; i<stateClass.length; i++){
stateClass[i].parentElement.getElementsByClassName("partA")[0].style.background = "pink"
}
<span class="container">
<span class="item">
<span class="partA">Content</span>
<span class="partB">A</span>
</span>
<input class="element state" />
</span>
<span class="container">
<span class="item">
<span class="partA">Content</span>
<span class="partB">B</span>
</span>
<input class="element" />
</span>
Upvotes: 0
Reputation: 2230
As per this CSS Tricks article
"there are no parent selectors in CSS, not even in CSS3"
The article is worth a read, but I suspect the only way you are going to be able to do this is with javascript.
Upvotes: 1
Reputation: 537
I'll offer a sort-of-solution that might work for you.
HTML
<span class="container">
<input class="element state" />
<span class="item">
<span class="partA">Content</span>
<span class="partB">A</span>
</span>
CSS
.state ~ .item .partA { background-color: pink; }
This way you swap the DOM elements around, which you than could position with CSS. See the fiddle here: http://jsfiddle.net/edkyy360/4/
Upvotes: 0
Reputation: 16841
CSS renders always in a forward sequence. So, what you want could only work if the input
came first in the structure:
.state ~ span .partA { background-color: pink; }
<span class="container">
<input class="element state" />
<span class="item">
<span class="partA">Content</span>
<span class="partB">A</span>
</span>
</span>
<span class="container">
<input class="element" />
<span class="item">
<span class="partA">Content</span>
<span class="partB">B</span>
</span>
</span>
Upvotes: 1