last child with element inside - css

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.

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;
}

Best replacement for font tag in html

Since the font tag in HTML is being deprecated in HTML5 (and I understand why) is there a clean solution for applying certain attributes and styles to only portions of a paragraph text? I'm using JavaScript to parse an XML file that relies on the fact that the font tag allows portions of wrapping text to be formatted using class-based CSS. I realize the "anchor" (a) tag could also be used for this purpose, but that way seems very backwards and unnatural.
EDIT
When I asked this question (a couple years ago now) I was failing to understand that every DOM element falls into a display category, the two primary categories being:
block - insists on taking up its own row
inline - falls in line with other inline elements or text
HTML offers two generic container elements, each of which by default adheres to one of these display values; div for block display, and span for inline display.
The span element is the perfect way to designate a certain chunk of text and give it a unique style or ID because you can wrap it around part of a larger paragraph without breaking the selected contents into a new row.
The span tag would be the best way.
Although inline CSS is typically not recommended, here is an example:
<p>
This is my <span style="font-weight:bold">paragraph</span>.
</p>
span and div are similar, but the div tag is a block element, so it will cause line-breaks. span is an inline tag that can be used inline with your text.
HTML:
<span class="yourstyle">
Text in your style
</span>
CSS:
.yourstyle {
color: red;
}
you could use a <span> tag
<p>here is your paragraph text and it goes on and on and on..... and now
lets start some <span>formatted text.</span> here is another<span>section
of formatted text</span> here is unformatted text<p>
you can either do inline styles such as <span style="color: #000000; font-family: calibri, arial, helvetica;"> or you can just apply a class to your span, like <span class="textformat1" and <span class="textformat2">. then just apply different css rules based on the class.
.textformat1 {
color: red;
}
.textformat2 {
color: blue;
}
hope this helps
Always use css files to hold your code which will be considered "universal" for each element you set. When you want to set for a specific, lets say <span> element. You would do just as Adam Plocher said above, use the style="" attribute for the <span>element.

Select parent n layers up in the tree using 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.

Hiding previous element by checked selector

I would like to use css3 features to hiding previous element.
Basically,
I want to use a checkbox to hide previous sibling element without using javascript.
I have prepared a sample for entry point.
http://cssdesk.com/5zccy
Thanks
Edit:
I have changed sample.
My usecase: I want to have collapsible sections at my site. Two area separated by a simple checkbox and checking it will beautifully hide previous sibling.
I believe that using pure css will let me to reduce using javascript for this task.
You can not hide the previous elements - just the following ones with the general sibling selector
DEMO
Then you might be able to position the elements, so on the actual page the checkbox will appear after the .parent div.
There's no css selector to select the previous tag of a matched element. The closest you can get using only css it's doing that for the next element:
<input class="hider" type="checkbox" /> child
<div class="parent">
Parent
</div>​
.hider:checked + * {
display:none;
}​

Complex CSS selector for parent of active child [duplicate]

