Why does the child selector select all descendants? - css

The child selector should select the immediate children contained by an element. But in the following code, the selector div > ul > li select all descendant <li> of <div>. I have no idea why the child selector expands its scope?
div>ul>li {
text-decoration: underline;
color: blue;
}
<div>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3
<ul>
<li>Item 31</li>
<li>Item 32</li>
</ul>
</li>
</ul>
</div>

If you take a look at the page in Chrome or Firefox's developer tools, you'll see what's happening. The selector isn't applying to the further descendants—instead, they're inheriting the color from their parent.
By default, the color property isn't set. This is equivalent to setting color: inherit;—in other words, it means "since I have no special instructions, I'll do whatever my parent is doing". So when you set a color for an element, it'll also apply to all that element's descendants, unless any of them specify a color of their own.

#Draconis' answer is off to a good start, but the comments suggest there is no solution to the underlining. So here is a solution.
/* Set all list elements to a default value. change this to what you need it to be */
li {
color: black;
text-decoration: none;
}
/* Then set the inner ULs to full width inline-block; which will prevent the
text-decoration from inheriting into them */
div>ul ul {
display:inline-block;
width: calc(100% - 40px);
}
div>ul>li {
text-decoration: underline;
color: blue;
}
<div>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3
<ul>
<li>Item 31</li>
<li>Item 32</li>
</ul>
</li>
</ul>
</div>

Related

CSS list decoration

I've hided list decoration, because I'm making dropdown lists. But the issue that it still take empty spase where it was dot before, how may I solve it?
I've delite decoration. but issue is empty spase before li
li {
list-style-type: none;
}
Most user agent style sheets add default padding or margin to ordered and unordered lists. You'll have to remove that too:
ul {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
For future reference, you can look at the elements in your page using your browser's developer tools (F12 by default) to see what CSS is being applied to them:
ul {
display: initial;
}
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>

Ignoring CSS nth-child for submenu li?

I am trying to hide several menu items from my mobile menu using the nth-child selector in CSS.
Here is the source code HTML and CSS: https://jsfiddle.net/jf1r12wh/
The HTML is something like this:
<ul class="mobile">
<li>Item 1</l1>
<li>Item 2</li>
<li>Item 3</li>
<ul><li>Submenu item 1</li>
<li>Submenu item 2</li>
<li>Submenu item 3</li></ul></ul>
I want to use the nth-child (or similar) to hide Item 1 and 2 on the mobile menu, but I don't want it to hide Submenu item 1 and Submenu Item 2, which it's doing.
I'm using this:
.mobile li:nth-child(1){
display: none !important;
}
.mobile li:nth-child(2) {
display: none !important;
}
The problem is that it's applying this to the submenu as well. How can I make it not to do that, and only apply to the main menu items?
All you have to do is show that the rule should only apply to direct children via the use of >
Like this:
.mobile > li:nth-child(2) {
display: none !important;
}
As Paulie_D mentioned in his comment, this is a part of specificity.
EDIT:
Here is a working snippet:
.mobile li:nth-child(1){
color: red;
}
.mobile > li:nth-child(2) {
color: red;
}
<ul class="mobile">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>
<ul>
<li>Submenu item 1</li>
<li>Submenu item 2</li>
<li>Submenu item 3</li>
</ul>
</li>
</ul>
For future reference, I would also like to point out that the correct semantic for a ul inside a ul is for the second ul to be inside it's own li
"The children (direct descendants) of a ul element must all be li elements". I've made sure that my code snippet reflects this for you.

CSS selector last visible child [duplicate]

This question already has answers here:
A CSS selector to get last visible div
(11 answers)
Closed 8 years ago.
Is there a way in CSS to apply CSS rules to a last visible child without knowing the class which makes an element invisible?
Example:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li style="display: none">Item 5</li>
<ul>
<style>
ul > li {
border: 1px solid black;
}
// Remove right border from last visible child
// This does not work of course, but this is what I am looking for
ul > li:last-child:not([style="display: none"]) {
border-right: none;
}
</style>
To be clear: I'm looking for a rule-based selector not class-based in CSS not Javascript. But this answer A CSS selector to get last visible div for example does not work. The problem here is that :last-child and :not can not be combined. :last-child([style="display: block"]) also does not work (when li has dispay: block), because it looks at the style attribute and not at the CSS rule.
Example in bootstrap (NOTE: hidden-md is an example, it could also be an other class which uses display:none):
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li class="hidden-md">Item 5</li>
<ul>
It is not possible with CSS, however you could do this with jQuery. Try this clumsy code.
jQuery:
$('li').not(':hidden').last().addClass("red");
HTML:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li class="hideme">Item 4</li>
</ul>
CSS:
.hideme {
display:none;
}
.red {
color: red;
}
jQuery (previous solution):
var $items = $($("li").get().reverse());
$items.each(function() {
if ($(this).css("display") != "none") {
$(this).addClass("red");
return false;
}
});
From CSS it is not possible :)
maybe if you draw the right border from the left border of next element or next pseudo element , you get half of the job done :http://codepen.io/gc-nomade/pen/ohKwv/
/* basic and naive workaround for borders */
ul {
text-align:center;
}li {
display:inline-block;
padding:0 1em
}
li + li {
border-left:solid;
}
ul:hover li:nth-child(even) {/* test : hide every even lis at once */
display:none;
}

