CSS style for parent instead of child? - css

I am using jquery to insert html I get from the server into a div. Based on the div contents i'd like to adjust the syle of the container. I wrote up a simple html test. How do I tell css to apply this site when it has X child? After googling I tried :has and :contains with neither working. I don't want to keep my styles in JS as css makes more sense.
Demo: http://jsfiddle.net/wd9fk/
html
<div id="a"><div id="b">B</div></div>
<div id="a"><div id="c">C</div></div>
css
#a { height: 400px; border: 1px solid red; }
#b { height: 200px; }
#a :has #b { height: 300px; border: 1px solid blue; }

You simply cannot traverse up the DOM in CSS. You will need to use JavaScript.
Here is an article explaining why: http://snook.ca/archives/html_and_css/css-parent-selectors
Long story short, it's due to the way CSS is read by the browser, and by introducing it, it would increase the performance hit by a factor of ten (at least!), because it would need to read every single node multiple times to see whether or not it fits the profile.
It's a nice thought, but it's simply not viable.

There is no parent selector for CSS yet, there are plans and it is being discussed though. In CSS Selectors level 4, a subject selector has been proposed, which would let you refer to elements this way:
ol! > li:only-child
Which then reads: “an ol element that contains a single li element” (this syntax is a proposal though), and would let you style the parent ol element.
If this proposal succeeds, subject selectors would be available in the next version of CSS selectors.
For now, Javascript is the way to go, until the subject selector becomes a standard.

You cannot traverse up the DOM to get the parent selector of current matching elements.
But you can do it with jQuery quite easy like this:
$('#Default a span.active').closest('.vehicle_details').css('background-color','#444');
Fiddle Demo

#a > #b { height: 300px; border: 1px solid blue; }
Not sure if this is what you wanted, but give it a try.
Regards.

Related

Overriding previously set CSS

My css:
.pic img:hover {
border: 1px black solid;
}
My html:
<div class="pic">
<img src="hey.jpg">
<img class="overlay" src="overlay.jpg">
</div>
I have an "overlay.jpg" that is placed in the bottom corner of the first image.
Problem with the css is that the overlay gets the :hover effect too.
The actual code is very complicated, I know the best solution would be to add a class to the first image and hover only that, but that will take more time than what i currently have to get this fixed.
The code has a class for the overlay images though, so I'm asking if theres a way to override the hover by setting some other css for the overlay class.
However .overlay:hover { border: none; } does not do the trick, even if i put it after the css above.
Your rule is less specific than the previous one so it is getting overridden.
You have to change it to:
.pic .overlay:hover { border: none; }
The concept
Specificity is the means by which a browser decides which
property values are the most relevant to an element and gets to be
applied. Specificity is only based on the matching rules which are
composed of selectors of different sorts.
How is it calculated?
The specificity is calculated on the
concatenation of the count of each selectors type. It is not a weight
that is applied to the corresponding matching expression.
In case of specificity equality, the latest declaration found in the
CSS is applied to the element.
Reference: Specificity
As long as overlay always comes after the first image, you can use :first-child to pick only the first image:
.pic img:first-child:hover {
border: 1px black solid;
}
It's supported in everything (excluding IE6, but I don't count that as a thing.)
You can also use the :not selector:
.pic img:not(.overlay):hover {
border: 1px black solid;
}
This way you won't have to worry about the order of the images and also don't have to worry about specificity by including another reset style.

Force to use style for a selector, no matter where it is in the dom

Say I would like to define a numbered circle, that looks like this:
http://jsfiddle.net/edi9999/6QJyX/
.number
{
border-radius: 50%;
width: 32px;
height: 24px;
text-align: center;
padding-top:8px;
font-size: 14px;
display:inline-block;
line-height: 16px;
margin-left:8px;
color:white;
background-color:black;
border-color:white;
}
I would like to add importance to the selector, so that no matter in what context the element is, an element with class number looks the same.
Here's an example of the code breaking: http://jsfiddle.net/edi9999/6QJyX/2/
A way to do this would be to add !important to all properties of the CSS, but I wonder if they could be other solutions, because it is a bit crappy.
I have added the private tag as that seems a bit like code-encapsulation.
Your best option is to increase the specificity of the selector. Other than that there is not much you can do.
#id .number
The ID selector will increase specificity so that only another ID in a selector will be able to override it.
http://jsfiddle.net/6QJyX/3/
Increasing the specificity of selectors will only lead to specificity wars (which leads to anger, which leads to hate, which leads to suffering). I would suggest decreasing the specificity of the selector that's causing the problem.
Pseudo code below:
.number {...}
.card span {...} // this selector is questionable
<div.number> this is styled correctly </div>
<div.card>
<span.number> this is styled incorrectly </span>
</div>
Why do all .card spans need to be styled a particular way? It seems as if the second selector is more like a grenade and less like a sniper—that is, it targets a blanket set of elements rather than just the ones you need.

