:first-child targeting all child elements - css

I have a unordered list with id of "navigation" and a few child list-item elements.
I am trying to select just the first item with :first-child but it is applying the CSS I use with this to all other list items.
ul#navigation li:first-child{
background:#fff;
}
So, to reiterate: this is giving every list-item a white background. I just want to select the first element. What is going wrong?

According to the comments, your problem is that your markup looks like this:
<ul id="navigation">
<a href="http://google.com">
<li>Google</li>
</a>
</ul>
Note how every li will be a :first-child under this model. I would suggest you go with the more appropriate structure of nesting your anchor within your list item. If you want the anchor to fill up the list item, set its display to block:
<ul id="navigation">
<li>Google</li>
</ul>
With the accompanying CSS:
#navigation a { display: block }
Once you have those structural changes in place, your selector should target the first list item:
/* > to target only immediate list items */
#navigation > li:first-child {
background: red;
}

Related

Why are my hover styles applying to children elements?

I have read what MDN says about the child combinator:
The child combinator (>) is placed between two CSS selectors. It matches only those elements matched by the second selector that are the children of elements matched by the first. Elements matched by the second selector must be the immediate children of the elements matched by the first selector.
What I don't understand is why the other two <li> elements are red, too.
.list > li:hover{
color:red
}
<ul class="list">
<li>I should be red
<ul>
<li>Why I am red too?</li>
<li>Why I am red too?</li>
</ul>
</li>
</ul>
With .list > li you are also including all the children of the parent list (which includes the second ul)
One way of overriding that is by explicitly setting the properties of the second list:
https://jsfiddle.net/6yeh6ggL/4/:
.list li a:hover{
color:red
}
.list ul li a:hover{
color:black
}
Just to help clarify a little.
Your selector is finding the li item you want which is the first one (it is only finding that one). The reason all the li's turn red is because color is set to the first li which is inherited by its children and in the case above those li's are its children.

Good practice on selecting a list menu

Considering this markup:
<div id="container">
<div id="mainmenu">
<ul>
<li> <h1>My Dashboard</h1></li><br>
<li> <h1>About</h1></li><br>
<li> <h1>Contact</h1></li><br>
<li> <h1>Setttings</h1></li><br>
<li> <h1>Log Out</h1></li><br>
</ul>
</div>
</div>
Selecting this way is a valid thing? I am having issues with some properties.
#container ul li{
display: inline-block;
}
#mainmenu ul li a{}
#mainmenu ul li a:hover{}
full sample:
https://jsfiddle.net/jhr1q1q4/
I'm somewhat unsure what you're asking...
Strictly speaking, the selectors you provided are valid and would select the <a> elements within your #mainmenu element.
But I would ask: is the ul li part of the selectors necessary? You could rewrite both of them as
#mainmenu a {}
#mainmenu a:hover {}
and they would work the same and require less parsing. If you wanted to only select <a> elements that are descendants of <li> elements, you could keep the li in your selector; however, the ul is not necessary -- it is implied your <li> elements will be children of a <ul> (assuming you're writing valid HTML).
Another note: <a> elements are inline, meaning they're meant to act at the text level. <h1> elements, on the other hand, are block-level elements, and thus do not belong inside <a> elements. In fact, you usually shouldn't have more than one <h1> on a page, let alone be using <h1>'s to mark up menu items. If you want your menu items to be big like headers, use your CSS rules to style them that way.
I am having issues with some properties.
What properties are causing trouble?

How to get only the last ul of specific id on page via CSS :last-child property?

My page generates two ULs of the same ID and I would like to remove the last one via CSS (display: none). I was trying with :last-child property but no luck at all. I either made both of them disappear or none of them.
Example:
<div id="content">
<ul id="some-ul">
<li>...</li>
<li>...</li>
</ul>
<ul id="some-ul">
<li>...</li>
<li>...</li>
</ul>
</div>
I would like to apply display: none only for the last ul#some-ul inside my #content.
It could be done like so:
#content ul:last-child {
display:none;
}
Note that last-child is only supported in IE9+. As mentioned by #Jop, you should set a class on the last child element to get around this for older versions of IE.
jsFiddle here.
Also, remember that ID's should always be unique.
Completely generic way to do this, that relies on no classes or ID's
div ul:last-of-type li:last-child {
display:none;
}
So basically, the div is the parent item that contains the list items - it could have a class or ID if you want.
Within that, you have your ul tags - the last-of-type does the magic, finding the last ul within the parent div. You then simply use last child on the li.
Here's the fiddle:
http://jsfiddle.net/Kx8SN/

