CSS for element without any grandchild elements [duplicate] - css

This question already has answers here:
Is there a CSS parent selector?
(33 answers)
Closed last year.
how to specify CSS for an element without any grandchild elements? e.g.,
<div class="foo">
<ul></ul>
</div>
<div class="foo">
<ul><li></li></ul>
</div>
// hide the <div> whose child <ul> is empty, how?
div.foo {
display: none;
}

Hey there is :empty selector in css which allows you to do like this.
Javascript method to get what you asked for
But If you want to hide other things you should use javascript
:has is experimental
A simple way of doing this
let text = document.querySelector("div.foo > ul");
if(text.innerHTML == ""){
// set your things
document.querySelector("div.foo").style.display = "none";
// you can delete this thing too but this is just an examplee
}
using :empty selector
If you don't wanna use javascript then this method is also good
Simply use
div > ul:empty{
display:none; // or any styles that you can see
}
For just illustration purpose :
div.foo > ul{
background-color:blue;
height:30px;
}
div.foo > ul:empty{
display:none;
}
<!-- Below is empty ul -->
<div class="foo">
<ul></ul>
</div>
<!-- Below is non empty ul -->
<div class="foo">
<ul>
<li>This is with text</li>
</ul>
</div>
But be carefull
Empty elements are elements that have nothing in them. It cannot even have a whitespace.
There is something called :blank but it is experimental as far as I know.

Related

CSS Select Sibling of An Element with A Specific Sub-Element?

The snippet below is a part of a much larger structure with many .step elements.
I need to match all .stepText elements that are next to .stepTitleAndImages ul.standard
In other words, match all .stepText elements that have .step parent that has .stepTitleAndImages child that has .stepImages.standard child
<div class="step">
<div class="stepTitleAndImages">
<h3 class="stepTitle"></h3>
<ul class="stepImages standard"></ul>
<div class="clearer"></div>
</div>
<div class="stepText "></div> **HOW TO SELECT ALL ELEMENTS LIKE THIS ONE?**
<div class="clearer"></div>
</div>
<div class="step">
<div class="stepTitleAndImages">
<h3 class="stepTitle"></h3>
<ul class="stepImages medium"></ul>
<div class="clearer"></div>
</div>
<div class="stepText "></div>
<div class="clearer"></div>
</div>
PS: I cannot modify the HTML. Cannot use anything other than pure CSS.
Just use this for selecting first case
.step:nth-child(1) .stepText {
... Your CSS here
}
For second one use
.step:nth-child(2) .stepText {
... Your CSS here
}
For selecting both use
.step .stepText {
... Your CSS here
}
Then you should require jquery for that
Selecting Parents sibling is not possible only with pure CSS yet, You can achieve this by a single line of jquery:
$('ul.standard').parent().siblings(".stepText").css(...your CSS here);
This cannot be done with your HTML structure and with pure CSS. The closest solution to your problem, changing the HTML structure and with pure CSS, would be to move the standard class to its parent tag:
<div class="stepTitleAndImages standard">
<h3 class="stepTitle"></h3>
<ul class="stepImages"></ul>
<div class="clearer"></div>
</div>
This would allow you to use the adjacent sibling selector (+), which matches the second selector if it's the direct next sibling of the first, like this:
.stepTitleAndImages.standard + .stepText {
/* Styles */
}
A more flexible approach would be to use the general sibling selector which would match any sibling preceded by the first selector, not only the direct next one:
.stepTitleAndImages.standard ~ .stepText {
/* Styles */
}
The :has pseudo-class is in development by Mozilla, but it hasn't hit any stable browsers yet. With it, and with your HTML structure, you could go:
.stepTitleAndImages:has(.standard) + .stepText {
/* Styles */
}
Unfortunately, currently you can't solve this in any other way with CSS (and with your HTML structure) only.

Is the > symbol necessary when selecting a child element in CSS? [duplicate]