Is there any real advantage to using nested selectors?

if #div2 is contained within #div1 is there any real advantage to referring to that in the css stylesheet? like this:
#div1 {
display:block;
}
#div1 #div2 {
background-color:#e0e0e0;
}
and then similarly. i have a table ID and then it's table headers
#myTable {
width:100%;
}
#myTable #productName{
width:75%;
}
The only advantage is that you can be more specific, for example create a rule that applies to some element only if it placed inside another one. But in most cases, there is no reason for that, and it may hurt the performance of your css (plus it creates code duplication, in case you want to change the parent ID).
In your case the selectors are IDs, and since there can be only one element with each ID, there are even less advantages for nested selectors, and probably you don't need them.
Read this article for more deep explanations.
As element-IDs are unique in the DOM the selected context is unambiguous in the given examples and there is no advantage whatsoever.
However, when you are working with classes nested selectors become very useful.
Generally its not useful to nest id selectors, but there are subtle differences, in the following, the nested rule has a higher specificity and the background will be red
HTML
<div id="outer">
<div id="inner">foo</div>
</div>
CSS
#outer #inner {
background-color: red;
}
#inner {
background-color: blue;
}
The rules for specificity are outline in the css spec.
That being said, classes are usually the way to go, but this can be useful for changing the styles of elements based on their container (if for some odd reason you cant/wont use classes)

CSS3 transition, target element before hover element

I’m trying to learn a bit more about the CSS3 transitions and “cool stuff”. So I have some nifty animations on my site, and I did some google research that helped me out quite a bit.
I wanted to select an element outside of my hover element. I found out that using the + sign you can target an element that comes after the hover element. A small example (in LESS):
header{
display: inline-block;
div#bg_2{
color:#000;
}
div#container{
float:left;
&:hover{
& + nav {
ul{
opacity: 0;
}
li{
.transition(1200ms, ease-in-out);
margin-left:-100px;
}
}
}
}
nav{
height:30px;
}
}
So this example allows me to give a transition to the element after the hover element. But my question is, is it possible to do the reverse? To target the element before the hover element? In the example, the bg_2 element.
The ! subject selector in the CSS Selectors 4 draft specification would be a way to select a previous element. It proposes that instead of writing .one + .two { … } to style .two, you could write !.one + .two { … } to style .one.
However, ! is currently not implemented in any browser. And the CSS Selectors 4 specification can still change, because it is a draft. Also, the spec currently marks the ! subject selector as being in the “complete” profile, which is meant to be used by JavaScript, but not in the “fast” profile, which CSS must use.
Since you can’t use !, there is currently no way to select what you want with pure CSS.
See also this answer about there being no parent selector, which links to the CSS specifications where you can find all defined selectors.
CSS alone can't currently achieve what you're after. We have sibling selectors (+ and ~), but the element being targeted must come after the first element.*
As a simple example, check out this fiddle. Given this markup:
<p class="one">One</p>
<p class="two">Two</p>
and this CSS:
.one ~ .two { background: red; }
.two ~ .one { background: green; }
You might expect .one to end up green and .two red. In reality, only .two receives a background colour, because the second line is trying to style an element that comes earlier in the DOM.
* + is the adjacent sibling combinator, ~ the general sibling combinator. See this CSS Tricks article for details. They are very similar: + will only target an element that is directly after another specific element whereas ~ will target a sibling that appear anywhere after it.

Alternating Row Colours in CSS3 With DOM changing

I'm using the following css to alternate the background colour of li elements, but need the css to be maintained if the rows get the .hidden class assigned to them (.hidden class being display: none;).
ul li:not(.hidden):nth-child(odd) {
background: #fff;
}
ul li:not(.hidden):nth-child(even) {
background: #f4f4f4;
}
Any ideas on how to keep the alternating colours while adding / removing li elements to / from the ul? Please only give a CSS based solution if possible. I may have to do it in JS but would prefer not to!
Cheers
Due to the way the :not() pseudo-class works, you cannot use it to filter elements out of the DOM to obtain a subset of elements on which to apply styles. See this answer for the nitty gritty.
EDIT: Apparently my solution below isn't supposed to work either. I need to take a break from answering questions or something. So I guess the only other feasible route may be to do this with JavaScript. I'm keeping this post here instead of deleting as I don't want to take the comments down with it.
To this end, if you can modify the HTML, you can instead use a class that is common to all your lis and target that instead, in conjunction with :nth-of-type():
ul li.shown:nth-of-type(odd) {
background: #fff;
}
ul li.shown:nth-of-type(even) {
background: #f4f4f4;
}
What if you changed your .hidden to the following
.hidden {height:0px; overflow:hidden}
I haven't tested this code at all, but the elements would still be in the DOM for manipulation yet shouldn't be visible to the user.

Resources