Opposite of adjacent sibling selector? - css

Please check this fiddle - http://jsfiddle.net/vfMsS/. I need to write selectors which select the element after the "active" element and the element before it. The "before" part doesn't seem to work. How to select the element before the a.active?

Like BoltClock said, there is no way to due this in current day browsers.
However, I believe it is possible in CSS.
The CSS Selectors level 4 syntax (specifically see this) with the syntax E! + F for "An element E preceding an element F".
So in your case the syntax would be a! + a.active meaning "An element with tag a preceding an element with tag a and class active". As of today, this is not yet implemented in any layout engine

The adjacent sibling selector only looks forward, not backward. There is no - combinator for previous adjacent siblings.
If you simply need to select anything that isn't .active in the same parent, and you don't mind slightly reduced browser support, you can use :not() instead. If you need to specify a different style for the one that comes after .active, you need to override:
a:not(.active) { background:red }
a.active + a { background:yellow }
Again, this assumes they always share the same parent.
jsFiddle preview

I was looking for the same solution of targeting the elements behind the .activelink
I set a default style for any element before the one .active then I selected all after that one with the sibling selector.
a.active { background: #ccc;}
a.active ~ * { background: yellow }
a { background: red }
Demo: https://codepen.io/ramiro-ruiz/pen/gBOPQL
That worked for me, hope it helps.

Why don't you try using a sibling combinator?
a.active ~ a { background:red }
http://jsfiddle.net/VixedS/6x7d9vm7/

I have to say, this is an issue I had for a while, and one of the things I didn't like much ended up resolving this issue... float: right.
In my case, it was the input[type='radio'] + label element, and since CSS flows forward and not backwards, ~ input[type='radio'] + label would choose all the siblings after the element that was checked.
Since, float: right is responsible for taking "A, B, C" and positioning them as "C, B, A" - I changed the order of radio elements from 1-6 to 6-1 in the HTML, and made them float: right with CSS.
What this did was reverse them back into the order of 1-6 when rendered to the browser.
Now, when I used ~ input[type='radio'] + label, it still defined the styles the same way (which in my case, was the color of the label), however, the siblings being styled were now - visually - the preceding ones.
This thread is over a year old, but if anyone needs an example, I'll create and post a pen if asked.

Related

Hovering a div to change the css on another div

I'm trying to change the color of a text while the mouse is over another div.
It will be better explained with a jsFiddle **:
What I want to do (with CSS) it that when I move the mouse on the first cicle it changes the color of the text ( Result 1).
I have tried what I found searching previous questions on stackoverflow, by using something like that :
div.circleoff:hover ~.test {
color: #fff
}
If you're looking for a color change of nested elements (not a sibling element), use
#schema>div:hover span { color:white; }
This means that hovering over #schema's direct children(division elements) will cause all its nested spans become white.
jsfiddle
Eric Meyer has a few demos on his site that will help with exactly this. Look at the 'popup' section. it can easily be adjusted to fit this.
meyerweb | css/edge
You need to check the specificity of your css selectors. Also, you should not be using the sibling operator. I think this is what you are trying to do (replaced the last 2 rules with the code below).
#schema div.circleoff:hover + .circleoff2 .test,
#schema div.circleon:hover + .circleoff2 .texte {
color: #fff
}

Css selection dependent on different selector's condition

