Parent and siblings inherits a child list items styles - css

I have a simple menu
<ul id="menu">
<li class="leaf">Menu Item 1</li>
<li class="leaf">Menu Item 2</li>
<li class="expanded">Menu Item 3
<ul>
<li class="leaf">Menu Item a</li>
<li class="leaf">Menu Item b</li>
<li class="leaf">Menu Item c</li>
</ul>
</li>
<li class="leaf">Menu Item 4</li>
</ul>
and
ul#menu li:hover {font-weight:bold;}
The problem I am facing is when I hover above a ul li li, the parent as well as all its siblings gets the hover effect. I only want the list item I hovered above to get the effect.
I tried ul#menu li.leaf:hover {..}, ul#menu li.expanded:hover {..} , but even in that case, when I hover above li.expanded, it's child inherits the style.
It is important for me to style the list items, not a (the style is more complicated than the one I posted)
How do I fix this?

I'm not really sure why this might be happening, but I'm assuming you're trying to put together a CSS-based dropdown menu?
I would recommend that you check out http://htmldog.com/articles/suckerfish/dropdowns/. It's a great help, and I always base dropdown menus off of it.
Sounds like your problem is some weird inheritance bug - does it happen in all browsers?

#menu li:hover li { font-weight:normal }
#menu li:hover, #menu li li:hover {font-weight:bold;}
The first rule prevents making all 2nd-level li's bold when a parent li is hovered. the second rule then sets only the currently hovered 1st-level li's and currently hovered 2nd-level li's to bold.

Related

hover on parent element with css

