Tricky CSS conditional sibling > child selector > Can this be done? - css

In the markup below, I'm looking for a way (perhaps using css selector's) to style the content div differently depending on the presence of menu? Menu may or may not be present in that location in the markup and if it is there, I need to add some top margin to content.
I believe sibling and descendent selector rules might not go this far...
"When menu is present as a child of header set the top margin of content (whose parent is a sibling of header) to 100 pixels. Otherwise, set it to zero"
<div class="header">
<div class="sitetitle">site title</div>
<div class="tagline">tagline</div>
<div class="menu">menu</div>
</div>
<div class="main">
<div class="content">content goes here</div>
</div>
If css allowed groupings, I would do it this way...
(.header ~ .menu) + (.main > .content) {margin-top:100px;}

Not possible in your markup.
CSS selectors can only look at the ancestor and at the sibling axes. You cannot look inside ("what children do I have") - only upwards ("what are my parents") and sideways ("what's next to me").
Examples. This:
div.header div.menu
refers to any <div class="menu"> one of whose ancestors is a <div class="header">.
This:
div.header > div.menu
refers to any <div class="menu"> whose direct ancestor (i.e. "parent") is a <div class="header">.
This:
div.header ~ div.menu
refers to any <div class="menu"> that has a <div class="header"> among its preceding siblings, i.e. they have the same parent and occur one after another, but not necessarily adjacent to each other (that's "looking sideways").
This:
div.header + div.menu
refers to any <div class="menu"> whose direct preceding sibling is a <div class="header">.
There are no other traversing selectors in CSS (this statement refers to CSS2) and certainly there are no conditionals.

You could use jQuery:
​$('.header:has(.menu) + .main > .content')​.css('margin-top', '100px');​​​​​​​​​​​
Unfortunately the :has() selector didn't find its way into css3.
But why don't you simply apply a margin-bottom to div.menu?

You could possibly use some javascript to detect that. Check if menu is under header at load, and if it is, then set the margin-top of content to 100px

I used this CSS code in a conditional formatting.
Format index by counting from the end.
#stk-service-account-menu ul li:nth-last-child(1):before {

Related

hide a div by clicking a non-parent div

In my site there're two different div, but they have the same parent div (two child div). So, I want to do this: div.1:hover -> div.2{display:none}. How can I do it using CSS?
Depending on the way your HTML is laid out it can work. The divs need to be next to each other like so:
<div class="first">
First div
</div>
<div class="second">
Second div
</div>
Then use this CSS:
div.first:hover + div.second { display: none; }
Fiddle here: http://jsfiddle.net/CyT2N/
You can easily accomplish that with JQuery.
$(document).ready(function(){$("#first").hover(function(){$("#second").hide();}, function(){$("#second").show();});});
Explanation:
this code adds a "hover" handler for the first element on document.ready, when the mouse enters we hide the second element, and when the mouse leaves, we show it again.
This way, it will work no matter where the elements are within the layout.
See here: http://jsfiddle.net/avrahamcool/RenK2/
Edit
If you want the second div to hide when the first one is clicked, use $("#first").click(function(){$("#second").hide();}) instead of hover(..)
See here: http://jsfiddle.net/avrahamcool/RenK2/1/
Here is a simple way of doing it:
If you have HTML similar to this:
<div class="wrap">
<div class="first">First div</div>
<p>some other element...</p>
<div class="second">Second div</div>
</div>
your CSS would be:
.first:hover ~ .second {
display: none;
}
Demo at: http://jsfiddle.net/audetwebdesign/HQN6n/
The one limitation that .first and .second must be sibling elements within the same parent element, .wrap in this example.
The general sibling combinator ~ is supported for IE7+
Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_selectors

Alternating element's style using pseudo class that are in separate parents

I have several div elements and I want to alternate another set of div styles within them. So basically change the child's style to alternating background colors like so:
HTML
<article class="post"> <!--first post-->
<div class="title">Title Here</div>
content here
</article>
<article class="post"> <!--second post-->
<div class="title">Title Here</div>
content here
</article>
CSS
div.title:nth-of-type(even) {
background-color: #F00;
}
div.title:nth-of-type(odd) {
background-color:#00F;
}
Is there a way to do this, because I know that using css to alternate styles it has to be within a parent. Or if not would there be any jquery script that i could use?
Thank you.
You should use
article.post:nth-of-type(even) .title
Works fine this way.
jsFiddle
Also, try to stay away from over-qualified CSS selectors like div.title, as explained in this article by CSS Wizardy. Basically, the .title in this instance is definitely within the article.post, so you don't need to add the div too.
Overqualified selectors make the browser work harder than it needs to
and uses up its time; make your selectors leaner and more performant by
cutting the unnecessary bits out.
nth-of-type is alway checking for the postition of the element in his parent. Hence, your div's are always first child of .post. That's why it doesnt work.
But you can check the child position of it's parent. Just like that :
.post:nth-of-type(even) div.title{}
.post:nth-of-type(odd) div.title{}

Why doesn't this CSS :not() declaration filter down?

I want to select spans that are not the descendants of a specific class, let's call it "no". Here's my CSS:
div:not(.no) span{background-color:#00f;}
Here's the HTML
<div>
<span>yes 1</span>
</div>
<div class="no">
<span>no 1</span>
</div>
<div class="no">
<div>
<span>no 2</span>
</div>
</div>
Two questions:
Why does my CSS apply to both yes 1 and no 2?
Why does the whole thing break if I switch to a universal selector?
*:not(.no) span{background-color:#00f;}
Here's the code in JSFiddle: http://jsfiddle.net/stephaniehobson/JtNZm/
Both of the span elements' parent div elements don't have the class no, regardless of whether any other ancestors do have it or not:
<div> <!-- This is div:not(.no), pretty much a given -->
<span>yes 1</span>
</div>
<div class="no"> <!-- In this case, although this is div.no... -->
<div> <!-- ... this is div:not(.no)! -->
<span>no 2</span>
</div>
</div>
Both html and body, which are ancestors of your div and span elements, satisfy *:not(.no) when using a universal selector (or rather, when omitting a type selector). This causes all of your span elements to have the background color.
One solution to this is to anchor your negation filter to the body element using the child combinator, if your top-level div elements will always be children of body:
body > div:not(.no) span { background-color: #00f; }
jsFiddle demo
Another solution is to simply use override styles.
BoltClock is correct. It might make more sense if you phrase the selector like this:
Select any span element
that is descended from a div element
whose class value does not contain the word no.
Each of the selected spans in your example is in fact descended from a div whose class value does not contain the word no—the fact that the second of them is also descended from a div whose class value does contain the word no doesn’t negate (ha!) the previous statement.
What’s interesting is I would wager that if you moved the second no down a level, the second span would still be matched. CSS doesn’t have a notion of element proximity, so any ancestor div should suffice to match the selector, regardless of whether it’s “closer” to the span or not.
I think the best choice is to split your statement into 2:
div span { background-color:#00f; }
.no span { background-color:#fff; }
You can see the effect here: http://jsfiddle.net/JHTqp/

Target same-level child of an element

Is there an easy way to target all 3rd layer elements?
For example, my right column layout is as follows:
<div class=right_column>
<div class=module>
<div>
<p></p>
</div>
</div>
<div class=different_module>
<div>
<p></p>
</div>
</div>
</div>
How do I target both non-classed <div> elements in this instance without specifying each one individually?
Like this: .right_column > div > div
> is the "Child Selector" - check out this top-notch article on CSS Tricks.
You should be able to do something like this
div > div > div{
/* styles here */
}
> is a child-selector.
Here it says select and use the div that is a child of a div that is a child of a div.
Here is an example: http://jsfiddle.net/hbXsE/1/
Note: the HTML you provided has a few missing div tags and some closing span tags. I redid it for the example.
You could use the selector div.right_column div div but it will also match divs nested more deeply. To avoid this on most newer browsers, you could use the child selector, like this: div.right_column > div > div but it won't work in older versions of IE

CSS '>' selector; what is it? [duplicate]

This question already has answers here:
What does the ">" (greater-than sign) CSS selector mean?
(8 answers)
Closed 3 years ago.
I've seen the "greater than" (>) used in CSS code a few times, but I can't work out what it does. What does it do?
> selects immediate children
For example, if you have nested divs like such:
<div class='outer'>
<div class="middle">
<div class="inner">...</div>
</div>
<div class="middle">
<div class="inner">...</div>
</div>
</div>
and you declare a css rule in your stylesheet like such:
.outer > div {
...
}
your rules will apply only to those divs that have a class of "middle" since those divs are direct descendants (immediate children) of elements with class "outer" (unless, of course, you declare other, more specific rules overriding these rules). See fiddle.
div {
border: 1px solid black;
padding: 10px;
}
.outer > div {
border: 1px solid orange;
}
<div class='outer'>
div.outer - This is the parent.
<div class="middle">
div.middle - This is an immediate child of "outer". This will receive the orange border.
<div class="inner">div.inner - This is an immediate child of "middle". This will not receive the orange border.</div>
</div>
<div class="middle">
div.middle - This is an immediate child of "outer". This will receive the orange border.
<div class="inner">div.inner - This is an immediate child of "middle". This will not receive the orange border.</div>
</div>
</div>
<p>Without Words</p>
<div class='outer'>
<div class="middle">
<div class="inner">...</div>
</div>
<div class="middle">
<div class="inner">...</div>
</div>
</div>
Side note
If you, instead, had a space between selectors instead of >, your rules would apply to both of the nested divs. The space is much more commonly used and defines a "descendant selector", which means it looks for any matching element down the tree rather than just immediate children as the > does.
NOTE: The > selector is not supported by IE6. It does work in all other current browsers though, including IE7 and IE8.
If you're looking into less-well-used CSS selectors, you may also want to look at +, ~, and [attr] selectors, all of which can be very useful.
This page has a full list of all available selectors, along with details of their support in various browsers (its mainly IE that has problems), and good examples of their usage.
> selects all direct descendants/children
A space selector will select all deep descendants whereas a greater than > selector will only select all immediate descendants. See fiddle for example.
div { border: 1px solid black; margin-bottom: 10px; }
.a b { color: red; } /* every John is red */
.b > b { color: blue; } /* Only John 3 and John 4 are blue */
<div class="a">
<p><b>John 1</b></p>
<p><b>John 2</b></p>
<b>John 3</b>
<b>John 4</b>
</div>
<div class="b">
<p><b>John 1</b></p>
<p><b>John 2</b></p>
<b>John 3</b>
<b>John 4</b>
</div>
It is the CSS child selector. Example:
div > p selects all paragraphs that are direct children of div.
See this
As others have said, it's a direct child, but it's worth noting that this is different to just leaving a space... a space is for any descendant.
<div>
<span>Some text</span>
</div>
div>span would match this, but it would not match this:
<div>
<p><span>Some text</span></p>
</div>
To match that, you could do div>p>span or div span.
It is a Child Selector.
It matches when an element is the child of some element. It is made up of two or more selectors separated by ">".
Example(s):
The following rule sets the style of all P elements that are children of BODY:
body > P { line-height: 1.3 }
Example(s):
The following example combines descendant selectors and child selectors:
div ol>li p
It matches a P element that is a descendant of an LI; the LI element must be the child of an OL element; the OL element must be a descendant of a DIV. Notice that the optional white space around the ">" combinator has been left out.
It declares parent reference, look at this page for definition:
http://www.w3.org/TR/CSS2/selector.html#child-selectors
It means parent/child
example:
html>body
that's saying that body is a child of html
Check out: Selectors

Resources