This question already has answers here:
CSS Child vs Descendant selectors
(8 answers)
Closed 8 years ago.
div > p {
background-color: yellow;
}
doesn't appear to evaluate any differently than
div p {
background-color: yellow;
}
But would there be an effect I am unaware of? It seems that using the > is more proper style, at least.
There is a difference; > is "immediately follows". So your div > p would apply to the p here:
<div>
<p>Text here</p>
</div>
but not here:
<div>
<table>
<tr>
<td>
<p>Text here</p>
</td>
</tr>
</table>
</div>
A more detailed description can be found within the CSS specification for child selectors.
Look at this example it might help you ...
div#container > ul {
border: 1px solid black;
}
.......
<div id="container"> <ul>
<li> List Item
<ul>
<li> Child </li>
</ul>
</li>
<li> List Item </li>
<li> List Item </li>
<li> List Item </li> </ul> </div>
A selector of #container > ul will only target the uls which are direct children of the div with an id of container. It will not target, for instance, the ul that is a child of the first li.
For this reason, there are performance benefits in using the child combinator. In fact, it's recommended particularly when working with JavaScript-based CSS selector engines.
.......
Read this : http://code.tutsplus.com/tutorials/the-30-css-selectors-you-must-memorize--net-16048
it will help you .
div > p selects the direct child p (only the sons),
div p selects all its children p, now matter how deep it is in the hierarchy (including the grandsons and great grandsons).
div>p
indicates a P which is a DIRECT child of div
div p
indicates a p that is descendent of div, not
Check Fiddle for example.
The > selector is used to select child elements of a particular elemnent.

css target first li in a div of many divs

so I have been trying all this stuff with first-child and everything and none seem to be working. If I have a div set up as such:
<div class="content">
<div class="thing">
abd
</div>
<div class="thing">
</div>
<div class="thing">
123
</div>
<div class="thing">
<li class="list" goal="target">
1
</li>
</div>
<div class="thing">
<li class="list">
2
</li>
</div>
<div class="thing">
<li class="list">
3
</li>
</div>
<div class="thing">
<li class="list">
4
</li>
</div>
</div>
what line of css that will be able to target only the first li element in the .content div (the one with the attribute goal="target")
now this can be fairly messy and there can be anywhere from 0 to 10 divs without a li before the first that contains one.
I have tried nearly anything with first-child, but it always targets every single li because they are in divs.
here is a jsfiddle if you want to try things
In CSS the format is grandparent parent element child... and :nth-child gives you the element the number specified down, so for your case that would be
.content .thing:nth-child(4) li {
/* CSS goes here */
}
In your example .content is the grandparent, .thing (the fourth one) is the parent, and of course the li is the element. Spaces are required for distinguishing in between levels in CSS.
Here is a working jsFiddle
Edit Without it being hard coded it's impossible to select the first li no matter who it's parent is without javascript.
Here is a jQuery fix:
$('.content').find("li").eq(0).css({ /* CSS goes here */});
Here is a straight javascript fix:
var elems = document.getElementsByTagName('li')[0];
elems.style.property="value";
OK first things first, goal is an invalid attribute so you shouldn't be using it. If you need custom attributes you should be using data-attributes
In order to target an element by attribute you should be using an attribute selector in your case the following selector would work.
li[goal="target"]{
/* Your styles go here.*/
}

How to properly select these elements?

<div id="main-content">
<div>
<div>target me
<div>don't target me</div>
</div>
</div>
<div>
<div>target me too
<div>don't target me</div>
</div>
</div>
</div>
I've tried this:
#main-content div>div {
}
But this ALSO targets the divs saying "don't target me" I wish not to target those divs.
Of course we can use Id's or classes, but the point is to declare a general rule for all.
Please advice.
Just refine the selector a bit to enforce the hierarchy: #main-content > div > div
http://jsfiddle.net/zXaLU/
As a note, when using structural selectors it's nice to reference non-generic tags.
Example: #main-content > NAV > UL is more meaningful than #main-content > DIV > DIV
If you want styles only to apply to the outer of the two divs, you need to use two style definitions. The first sets the style for the div targeted and the second for the inner div not to be targeted:
#main-content div>div {
/* set some styles */
}
#main-content div>div>div {
/* reset the styles defined before */
}
In general the inner div (not targeted) inherits all the styles of its parent div, so in order to nullify that effect, you have to explicitly reset all those styles again.
EDIT
After all comments: If "targeting" does not include usual CSS inheritance, Tim Medora's answer is more suitable. My answer tried to account for inheritance as well.
How [dooes one] properly select [the specified] elements?
The "proper" way would be to give the items you want to select a class that is indicative of their status:
<div id="main-content">
<div>
<div class="someclass">target me
<div>don't target me</div>
</div>
</div>
<div>
<div class="someclass">target me too
<div>don't target me</div>
</div>
</div>
</div>
...and then you can simply use the class selector:
.someclass {
...styles...
}
But if you're unable to modify the markup, you can still use the child selector chain:
#main-content > div > div {
...styles...
}

CSS3 selector to find the 2nd div of the same class