Styling nested lists with any depth

I was wondering if it's possible to style nested unordered lists with CSS only, without using any scripts. The problem is that CSS needs to work for any depth of the list tree.
For example, I have a list:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li class="holder">
<ul>
<li>Item 4</li>
<li>Item 5</li>
<li class="holder">
<ul>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li class="holder">
<ul>
<li>Item 9</li>
<li>Item 10</li>
<li>Item 11</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
And this is my CSS:
li{
background: gray;
border: 1px solid;
display: block;
margin: 2px;
}
.holder{
background: none;
border: none;
}
/*replace these styles*/
li > ul > li{
background: white;
}
li > ul > li > ul > li{
background: gray;
}
li > ul > li > ul > li > ul > li{
background: white;
}
If node's parent has background A, node should have background B. If node's parent has background B, node should have background A.
Please check : http://jsfiddle.net/bCU34/6/
CSS selectors allow you to select all named elements of a parent node by separating the named element from the parent element with a space. To select all unordered list elements, for example, you would do like below. Notice all ul elements at any depth inherit the style no bullets/margin/padding. In order do style nth layer for an element type, you need to use the parent selector >. See below. I used font color but you could set background images the same way. Note there is no decendant level selector at this time that I know of. This was addressed on another post CSS select nested elements up to N levels deep.
.container ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.container > ul > li {
color: green;
}
.container > ul > li > ul > li {
color: red;
}
.container > ul > li > ul > li > ul > li {
color: blue;
}
<section class="container">
<h1>CSS Nested List Styling</h1>
<ul>
<li>
<h3>Section 1</h3>
<ul>
<li>
<h4>Foo</h4>
<ul>
<li>
<h5>Bar</h5>
</li>
<li>
<h5>Bar</h5>
</li>
</ul>
</li>
<li>
<h4>Foo Bar</h4>
<ul>
<li>
<h5>Bar</h5>
</li>
<li>
<h5>Bar</h5>
</li>
</ul>
</li>
</ul>
</li>
<li>
<h3>Section 2</h3>
<ul>
<li>
<h4>Hello</h4>
<ul>
<li>
<h5>World</h5>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</section>
There isn’t any specific way of doing this currently with Selectors level 3, and the current draft of Selectors level 4 doesn’t seem to add anything either. I had a dig through the www-style mailing list and came up with this post by Lachlan Hunt from April 2005 that suggests that an :nth-descendant() style selector had been considered but never specified.

target first submenu of parent ul

I need to target css for the first level ul submenu in a parent ul.
CSS:
#menu li:hover > ul.sub_menu { ...some styles }
..but this will ofcourse do it for all the sub_menu's, I only want this particular style for the first sub_menu relative to the parent when you hover over the parent list item.
HTML:
<ul id="menu">
<li>Item
<ul class="sub_menu"><!-- target only this one -->
<li>Item
<ul class="sub_menu">etc...</ul><!-- do not do for this one and so on-->
</li>
</ul>
</li>
<li>Item
<ul class="sub_menu"><!-- target only this one -->
<li>Item
<ul class="sub_menu">etc...</ul><!-- do not do for this one and so on-->
</li>
</ul>
</li>
</ul>
Thanks for any feedback...
You can use the :first-child selector:
#menu > li:first-child > ul.sub_menu {
color: red;
}
And then use the descendant selector to revert the changes for the other elements:
#menu > li:first-child > ul.sub_menu ul {
color: black;
}
Demo: http://jsfiddle.net/6y4Sb/

Resources