CSS Child Selector (>) not working with certain properties - html

When I'm trying to select all direct child of a parent element using ">", it works with some properties like border and all, but not with font-properties like color, font-weight etc..
My HTML is
<ul>
<li>Item 1</li>
<li>
<ol>
<li>Subitem 2A</li>
<li>Subitem 2B</li>
</ol>
</li>
</ul>
CASE1 CSS:
ul>li {
color:#F00;
}
But here the color:#F00 property gets applied to all the "li" elements, But i want it to get applied only for the direct "li"s of "ul".
CASE 2
CSS:
ul>li {
border: solid 1px #000;
}
This one works well for me and the border gets applied only to the direct li child only.
I know it can be resolved by overriding with some other classes and all. But i want to know, why some css properties get inherited and others not.

It's happening due to the default inheritance capability of certain CSS Properties. Values of these kind of properties will be transmitted to the child by default.
This document from W3C gives detailed list of inheritance in various CSS properties. Full property table

try this
Demo
<ul>
<li>Item 1</li>
<li>
<ol>
<li>Subitem 2A</li>
<li>Subitem 2B</li>
</ol>
</li>
</ul>
css
ul > li {
color:#F00;
}
ul > li > ol > li {
color:#000;
}

try this
ul > li ol li {color:black;}

As the listing element has been inheriting the color property from its parent, you need to override it.
You can add below style before yours as like
li {
color: #000;
}
ul>li {
color:#F00;
}
It overrides the color: inherit value.

I think you might find the answer you need here: http://www.w3schools.com/cssref/sel_firstchild.asp
You should be able to select these elements with
ul:first-child {
// css
}
Hope this helps

Related

Direct children (Child combinator) selector not restricting to children

Why do the nested <ol> list items receive the sqpurple.gif bullet?
ul > li {
list-style: outside url("https://www.w3schools.com/cssref/sqpurple.gif") disc;
}
<ul>
<li><ul> - parent
<ol>
<li><ol> - parent. Shouldn't this be a number?</li>
</ol>
</li>
</ul>
Windows 10 x64
Chrome v91.0.4472.114
Firefox v89.0.1
Edge v91.0.864.67
Per https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-image:
Note: This property is applied to list items, i.e. elements with display: list-item; by default this includes <li> elements. Because this property is inherited, it can be set on the parent element (normally <ol> or <ul>) to let it apply to all list items.
To fix this you should reset the <ol> to have no image.
The use of ul > li is flawed since you should be setting the list-style-image property on the <ul> or <ol>
ul {
list-style-image: url("https://www.w3schools.com/cssref/sqpurple.gif");
}
ol {
list-style-image: none;
}
<ul>
<li><ul> - parent
<ol>
<li><ol> - parent. This is now a number as expected!
<ul>
<li><ul> - parent</li>
</ul>
</li>
</ol>
</li>
</ul>
I had to puzzle this one out, too, and I've been doing CSS for more than 20 years. The best way to explain it, I think, is that the rule is inherited, not the selector. That is, any element inside the selected element gets the rule, and since any li accepts a list-style property rule, it applies.
As others have demonstrated, the solution is to override for interior list items. You may also be able to implement the :not pseudo-selector to be more restrictive in your selector. (Actually, you can't, at least using combinators).
Here is a similar post: https://stackoverflow.com/a/6367905/9730836
You can reset the style to every children (as there is inheritance).
Try:
ul>li {
list-style: outside url("https://www.w3schools.com/cssref/sqpurple.gif") disc;
}
li * {
list-style: initial;
}
<ul>
<li><ul> - parent
<ol>
<li><ol> - parent. Shouldn't this be a number?</li>
</ol>
</li>
</ul>

Why is a second-child affected by my first-child color property?

I was finishing up selectors and testing my knowledge and encountered a problem that makes no sense.
In theory, the code below should color all first children that are li red, yet, a first and second child are being colored red.
Why is the second child colored red here?
li:first-child{
color: red;
}
<ul>
<li>Peter
<ol>
<li>Juan</li>
<li>Samuel</li>
</ol>
</li>
<li>John
<ol>
<li>Patrick</li>
<li>Spongebob</li>
</ol>
</li>
<li>Sara
<ol>
<li>Jonathan</li>
<li>Kragie</li>
</ol>
</li>
</ul>
color is inherited from the parent element....in this case the li:first-child
So when you tell the li to be a red color this is inherited by all its children.
You have no rule to override this for the children so they are colored by inheritance/
It happens because the color is inherited from the parent element, try to add this to your CSS to override it:
li {
color:initial;
}
This is because you have nested lis.
The second inner li is being coloured red because it's inheriting that rule from the style applied to the first child outer li, ie its parent.
li:first-child { color: red; }
li:not(:first-child) { color: black; }
That will override the inheritance and result in the text of the first outer and inner lis being red. Fiddle
Alternatively, if you want to colour only the inner lis:
li li:first-child { color: red; }
The li:first-child selector will also select the first li element in your parent list. You can target your selector using direct descendents or you can use classes.
Option 1: class selector on parent list
This is the preferred option as it will automatically namespace your css. All your selectors will start with .menu when targeting child elements.
<ul class="menu">
<li>Peter<ol>
<li>Juan</li>
<li>Samuel</li>
</ol></li>
</ul>
.menu ol li:first-child{
color: red;
}
If you want to override the style of a menu, you can use an extra class on the menu element and for example target it with the following selector. .menu.horizontal
Option 2: class selector on list item
This option has the same benefits of the first option, but now .menuItem is namespaced on its own.
<ul>
<li class="menuItem">Peter<ol>
<li>Juan</li>
<li>Samuel</li>
</ol></li>
</ul>
.menuItem ol li:first-child{
color: red;
}
Option 3: direct descendent selector
ol>li:first-child{
color: red;
}
It is always better to use classes because if you use ol elements in other places, the selector would still apply there.

Property is not acting according to the specification

I'm having a hard time understanding why the behavior of certain properties do not follow the behavior stated in the W3 specification.
For example, in the specification it says that the "background-image" and "background-color" property is not inherited.
But the following code proves this otherwise.
The CSS
#nav > li {
background-color: yellow;}
The markup
<div>
<ul id="nav">
<li>This is a list</li>
<li>This is a list</li>
<li>
<ul>
<li>This is a list</li>
<li>This is a list</li>
</ul>
</li>
</ul>
</div>
You will see that even the 2nd level list items which is nested inside the 3rd list item also has their background-color changed, while I only intended for it to be applied only on the direct children which is the 1st level list items.
Now my question is this.
Why is this happening? Who is in the wrong here, the browsers or the specification? Am I missing something?
Any help is appreciated.
I think I found your answer.
When you look at the devtools, you will see, that the 2nd level got no background-color. The color you see, is the color of the parent li :-)
Fiddle
#nav > li {
background-color: yellow;
}
With the border property you can see it better.
Updated fiddle:
http://jsfiddle.net/2brhj2bq/1/
#nav li {
border:1px solid red;
}
#nav > li {
border:1px solid lime;
}
This is because the next UL is also in the Li , and li have bg color yellow so it should be yellow . just think it what have you done , you are assigning bg then you are seeking why it is happening it is not the bg of inner ul li it is the bg of ul#nav li.

