Select parent n layers up in the tree using CSS? - css

I have an app with relatively complex DOM structure with 20+ layers of divs.
If I have a div with class="active" somewhere in the middle of the tree, how can I select it's parent n layers up in the tree using CSS?
For example, how do I select the div marked in uppercase (4 layers up) in the following tree ? :
<DIV>
<div>
<div>
<div>
<div class="active">
</div>
</div>
<div>
</div>
</div>
</div>
</DIV>
Same considering first-child ? How to select a first-child n layers down the tree ?

Unfortunately, there is no such thing as a parent selector. You'll have to set a class on the desired element directly, either by hand, or with some server-side code, or via JavaScript.

Based on this article I found titling CSS4 Preview, it will be possible in CSS4 to style parent elements. The article shows that it would be possible to style parent elements like the following:
$div > div > div > div.active { border: 1px solid #ccc; }
(Given example would style the div nested 3 layers up in the tree related to div.active)
Going back to my app, using PHP and inline CSS, I would be able to control the n (nesting depth).
Until CSS4 though, I will use some kind of jQuery solution.

Related

CSS - Set parent element display none

I have a web code generated by an aplication (built in angular). It is a menu choice where I need to hide some of them. It looks e.g. like this:
<div class=first>
<div class=second>
<a href=href1>
</div>
<div class=second>
<a href=href2>
</div>
<div class=second>
<a href=href3>
</div>
</div>
Now what I need is to hide the div which contains a element with href2.
I can hide the a element:
.first .second a[href="href2"] {display:none}
But I need to hide the whole div element. I thought:
.first .second < a[href="href2"] {display:none}
that doesn't work.
I KNOW THE JQUERY SOLUTION with has function. The problem is I can only adapt css files of the application. If i'm right I cannot use jquery in css file.
Please...any Idea how to do this ?
thanks a lot for help
best regards
Marek
At the moment there is (sadly) no way to adress the parent element with CSS.
I don't know your layout or CSS Code but maybe you can just structure your HTML-Code in a different way.
Edit
And now I understand your question...
To hide (for example) the 3th .second div you don't need to adress it from the child element but from the parent element.
What you are probably looking for are the nth selectors,
for instance: nth-child() or nth-of-type().
You can find more info here.
Also, you should probably take a look at the basics of HTML and CSS.
In your code you have not closed the <a> tags or wrapped the values of the attributes in quotation marks.
Wrong:
<div class=first></div>
Right:
<div class="first"></div>
To hide (for instance) the first element you could use the :first-child selector or the :nth-child() selector. Since you will probably use the nth-child() selector this would be:
.first > .second:nth-child(1) {
display: none;
}

How to select an element that has no leading or trailing text nodes?

I experimented with using the :only-child pseudo-class but unfortunately this does not seem to consider the text nodes:
<style type="text/css">
div span:only-child {
color: red;
}
</style>
<div>
Test
<span>This still becomes red :(</span>
</div>
<div>
<span>This becomes red, as it should!</span>
</div>
<div>
<span>This does not become red - great!</span>
<span>This does not become red - great!</span>
</div>
I am trying to find a way to detect when a specific element is completely alone within its container element in a situation where I am unable to introduce new classes.
Is there a way to achieve this with CSS?
Is there a way to achieve this with CSS?
Unfortunately, not.
Included in an old revision of the CSS Working Group "mistakes" list is missing the idea that..
No naked text mixing with elements. All raw text should have an addressable, stylable element wrapping it, created by CSS if necessary.
Current list
Text Nodes are not element and CSS can't select (or ignore) elements that don't exist.
So, it's probably best practice to always use a text element when incorporating text in a page...you never know when you might need to style it.
div:nth-child(2) span {
color: red;
}
https://jsfiddle.net/cmckay/8663aLcg/

How can I :hover over different links in one line while getting the spacing correct?

I have the top bar of my page set up as follows: Home | Contact Us etc..
It lies within a p tag inside a div id.
How would i go about setting up the :hover css on each link without having to separate them into different classes such as how I have them at the moment. Is it possible?
I don't think i used the correct css because i couldn't position them correctly without having to use different padding parameters for each class which makes the spacing look inaccurate.
via codepen: http://codepen.io/Hafkamp/pen/jabmE
html:
<div id="topinfo">
<div class="home"><p>Home |</p></div>
<div class="about"><p>About |</p></div>
<div class="contactUs"><p>Contact Us |</p></div>
<div class="map"><p>Map |</p></div>
</div><!--/topinfo tag-->
css:
.home p{padding-right:250px;}
#topbar .home p:hover{color:rgba(255,255,255,1)}
Is there an easier way to do this that is not so tedious. This method also causes the divider to have the hover effect which is not desirable.
The best way of defining menus in a page is to use "ul" and "li" tags. But if you still want to use with tag you have to use it this way:
`Home
About
contact
.home_link, .about_link, .contact_link{color: red;}
.home_link:hover, .about_link:hover, .contact_link:hover {color: blue;}`
I would give them all the same class, say topitem, and use a rule like this:
.topitem:hover p {
color:rgba(255,255,255,1);
cursor:pointer;
}
Although really, I would get rid of the interior <p> tag and reduce the selector to .topitem:hover – the text is already wrapped in a <div>, so why wrap it again? (But see Zinnia's note about the convention of using <ul> and <li> instead of nested <div>s.)

last child with element inside

I think this is impossible :-(
Using CSS, I need to select the last label in the list of paragraphs, which is inside of a span.
<div>
<p>
<span>
<label>no good, because not the last</label>
</span>
</p>
<p>
<span>
<label>good</label> <!-- This one should be selected -->
</span>
</p>
<p>
<label>no good, because is not inside of a span</label>
</p>
</div>
Virtually the selector would be something like this:
div (p > span):last-child label {
background: red;
}
But I don't think CSS understands parenthesis (yet).
The reason for this is that ExtJS (Sencha) puts radio buttons in nested containers. The visibility of buttons is declared in the inner containers (that would be the span tags in the example above). I want to round corners of the last VISIBLE label, thus I need to find the last outer container that has an inner container declaring it's visibility.
Perhaps there is a different workaround for this? As a last resort, I'd accept a JS solution, as long as it's based on native ExtJS components/elements traversing syntax, rather than jQuery.
Please ask for more detail if needed.
It will (maybe, depends on if the selector will be in the final spec) partly be possible with CSS 4:
!p > span {
background: red;
}
But this will select all <p/> that have a <span/> inside, not only the last one. CSS currently does not know a :last selector, and as far as I can see even with CSS 4 this won't be implemented1.
So the summary is: Currently there is no way to do this in pure CSS.
Currently your only option is to use JavaScript. A sample in jQuery would be:
$('p:has(span)').last().css({ 'background': 'red' });
Here is a demo.
Or, as you mentioned in your comment, with extjs:
Ext.select('p:has(span):last').setStyle('background', 'red');
Here is a demo.
Answer to your updated question
Your new example does not need a parent selector anymore. The partly working CSS would be
div > p > span > label {
background: red;
}
But still: There is no :last selector in CSS1. Updating the above JavaScript samples:
jQuery:
$('div > p > span > label').last().css({ 'background': 'red' });
extJS:
Ext.select('div > p > span > label:last').setStyle('background', 'red');
1 About the :last selector:
To make it more clear: :last-child selects the last child inside an element in the dom, whatever it is. It is no sub query. So, even if your parenthesis version would be implemented, :last-child would select nothing because the really last element is not part of the query. You would need a :last selector like in some JavaScript libraries which selects the last item of the resultset, so it's a sub query. This is a completely different selector and will not be part of CSS soon.

css - define styling for siblings child element

I am trying to define styling for second sibling's child element based of first sibling's class.
Here is an example of what I am trying to achieve
<div >
<div class="one">
<div class="find edit">
Find me
</div>
</div>
<div class="two">
<div class="change">
Change me
</div>
</div>
</div>
In this example, I want "Change me" to be green if "edit" class is found. Is it possible to achieve this purely based on css?
Help much appreciated.
Thanks,
Medha
As far as I know, it's not possible to access the parent selector (I wish it was). If you could consider this structure, it'll be no problem at all:
HTML
<div>
<div class="one edit">
<div class="find">
Find me
</div>
</div>
<div class="two">
<div class="change">
Change me
</div>
</div>
</div>
CSS
.one.edit + .two .change { color: green; }
If not, you could easily accomplish what you're after with a little JavaScript.
Here You can find answer:
Complex CSS selector for parent of active child
Short answer copied from link:
Selectors are unable to ascend
CSS offers no way to select a parent or ancestor of element that
satisfies certain criteria. A more advanced selector scheme (such as
XPath) would enable more sophisticated stylesheets. However, the major
reasons for the CSS Working Group rejecting proposals for parent
selectors are related to browser performance and incremental rendering
issues.
Update:
Now I notice the edit class required in the child. You cannot.
simply you need something like a parent selector, and this doesn't exist in CSS 3, it's suggested in CSS 4 though, but that's far from happening any time soon.
More here:
CSS selector for "foo that contains bar"?
.
Original:
Depending on which browsers you care about, this may work:
div.one + div.two > div.change {
color: green;
}
Reference:
http://www.w3.org/TR/CSS21/selector.html#adjacent-selectors
Live Example:
http://jsfiddle.net/Meligy/NVjq6/

Resources