This question already has answers here:
Is there a CSS parent selector?
(33 answers)
Closed 9 years ago.
Is there a way to select a parent element based on the class of a child element in the class? The example that is relevant to me relating to HTML output by a nice menu plugin for http://drupal.org. The output renders like this:
<ul class="menu">
<li>
<a class="active">Active Page</a>
</li>
<li>
<a>Some Other Page</a>
</li>
</ul>
My question is whether or not it is possible to apply a style to the list item that contains the anchor with the active class on it. Obviously, I'd prefer that the list item be marked as active, but I don't have control of the code that gets produced. I could perform this sort of thing using javascript (JQuery springs to mind), but I was wondering if there is a way to do this using CSS selectors.
Just to be clear, I want to apply a style to the list item, not the anchor.
According to Wikipedia:
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.
And for anyone searching SO in future, this might also be referred to as an ancestor selector.
Update:
The Selectors Level 4 Spec allows you to select which part of the select is the subject:
The subject of the selector can be explicitly identified by prepending
a dollar sign ($) to one of the compound selectors in a selector.
Although the element structure that the selector represents is the
same with or without the dollar sign, indicating the subject in this
way can change which compound selector represents the subject in that
structure.
Example 1:
For example, the following selector represents a list item LI unique child of
an ordered list OL:
OL > LI:only-child
However the following one represents an ordered list OL having a unique child,
that child being a LI:
$OL > LI:only-child
The structures represented by these two selectors are the same,
but the subjects of the selectors are not.
Although this isn't available (currently, November 2011) in any browser or as a selector in jQuery.
You can use has():
li:has(a:active) {
/* ... */
}
Unfortunately, there's no way to do that with CSS.
It's not very difficult with JavaScript though:
// JavaScript code:
document.getElementsByClassName("active")[0].parentNode;
// jQuery code:
$('.active').parent().get(0); // This would be the <a>'s parent <li>.
Late to the party again but for what it's worth it is possible using jQuery to be a little more succinct. In my case I needed to find the <ul> parent tag for a <span> tag contained in the child <li>. jQuery has the :has selector so it's possible to identify a parent by the children it contains (updated per #Afrowave's comment ref: https://api.jquery.com/has-selector/):
$("ul").has("#someId")
will select the ul element that has a child element with id someId. Or to answer the original question, something like the following should do the trick (untested):
$("li").has(".active")
THE “PARENT” SELECTOR
Right now, there is no option to select the parent of an element in CSS (not even CSS3). But with CSS4, the most important news in the current W3C draft is the support for the parent selector.
$ul li:hover{
background: #fff;
}
Using the above, when hovering an list element, the whole unordered list will be highlighted by adding a white background to it.
Official documentation: https://www.w3.org/TR/2011/WD-selectors4-20110929/#overview (last row).
The first draft of Selectors Level 4 outlines a way to explicitly set the subject of a selector. This would allow the OP to style the list element with the selector $li > a.active
From Determining the Subject of a Selector:
For example, the following selector represents a list item LI unique child of an ordered list OL:
OL > LI:only-child
However the following one represents an ordered list OL having a unique child, that child being a LI:
$OL > LI:only-child
The structures represented by these two selectors are the same, but the subjects of the selectors are not.
Edit: Given how "drafty" a draft spec can be, it's best to keep tabs on this by checking the CSSWG's page on selectors level 4.
Future answer with CSS4 selectors
New CSS Specs contain an experimental :has pseudo selector that might be able to do this thing.
li:has(a:active) {
/* ... */
}
The browser support on this is basically non-existent at this time, but it is in consideration on the official specs.
Answer in 2012 that was wrong in 2012 and is even more wrong in 2018
While it is true that CSS cannot ASCEND, it is incorrect that you cannot grab the parent element of another element. Let me reiterate:
Using your HTML example code, you are able to grab the li without specifying li
ul * a {
property:value;
}
In this example, the ul is the parent of some element and that element is the parent of anchor. The downside of using this method is that if there is a ul with any child element that contains an anchor, it inherits the styles specified.
You may also use the child selector as well since you'll have to specify the parent element anyway.
ul>li a {
property:value;
}
In this example, the anchor must be a descendant of an li that MUST be a child of ul, meaning it must be within the tree following the ul declaration. This is going to be a bit more specific and will only grab a list item that contains an anchor AND is a child of ul.
SO, to answer your question by code.
ul.menu > li a.active {
property:value;
}
This should grab the ul with the class of menu, and the child list item that contains only an anchor with the class of active.
I had the same problem with Drupal. Given the limitations of CSS, the way to get this working is to add the "active" class to the parent elements when the menu HTML is generated. There's a good discussion of this at http://drupal.org/node/219804, the upshot of which is that this functionality has been rolled in to version 6.x-2.x of the nicemenus module. As this is still in development, I've backported the patch to 6.x-1.3 at http://drupal.org/node/465738 so that I can continue to use the production-ready version of the module.
Many people answered with jQuery parent, but just to add on to that I wanted to share a quick snippet of code that I use for adding classes to my navs so I can add styling to li's that only have sub-menus and not li's that don't.
$("li ul").parent().addClass('has-sub');
I actually ran into the same issue as the original poster. There is a simple solution of just using .parent() jQuery selector. My problem was, I was using .parent instead of .parent(). Stupid mistake I know.
Bind the events (in this case since my tabs are in Modal I needed to bind them with .live instead of a basic .click.
$('#testTab1 .tabLink').live('click', function() {
$('#modal ul.tabs li').removeClass("current"); //Remove any "current" class
$(this).parent().addClass("current"); //Add "current" class to selected tab
$('#modal div#testTab1 .tabContent').hide();
$(this).next('.tabContent').fadeIn();
return false;
})
$('#testTab2 .tabLink').live('click', function() {
$('#modal ul.tabs li').removeClass("current"); //Remove any "current" class
$(this).parent().addClass("current"); //Add "current" class to selected tab
$('#modal div#testTab2 .tabContent').hide();
$(this).next('.tabContent').fadeIn();
return false;
})
Here is the HTML..
<div id="tabView1" style="display:none;">
<!-- start: the code for tabView 1 -->
<div id="testTab1" style="width:1080px; height:640px; position:relative;">
<h1 class="Bold_Gray_45px">Modal Header</h1>
<div class="tabBleed"></div>
<ul class="tabs">
<li class="current"> Tab Title Link
<div class="tabContent" id="tabContent1-1">
<div class="modalCol">
<p>Your Tab Content</p>
<p>tabBased Anchor Link </p>
</div>
<div class="tabsImg"> </div>
</div>
</li>
<li> Tab Title Link
<div class="tabContent" id="tabContent1-2">
<div class="modalCol">
<p>Your Tab Content</p>
<p>tabBased Anchor Link </p>
</div>
<div class="tabsImg"> </div>
</div>
</li>
</ul>
</div>
</div>
Of course you can repeat that pattern..with more LI's
Another thought occurred to me just now that could be a pure CSS solution. Display your active class as an absolutely positioned block and set its style to cover up the parent li.
a.active {
position:absolute;
display:block;
width:100%;
height:100%;
top:0em;
left:0em;
background-color: whatever;
border: whatever;
}
/* will also need to make sure the parent li is a positioned element so... */
ul.menu li {
position:relative;
}
For those of you who want to use javascript without jquery...
Selecting the parent is trivial. You need a getElementsByClass function of some sort, unless you can get your drupal plugin to assign the active item an ID instead of Class. The function I provided I grabbed from some other genius on SO. It works well, just keep in mind when you're debugging that the function will always return an array of nodes, not just a single node.
active_li = getElementsByClass("active","a");
active_li[0].parentNode.style.whatever="whatever";
function getElementsByClass(node,searchClass,tag) {
var classElements = new Array();
var els = node.getElementsByTagName(tag); // use "*" for all elements
var elsLen = els.length;
var pattern = new RegExp("\\b"+searchClass+"\\b");
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}

Resources