Removing default styling from HTML list elements

So I have some code that looks like:
<ul>
<li>
<ul>
<li> ... </li>
</ul>
</li>
</ul>
This has indented itself. I have no styling to indent this. According to the computed styling there is no margin-left, yet everything is actually indented, I guess this is the default behaviour of nested ul elements?
Regardless, on every nested ul, I have a class that is called comment-children I need to say only 5 down can indent (so .comment-children .comment-children .comment-children .comment-children .comment-children done, great) but at a width of 640px, all nesting must be turned off.
The part I am having the trouble with is that the ul elements are nested by default http://jsfiddle.net/d7az0jv3/
What do you want to do
Remove all default nesting and let me nest it my self via the class comment-children
At 640px remove all nesting.
Your example is insufficient to demonstrate what you want to do involving the class comment-children, but generally, to remove the indentation on lists across browsers, you should implement the rules
ul, li { margin-left: 0; padding-left: 0; }
Here's an updated jsfiddle
If you want to only nest elements up to a certain level, my recommendation would be to apply a class to the base ul that sets the indentation, and then add a rule that stops the indentation at a certain depth below that base class. Here is an updated version of your code with the nesting stopping at level 5.
HTML:
<ul class="comment">
<li>level one</li>
<li>
<ul>
<li>level two</li>
<li>
<ul>
<li>level three</li>
(etc., up to level seven)
CSS:
ul {
list-style:none;
}
ul, li { /* reset the margin and padding */
margin: 0;
padding: 0;
}
.comment ul {
/* 1 em margin for the UL elements under .comment */
margin-left: 1em;
}
.comment ul ul ul ul ul {
/* stop the nesting! */
margin-left: 0;
}
jsfiddle for this

Pseudo-class inside :not

Is it possible to use a pseudo class inside of a :not tag?
Example:
li:not(.inner:hover):hover { // Code }
<li>
<div class="inner"></div>
</li>
I am trying to cancel out the effect of the parent hover, when I hover an inner item, without using javascript.
The expected result for above code is when you hover the li, but not the inner div, the li get's a hover effect. But only if you're not hovering the .inner.
Update
http://jsfiddle.net/eTV86/
What I want is, when the .inner turns black, the li turns back to red.
Yes, but you're using both a class and a pseudo-class, which is invalid:
li:not(.inner:hover):hover
Even if you change it to something that's valid (as per this answer):
li:not(.inner):hover, li:not(:hover):hover
The first selector will always match your li on hover, and the second selector won't ever match anything. It will never match your div.inner because you're attaching the :not() to the li.
Lastly, if you want to change the li when .inner gets a hover, that's not possible with current CSS selectors. You'll need JavaScript.
You can use the simple css instead pseudo class
HTML
<ul>
<li class="active">Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
​
​
CSS
ul li a{ color:black}
ul li a:hover { color:red }
ul li.active a:hover { color:black /*re use the same properties which is there in default style viz ul li a{} */}
DEMO http://jsfiddle.net/mKQas/2/