Is it possible to define css class behaves dependent to an other css class?
For example; when
a:hover
Then I want to set
p {background:#fff;}
Is this possible with pure css?
Edit: Assume that no nested relation exist.
If you mean you want all p to have that style when a:hover regardless of where they are in the DOM, then no, you can't do that. You'll need to use a script to apply the style (or some class containing that style) to the p elements when a receives a hover.
if you have a structure like this:
<a><p>...</p></a>
then this:
a:hover p {background: #fff;}
will work. However, block elements should not be placed inside inline elements (in this case, no <p> inside <a>
if your markup is valid, and looks like this:
<p><a>...</a></p>
then you could have
p:hover {background: #fff;}
but a descendant can't affect the parent css (unless you use javascript) while the opposite is true (parent css affects descendants)
I do not see why you would be limited to these restrictions with a littl creativity. if you use fixed positioning the descendant can overlap its parent. and still respond like a descendant.
If the <p> tag immediately follows the <a> tag then you could use the adjacent sibling selector e.g.
a:hover+p{
background:#fff;
}
This is supported in IE8+

Overriding a class in CSS

There are already many questions related to this. But I'm still not clear. Also not sure if the title of the question is correct. Here's my problem:
What the below CSS code means?
#nav li { /*some cssA*/ }
#nav li.over { /*some cssB*/ }
#nav li a { /*some cssC*/ }
#nav li a:hover { /*some cssD*/ }
#nav li ul a span { /*some cssE*/ }
As per my understanding, please correct me if I am wrong:
Line 1: every li element within any element with id="nav" will have styling cssA
Line 2: When I put my cursor over every li element within any element with id="nav" will have styling cssB
Line 3: every a element within every li element within any element with id="nav" will have styling cssC
Line 4: When I hover every a element within every li element within any element with id="nav" will have styling cssD
Line 5: Every span element within every a element within every ul element within every li element within any element with id="nav" will have styling cssE. Also anyother ul or a element will not have this style untill unless the parent element has id="nav"
You are correct on all except .over, The "." represents a class. and "#" represents ID. But yeah, you've got the concept down.
Also, if you want to "Override" as the title says, you'll add
!important
to the end of any rules you want to take precedence over the others.
you can override the css by giving !important or you can give inline style.
priority of inline css is high then external css
All of the existing answers are correct, but there is a bit more to it than has been given already.
As has already been said, "li.over" is a combined selector - it will selector li elements that also have a class of "over". If you wanted to use different CSS properties or property values whilst the mouse is over (hovering over) the element then you use the pseudo class selector "li:hover". These are called pseudo class as you aren't selecting something that is part of the document, but based on the state of an element. There are also pseudo elements which again aren't in the document directly, but logical extensions of the document structure - for example first-child, first-of-type, fifth-of-type, odd items etc.
"#nav li ul a span" is a descendant selector, as you say it will select elements that are children (at any level) of each parent, so "#nav li" selects "li" elements contained within an item with ID "nav" - even several levels down.
If you want to select items that are direct children of the parent then you can use the ">" symbol. I.e. "#nav > li" will select li elements that are directly below any item with an ID of "nav", but not any li elements that are children of that element, or indeed elements below that.
Incidentally "#nav" is exactly equivalent to "*#nav" as it selects any element with the ID, you could also write "ul#nav" if you only wanted to select ul elements with the ID. This could in turn be combined with a class "ul#nav.bar" or even multiple classes "ul#nav.bar.touch".
Removing the space between the selectors like this combines them, so in the last case instead of looking for an item with class "touch" inside an item with class "bar" inside an item with ID "nav" inside a "ul" element, you are selecting a "ul" element with an ID of "nav" and both the classes "bar" and touch". An element like this-
<ul class="bar touch" id="nav">...</ul>
It is also possible to use attribute selectors, so if you wanted to select links which will open in a new window you could use "a[target=_blank]" - which selects based both on the presence of the attribute and the value - or if you wanted to select links with any href value you could use "a[href]". This simply selects all elements with this attribute.
On top of that you can even select items which are adjacent (next to) another element, if you wanted to select all paragraphs directly following an image then you would use "img + p" in your selector, or "p + img" if you wanted to select images directly following a paragraph. As always the last item in the selector is the one the styles are applied to.
It is generally considered good practice not to be overly specific with CSS selectors, as it makes your code much less re-usable. Unless you need to write "div.widget" just write ".widget" as the otherwise you'd not be able to create a "widget" using other elements, and it makes it much harder to override these properties later on in those cases you might need to.
To wrap up selectors, there's a good introduction to CSS selectors on MDN and Code School (paid course provider) also have a excellent online foundation course on CSS available for a very reasonable price which will go through selectors in some detail.
With regard to overriding classes, there are two further concepts you should understand - cascade order and specificity.
Given a HTML snippet of-
<div class="widget">
<p>
Some text you want to style
</p>
</div>
And the following CSS-
#widget p { color: yellow; }
p { color: blue; }
The color of the text would be yellow and not blue because the specificity of the first selector is greater (more specific) than the second. To understand this I suggest you have a play with a Specificity calculator and have a read of the Smashing Magazine tutorial on the subject.
In short though, inline styles trump all, and the more specific a selector the more likely it is to be applied in place of other selectors that would otherwise apply different property values. The value in the selector with the highest specificity score "wins", but other property values from selectors with lower specificity that do not clash will also still be applied to the element.
For example, altering our earlier CSS-
#widget p { color: yellow; }
p {
color: blue;
font-weight: bold;
}
The text will still be yellow, but will also be bold as there is no font-weight property given in the selector with higher specificity.
The last concept you should understand is what happens when two or more rules have identical specificity.
#widget p { color: yellow; }
#widget p {
color: blue;
font-weight: bold;
}
In this case our text is now blue as the second rule appears later in the stylesheet and thus overrides the first. If you have multiple stylesheets then the rules from the last stylesheet to appear in the document head will override rules with identical specificity.
In almost all cases you should use a more specific or the order of the selectors within the stylesheet in order to apply the right styles to the right element, and absolutely should not be routinely using the !important flag to achieve this unless absolutely necessary. See http://james.padolsey.com/usability/dont-use-important/ for a fuller explanation than I give here, but it rapidly becomes unmaintainable (what do you do when everything is "important") and it is also not accessible for users who may wish to override your styles in their user agent stylesheet (local to their browser) in order to help them read or use the page (increasing font size, contrast with background colour etc.)

CSS: Possible to select a certain child plus the immediate following sibling?

I'm currently doing this using Javascript, however, I was wondering if it's possible to select a certain child of an unordered-list and then its immediate sibling, using CSS.
Example with 4 list-items:
ul.tab li:hover + (the next sibling that follows the current hovered one) {
}
You want the adjacent sibling selector for which you amusingly basically have the syntax already.
Be advised: :hover is specifically a x-browser problem in Safari though.

Combining two selectors in CSS3

Is there anyway to combine two selectors? such as:
#div:hover:not(.class)
Edit:
I understand this work as I wrote. However, how can I achieve a "hover" effect for a "LI" element , but exclude the hover effect when the mouse is over a certain "DIV' inside the LI?
E.G.
<li>Hello <div id="#no-hover">Bye</div> </li>
I would like to get a hover effect for the li:
li:hover{ text-color:#CCC; }
but somehow exclude the hover effect when the mouse is over the #no-hover div.
Any ideas?
Based on your question edit, to maximize browser compatibility (I mean, why not if you can?) you can get away with not using CSS3 selectors at all. Try this, assuming black is the default text color:
li, li:hover div#no-hover {
color: #000;
}
li:hover {
color: #ccc;
}
Although you may want to use a class instead of an ID if you want to affect multiple elements with a no-hover classification. In which case you would do this instead for your first rule:
li, li:hover div.no-hover {
Either way, since selecting a descendant with its ancestor is more specific than selecting just the ancestor, assuming the same combinators on the ancestor it'll override the second rule even though that one comes later.
Update:
If you only want to have the hover effect not applying to Bye, then you can just create an extra hover rule for that and set the color explicitly (as other answers showed).
If the hover effect should not apply to the whole li element, then I think there is no way to do it. You needed some kind of parent selector, which does not exist in CSS.
Yes and it is fairly easy to try: http://jsfiddle.net/5vaUW/
(probably only works if your browser supports CSS3)
You might want to read more about CSS3 selectors, where you can find this:
A selector is a chain of one or more sequences of simple selectors separated by combinators. One pseudo-element may be appended to the last sequence of simple selectors in a selector.
A sequence of simple selectors is a chain of simple selectors that are not separated by a combinator. It always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence.
A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.
In css2, would be:
li:hover{
color:#CCC;
}
li:hover div{
color: #000;
}
For CSS3, I agree with Felix Kling.

Resources