I need a CSS selector that can find the 2nd div of 2 that has the same class. I've looked at nth-child() but it's not what I want since I can't see a way to further clarify what class I want. These 2 divs will be siblings in the document if that helps.
My HTML looks something like this:
<div class="foo">...</div>
<div class="bar">...</div>
<div class="baz">...</div>
<div class="bar">...</div>
And I want the 2nd div.bar (or the last div.bar would work too).
Selectors can be combined:
.bar:nth-child(2)
means "thing that has class bar" that is also the 2nd child.
My original answer regarding :nth-of-type is simply wrong. Thanks to Paul for pointing this out.
The word "type" there refers only to the "element type" (like div). It turns out that the selectors div.bar:nth-of-type(2) and div:nth-of-type(2).bar mean the same thing. Both select elements that [a] are the second div of their parent, and [b] have class bar.
So the only pure CSS solution left that I'm aware of, if you want to select all elements of a certain selector except the first, is the general sibling selector:
.bar ~ .bar
http://www.w3schools.com/cssref/sel_gen_sibling.asp
My original (wrong) answer follows:
With the arrival of CSS3, there is another option. It may not have been available when the question was first asked:
.bar:nth-of-type(2)
http://www.w3schools.com/cssref/sel_nth-of-type.asp
This selects the second element that satisfies the .bar selector.
If you want the second and last of a specific kind of element (or all of them except the first), the general sibling selector would also work fine:
.bar ~ .bar
http://www.w3schools.com/cssref/sel_gen_sibling.asp
It's shorter. But of course, we don't like to duplicate code, right? :-)
UPDATE: This answer was originally written in 2008 when nth-of-type support was unreliable at best. Today I'd say you could safely use something like .bar:nth-of-type(2), unless you have to support IE8 and older.
Original answer from 2008 follows (Note that I would not recommend this anymore!):
If you can use Prototype JS you can use this code to set some style values, or add another classname:
// set style:
$$('div.theclassname')[1].setStyle({ backgroundColor: '#900', fontSize: '1.2em' });
// OR add class name:
$$('div.theclassname')[1].addClassName('secondclass'); // pun intentded...
(I didn't test this code, and it doesn't check if there actually is a second div present, but something like this should work.)
But if you're generating the html serverside you might just as well add an extra class on the second item...
HTML
<h1> Target Bar Elements </h1>
<div class="foo">Foo Element</div>
<div class="bar">Bar Element</div>
<div class="baz">Baz Element</div>
<div class="bar">Bar Second Element</div>
<div class="jar">Jar Element</div>
<div class="kar">Kar Element</div>
<div class="bar">Bar Third Element</div>
CSS
.bar {background:red;}
.bar~.bar {background:green;}
.bar~.bar~.bar {background:yellow;}
DEMO
https://jsfiddle.net/ssuryar/6ka13xve/
What exactly is the structure of your HTML?
The previous CSS will work if the HTML is as such:
CSS
.foo:nth-child(2)
HTML
<div>
<div class="foo"></div>
<div class="foo">Find me</div>
...
</div>
But if you have the following HTML it will not work.
<div>
<div class="other"></div>
<div class="foo"></div>
<div class="foo">Find me</div>
...
</div>
Simple put, there is no selector for the getting the index of the matches from the rest of the selector before it.
And for people who are looking for a jQuery compatible answer:
$('.foo:eq(1)').css('color', 'red');
HTML:
<div>
<div class="other"></div>
<div class="foo"></div>
<div class="foo">Find me</div>
...
.parent_class div:first-child + div
I just used the above to find the second div by chaining first-child with the + selector.
Is there a reason that you can't do this via Javascript? My advice would be to target the selectors with a universal rule (.foo) and then parse back over to get the last foo with Javascript and set any additional styling you'll need.
Or as suggested by Stein, just add two classes if you can:
<div class="foo"></div>
<div class="foo last"></div>
.foo {}
.foo.last {}
First you must select the parent element and set :nth-of-type(n) for the parent and then select the element you want. something like this :
#topmenu li:nth-of-type(2) ul.childUl {
This will select the second submenu from topmenu. #topmenu li is the parent element.
HTML:
<ul id="topmenu">
<li>
<ul class="childUl">
<li></li>
<li></li>
<li></li>
</ul>
</li>
<li>
<ul class="childUl">
<li></li>
<li></li>
<li></li>
</ul>
</li>
<li>
<ul class="childUl">
<li></li>
<li></li>
<li></li>
</ul>
</li>

Resources