Styling a dynamic nested UL structure

I have a nested UL structure that represents a folder tree which can grow very deep. I'm stuck at doing a simple :hover effect for the LI elements. The problem is that doing a li:hover won't work as it affects all the parent "li's" aswell. Usually I would have tried to apply the hover effect to a link element or something in the LI, to avoid parents taking the style aswell, but due to circumstances that's not an option now. I have a working solution by using javascript to place a class on the hovered LI and then style this class instead, but i'm really interested in seeing if there's actually a way of accomplishing this through pure css.
I imagine there may be a way of doing a very "hardcoded" css solution but i am more interested in a dynamic and clean one, since the structure can nest indefinitely.
Maybe there's some pseudo selector i'm not aware of? Note that it doesn't have to be IE<8 compatible
<ul>
<li>
This LI should not recieve the hover effect
<ul>
<li>
A li:hover will place the effect on this LI,
but also the parent LI, since that element is
also techincally being hovered.
</li>
</ul>
</li>
</ul>
If you want to use pure CSS then you will need to us parent, child, elements.
For the hover elements:
ul li:hover{
"Style"
}
For the other elements:
ul li ul li{
"Style"
}
UPDATE: I just reread your question, in which you state:
"Usually I would have tried to apply the hover effect to a link
element or something in the LI, to avoid parents taking the style as
well, but due to circumstances that's not an option now."
If that is true, then the solution below is not viable for your circumstance, and you cannot achieve what you desire with pure CSS. I've left my answer, however, as others who want to achieve this but can use a nested element may find it useful.
Pure CSS Only by Adding HTML
The only way you can possibly achieve something of what you seek by pure CSS is to add an extra element (like a span) within the li and perform the hover on that. I assume that whatever folder is being hovered, that folder alone is what you want to highlight. If so, this fiddle illustrates what I am saying, using this code:
HTML
<ul>
<li>
<span>Folder 1</span>
<ul>
<li>
<span>Folder 1.1</span>
<ul>
<li>
<span>Folder 1.1.1</span>
<ul>
<li>
<span>Folder 1.1.1.1</span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
CSS
li span:hover {
color: red;
background-color: yellow;
}
Now, if you want child folders to also highlight on hover of a parent folder, then perhaps this fiddle illustrates what you want with this code change:
CSS
li span:hover,
li span:hover + ul span {
color: red;
background-color: yellow;
}
They key point is to utilize the extra element to control the hover, whether of the item itself or any later generation elements that the hover should affect.
Not clear at all... but if you want to style nested LI when you are hovered the parent LI without styling the parent one...
Try this:
CSS
ul li ul li {
color: blue
}
ul li:hover ul li {
color: red
}
fiddle example: http://jsfiddle.net/EHp3n/
Your question is not very clear and also it will confuse. Let me explain, when the user hover the city (India / China / UK), style should be applied to State and Country through CSS.
<ul>
<li>India (Apply Style)
<ul>
<li>India State (Apply Style)
<ul>
<li>India City (On Hover)</li>
</ul>
</li>
</ul>
</li>
<li>China
<ul>
<li>China State
<ul>
<li>China City</li>
</ul>
</li>
</ul>
</li>
<li>United Kingdom
<ul>
<li>UK State
<ul>
<li>UK City</li>
</ul>
</li>
</ul>
</li>
</ul>

css last-child matches all children

I am trying to use create a separator between my links by creating a border on the right side of each of them. Then on the last one, remove it. I have the following html and css but what I'm finding is that each "a" tag matches the last-child selector. I'm not clear why and what the proper way would be to do this.
<ul class="nav">
<li>link1</li>
<li>link2</li>
<li>link3</li>
<li>link4</li>
</ul>
.nav a { border-right:solid 1px #000;}
.nav a:last-child { border-right-width:0px;}
That's because each a is the last-child of its parent li. You'd want something like .nav li:last-child a instead.
All your <a> tags are last children of their parent <li>

Resources