I was wondering if there is a way you can apply a hover effect on parent element with just css.
For example, I have a navigation:
<nav>
<ul>
<li id="firstLiElement" class="main-nav ieraksti">ieraksti!</li>
<ul id="audio_sub_menu">
<li class="mes">mēs 1</li>
<li id="klienti">mēs 2</li>
</ul>
<li class="main-nav" id="audio">paklausies!</li>
<li class="main-nav" id="video">paskaties!</li>
<li class="main-nav" id="kontakti">pasūti!</li>
</ul>
</nav>`
And what I want is to, when hovered on
nav ul ul li
element, it affects the
#firstLiElement
.
I know it can be done with JS, but there has to be also a way to do this with css. I found a lot of solutions when you need to affect the sibling or child, but didn't find anything for this situation.
EDIT:
Sorry, didn't even write what I was looking for... Yes, sub_menus are hidden, but when I hover the main navigation li element, they shove up, and they stay visible also when I hover on them. What I am missing is to change the background color of the main navigation li element when the sub menu is hovered.
I found this for you.
a < img { border: none; }
In this example, it would select a tags but only if they contained an img tag. (Aside: this would be a weird departure from the typical syntax where the actual elements being selected are on the right, this would be on the left).
a img:parent { background: none; }
The key difference being that the :parent syntax would only evaluate a single element, the parentNode available in the DOM for every element. This would be similar to forcing the :has selector to only evaluate children rather than all descendants.
https://css-tricks.com/parent-selectors-in-css/
I believe it can't be done. CSS or Cascade Style Sheet - keyword here is Cascade - executes in a cascade direction and not the other way around.
You can do this (assuming the audio_sub_menu, i.e., is hidden):
nav ul a:hover ul {
visibility: visible;
}
And you'll be targeting a child on its parent hover. So, you can either change your layout and design to use this knowledge, or go with the JS solution :)
edit
to get the same color, style the :hover on the parent as well and change the first </a> in your HTML code
<nav>
<ul>
<a href="#"><li id="firstLiElement" class="main-nav ieraksti">ieraksti!</li>
<ul id="audio_sub_menu">
<li class="mes">mēs 1</li>
<li id="klienti">mēs 2</li>
</ul>
</a>
<li class="main-nav" id="audio">paklausies!</li>
<li class="main-nav" id="video">paskaties!</li>
<li class="main-nav" id="kontakti">pasūti!</li>
</ul>
</nav>
And the CSS
nav ul a:hover {
background-color: your_color;
}
nav ul a:hover ul {
visibility: visible;
background-color: your_color;
}
edit - On the hetasbo's answer
those are suggested css selectors, they don't exist

Multiple sub-menus and scrolls

In Wordpress i created a menu with sub menus and i want to scroll down so the menus are not going to be so big. so i add
Blockquote
.sub-menu li:hover ul and then overflow-y
Blockquote
But only the first submenu becomes a scrolling on. If i have submenu in a submenu then the first submenu doesn't work..
check what i mean here http://www.intereuropetravel.com
Read your rule from right to left.
.sub-menu li:hover ul
This says "for any ul within an li:hover which is within a .sub-menu - { apply these rules }
I can't tell exactly what you want - but I think your selector is not doing what you intend. - so write out what you want to happen, and think about it from right to left.
The only reason why WordPress is relevant, is that it gives you some default classes for your menu.
<ul class="menu">
<li>List item
<ul class="sub-menu">
<li>Sub menu item
<ul class="sub-menu">
<li>etc
<ul class="sub-menu">
<li>etc</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
So, this is some pretty gnarly nesting and, I'm just going to say - that maybe you should rethink this approach, but otherwise - I suggest you build out more specific selectors for each level and control them independently. In WordPress admin under menu - you can reveal a field that will allow you to give unique classes to each of these levels with which you can target more easily.
in your case, you can probably put
.menu-main-menu-container li:hover ul {} -
which would be --- "any list inside of any li in your container {}"
maybe even:
.menu-main-menu-container li:hover > ul {}
which would be --- "any list directly inside of any li in your container {}"

Putting two ul elements side-by-side in a menu and changing to click instead of hover

I have this menu using just CSS and HTML.
Some of the sub-menus are long, so I would like to sub-divide them into separate lists of up to 5 items and display them side by side instead of underneath each other.
So I've put them in a <div> and created 2 separate <ul> items. I tried to make them display: inline and set the maximum height of the <div> to 100px but it doesn't really force the browser to put the second <ul> beside the first one.
<li>
Sub Item 1.2 Can be long
<div>
<ul>
<li>Sub Item 1.2.1</li>
<li>Sub Item 1.2.2</li>
<li>Sub Item 1.2.3</li>
<li>Sub Item 1.2.4</li>
<li>Sub Item 1.2.5</li>
</ul>
<ul>
<li>Sub Item 1.2.6 From here should be in 2nd col</li>
<li>Sub Item 1.2.7</li>
<li>Sub Item 1.2.8</li>
<li>Sub Item 1.2.9</li>
<li>Sub Item 1.2.10</li>
</ul>
</div>
</li>
Full working sample here: http://jsfiddle.net/nhfHw/17/
To see the issue just hover over Item 1 > Sub Item 1.2 Can be long
Apart from this I would like to make the menu open up the sub-levels on click rather than hover but I guess its not possible using just CSS. What is the best approach to do it in javascript?
To have them sit side-by-side, use display:inline-block on those sub-sub ULs (Fiddle):
#nav ul li ul li ul
{
display:inline-block;
float:none;
}
For binding the clicks, here is the way to do it with pure JS: How do I bind a click to an anchor without a framework (javascript)
If you want to use jQuery, I'd recommend toggling a class and using that in the css to display/hide the navigation:
$('#nav li').bind('click', function() {
$(this).toggleClass('open');
}
then in your CSS do something like:
#nav ul li.open ul {
display:block;
}

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: set style only for li that have inside an ul

I have an unordered list (ul) with some list items (li). One of this have another unordered list inside (ul). Now, I want to se to all these li the same stylesheet, except for the li that have another unordered list inside.
<ul>
<li>Element</li>
<li>Another Element</li>
<li>Special Element
<ul>
<li>Child</li>
<li>Child</li>
</ul>
</li>
</ul>
How can I set CSS without set a specific class for the special li?
ul ul li { your-rules: here; }
I recommend giving this a read, it will help you understand the cascade and specificity: http://reference.sitepoint.com/css/inheritancecascade
-- edit --
Sorry, just realised you want to style the li, not the ul li inside.
li:nth-child(3) { your-rules: here; }
NOTE: this will affect your inner lis as well if there are three or more.
Read http://css-tricks.com/how-nth-child-works/ to understand the rule I've suggested you use.
In the current CSS specs, this is not possible. There is no selector for "an element that contains some specific content". It may be possible in CSS4, but as of now, you will have to take special measures to single out the "special" li.
<ul>
<li>Element</li>
<li>Another Element</li>
<li class="specialelement">Special Element
<ul>
<li>Child</li>
<li>Child</li>
</ul>
</li>
</ul>
and give class .specialelement a style of its own.
try with
ul li > li {
some style
}

Resources