I have a fiddle here http://jsfiddle.net/13v2fcjf/
It has a basic html document with lists and sublists
<ul>
<li>Item 1
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
<li>Sub Item 3</li>
</ul>
</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4
<ul>
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
</ul>
</li>
</ul>
And I'm using the following css -
li:hover {
background: #f7f7f7;
}
When I hover on an li item with a subitem(s), all the subitems also get highlighted. This is not desirable. I want only the list item on which the user's hovering to be highlighted. How can I achieve this ?
Also, I tried using the :not selector but it doesn't work.
I think you just need to set the background on the nested <ul> tag. Something like this:
li:hover > ul {
background: #fff;
}
Edit: this is assuming you only want the parent <li> highlighted, which as #j08691 points out in the comments, might not be entirely what you're after. If you want each <li> to be highlighted, you might have to modify your HTML slightly to make this easier:
<ul>
<li><a>Item 1</a>
<ul>
<li><a>Sub Item 1</a></li>
<li><a>Sub Item 2</a></li>
<li><a>Sub Item 3</a></li>
</ul>
</li>
<li><a>Item 2</a></li>
<li><a>Item 3</a></li>
<li><a>Item 4</a>
<ul>
<li><a>Child 1</a></li>
<li><a>Child 2</a></li>
<li><a>Child 3</a></li>
</ul>
</li>
</ul>
By wrapping the items and sub-items in another tag - here I've just used an <a> tag for the sake of argument - you can target that tag to be highlighted on :hover without the nested tags being affected in the same way as in your original code:
a {
display: inline-block;
padding: 4px;
}
a:hover {
background: #f7f7f7;
cursor: pointer;
}
See http://jsfiddle.net/13v2fcjf/3/
If Ian's option doesn't work for you, a second opotion is to wrap the <li> contents in a span and apply the hover to that, like this example fiddle:
HTML:
<ul>
<li><span>Item 1</span>
<ul>
<li><span>Sub Item 1</span></li>
<li><span>Sub Item 2</span></li>
<li><span>Sub Item 3</span></li>
</ul>
</li>
....
CSS
li span:hover {
background: #f7f7f7;
cursor: pointer;
}
HTH,
-Ted
This effect is just natural because the sub items are inside of the main items.
There are two options that come to my mind:
1.) Resetting the background color of the sub lists with
li:hover > ul {
background-color: white;
}
2.) Using the li items as a container:
<li><span class="highlighted">Item</span></li>
.highlighted:hover {
background-color: red;
}
This was a challenge, but the following CSS works with your existing markup. It highlights only a hovered li, without highlighting its parent.
The main trick is to have the CSS create new content when hovering over a nested li. You can do this using the :before pseudo element:
li li:hover:before {
content: '';
position: absolute;
top: 0; bottom: 0; right: 0; left: 0;
z-index: -1;
background: white;
}
(If you're targeting CSS3 browsers only, you can use ::before instead of :before.)
This causes a nested li to cover up its parent li. The negative z-index prevents the background from covering up any text.
Parent li's need relative positioning with a z-index, and nested li's need static positioning for this to work:
li {
position: relative;
z-index: 0;
}
li li {
position: static;
}
The other trick has been mentioned in other posts:
li:hover ul {
background: white;
}
Full CSS:
li {
line-height: 1.65em;
cursor: pointer;
}
li {
position: relative;
z-index: 0;
}
li li {
position: static;
}
li:hover {
background: #def;
}
li:hover ul {
background: white;
}
li li:hover:before {
content: '';
position: absolute;
top: 0; bottom: 0; right: 0; left: 0;
z-index: -1;
background: white;
}
Working fiddle
Related
Why is the dropdown ul in 'Menu Item 2' not being aligned absolutely to the top of its parent li element?
With the dropdown ul CSS set as:
position:absolute;
top:0;
left:0;
I would expect it to be covering from the top left of the parent element, i.e. covering it completely.
Some confusing symptoms:
I want the parent menu to be clickable AND have a dropdown in some cases. So where there is a dropdown, the parent menu <li> has an <a> that is padded to increase the clickable area. This also increases the containing <li>, since the li:hover shows the same padded area. This works as desired.
However, when the dropdown is shown and aligned to <li>, <li> seems to be in the position before it was expanded by <a>. When I check in a browser (Chrome and Firefox) the <li> element is not actually filling the same space as the <a> and so the dropdown appears some amount below the where I want it.
I understand that I can use top:SOME_NEGATIVE_OFFSET in the absolutely positioned dropdown but this feels hacky and I'd like to understand what's going on?
It's my first post, please go easy on me :)
<!DOCTYPE html>
<html>
<head>
<title>DropDownTest</title>
<style>
ul{
list-style:none;
margin:0;
padding:0;
}
li{
display:block;
position:relative;
}
li>a{
padding:1rem;
background-color:grey;
}
li>a:hover{
background-color:lightgray;
}
.mainbar>li{
float:left;
}
li.hasDrop:hover>ul{
display:block;
}
.dropContent{
display:none;
position:absolute;
top:0; /*not working as expected*/
left:0;
margin:0;/*thought this might have helped but no*/
padding:0;
z-index:1;
list-style:none;
min-width:100%;
}
.dropContent>li>a{
display:block;
}
</style>
</head>
<body>
<div>
<ul class="mainbar">
<li>Menu Item 1</li>
<li class="hasDrop">
Menu Item 2
<ul class="dropContent">
<li>Sub 1</li>
<li>Sub 2</li>
<li>Sub 3</li>
</ul>
</li>
<li>Menu Item 3</li>
</ul>
</div>
</body>
</html>
It happens beacuse your a element is getting padding as inline element.
Modify this rule:
li>a {
padding: 1rem;
background-color: grey;
display: block; /* this*/
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
display: block;
position: relative;
}
li>a {
padding: 1rem;
background-color: grey;
display: block; /* this*/
}
li>a:hover {
background-color: lightgray;
}
.mainbar>li {
float: left;
}
li.hasDrop:hover>ul {
display: block;
}
.dropContent {
display: none;
position: absolute;
top: 0;
/*not working as expected*/
left: 0;
margin: 0;
/*thought this might have helped but no*/
padding: 0;
z-index: 1;
list-style: none;
min-width: 100%;
}
.dropContent>li>a {
display: block;
}
<div>
<ul class="mainbar">
<li>Menu Item 1</li>
<li class="hasDrop">
Menu Item 2
<ul class="dropContent">
<li>Sub 1</li>
<li>Sub 2</li>
<li>Sub 3</li>
</ul>
</li>
<li>Menu Item 3</li>
</ul>
</div>
I created a navigation bar at for my website using an in-line list and then it has been styled. Each <li> is exactly the same but I want the last one to have a different size as i wish to change the width and padding of it.
I have no idea how I am able to do this, I've tried multiple ways but experienced lots of problems along the way. I tried adding styling in the <li> tag on the HTML page, but it changed absolutely nothing, I then tried using the last-child selector which worked to an extent. It allowed me to change the padding of it but not width. But it didn't just change it for the last one but also the first one.
CSS:
.dropdown{
position: relative;
margin: 0 auto;
float: right;
top: 20px;
font-size: 13px;
}
.dropdown li {
float: left;
width: 155px;
background-color:#373737;
position: relative;
border-bottom:1px solid #575757;
border-top:1px solid #797979;
}
.dropdown li a {
display: block;
padding: 10px 8px;
color: #fff;
position: relative;
z-index: 2000;
text-align:center;
}
.dropdown li a:hover,
.dropdown li a.hover{
background: #CF5C3F;
position: relative;
}
.dropdown :last-child li a{
padding: 0px;
width: 40px;
}
HTML
<ul class="dropdown">
<li><a id="page1" href="index.html">Home</a></li>
<li>Internet Architecture
<ul class="sub_menu">
<li>Item Two</li>
<li>Item Three</li>
<li>Item Four</li>
<li>Item Four</li>
</ul>
</li>
<li>Internet Security
<ul class="sub_menu">
<li>Laws</li>
<li>Security Risks</li>
</ul>
<li>Internet Security
<ul class="sub_menu">
<li>Laws</li>
<li>Security Risks</li>
</ul>
</li>
<li>Item One
<ul class="sub_menu">
<li>Item Two</li>
<li>Item Three</li>
<li>Item Four</li>
</ul>
</li>
<li><img src="images/contact_white.png" width="30px" height="auto"></li>
</ul>
Does anyone have any idea on how to fix this?
I want the last one to have a different size as i wish to change the width and padding of it.
So if you meant last child of level 1 than use
ul.dropdown > li:last-child {
/* Target */
}
And if you meant each last child of li on 2nd level ul, than use
ul.dropdown > li > ul > li:last-child {
/* Target */
}
Demo
Demo (Just more elements, nothing fancy)
I may be missing something here, but if I understand your question right it's as simple as giving the <li> you want to be the odd one out an id, and then using css to change li#myId..
I have a menu with sub menus. I used nested uls to achive this. Now I'm facing this situation: I want all the items and subitems to be displayed horizontally at their respective level. The problem is that when an parent list has a children list, it's width grows so the next item at the same level goes far to the right.
To have things more clear here's a fiddle of what I'm taking about: http://jsfiddle.net/matias/n8gFT/
As you can see I would like to have the items B and C placed where the green dashed spaces are.
Is it possible to do this?
I would like to keep using nested uls and display: inline-block for itemes instead of float: left
SAMPLE HTML:
<ul>
<li>ITEM A
<ul>
<li>sub item A1</li>
<li>sub item A2</li>
</ul>
</li>
<li>ITEM B</li>
<li>ITEM C</li>
</ul>
SAMPLE CSS:
ul{border: 1px solid red; padding: 10px;}
li{display: inline-block; border: 1px solid blue; margin: 5px; padding: 10px; vertical-align: top;}
span{border: 1px dashed lime; margin: 0 10px; padding: 5px;}
EDIT 1: I forgot to tell you this: A, B and C have children. If I click on B, it's children are shown and A's and C's are hidden...and so on....
We will start off with a little CSS
#menu > li.sub ul {
list-style: none;
position: absolute;
top: -1000em;
left: 0px;
}
#menu li.sub ul li a {
display: inline;
}
#menu > li.sub:hover ul {
top: 3em;
}
#menu{
text-align:left;
}
li{
display:inline-block;
}
Finish with some HTML
<ul id="menu" >
<li class="sub">
ITEM A
<ul>
<li>sub A1</li>
<li>sub A2</li>
</ul>
</li>
<li class="sub">
ITEM B
<ul>
<li>sub B1</li>
<li>sub B2</li>
</ul>
</li>
<li class="sub">
ITEM C
<ul>
<li>sub C1</li>
<li>sub C2</li>
</ul>
</li>
</ul>
and a JSFIDDLE http://jsfiddle.net/ShADm/28/
You could style the lists that are being pushed over of margin-left: -20px; here is a working fiddle
http://jsfiddle.net/n8gFT/1/
Of course the amount it is pushed over can be edited by changing the margin-left
I achieved what I was looking for using display: table-cell to the li's and reducing ul's width.
See demo
Add a class to the sub lists and style them like this:
.sub { position: absolute; margin-left: -27px; }
First of all, sorry for my english, it is not perfect. I have a tree ordered in ul lists, something like this (it is dinamic):
<ul>
<li>
Level 1
<ul>
<li>Item level 2</li>
</ul>
</li>
</ul>
<ul>
<li>
Level 1
<ul>
<li>
Item level 2
<ul>
<li>Item level 3</li>
<li>Item level 3</li>
</ul>
</li>
<li>
Item level 2
</li>
<li>
Item level 2
</li>
</ul>
</li>
</ul>
This is the result I would like:
http://oi48.tinypic.com/dpgt4p.jpg
I would like to join each father with its son with lines. I know how to display each div correctly with display:table, display:cell, etc... But I have no idea about how to draw those lines with css for joining the divs.
Has anybody any idea or suggestion please? I would like to combine HTML + CSS or any solution with Javascript.
Have you ever seen before something like this?
This is a CSS only approach. It's a not a fully working example but maybe it helps you to get into the right direction.
I used this background image to connect the items: This must be improved, as it doesn't work solely when there are multiple child elements on a sibling.
CSS
ul {
position: relative;
width: 100px;
left: 115px;
}
ul > li {
position: relative;
}
ul > li > ul {
margin-top: -18px;
}
ul > li > ul > li:before {
content: '';
position: absolute;
top: 5px;
left: -31px;
width: 30px;
height: 5px;
background: transparent url(http://i.stack.imgur.com/l2mLf.png) no-repeat 0 -10px;
}
ul > li > ul > li:first-child:before {
top: 10px;
left: -21px;
width: 20px;
height: 1px;
background: transparent url(http://i.stack.imgur.com/l2mLf.png) no-repeat 0 0;
}
Demo
Try it
You can use jsPlumb as an add on to jQuery. It will allow you to plumb the elements together, or for a slightly more simple solution take a look at raphaels example.
I'm currently trying to create a drop-down menu from nested unordered lists. I have the menu working however I'm having some issues with regards to styling. The overall link that triggers the drop-down is clickable and needs to have a blue background with white text however, the drop-down elements need to have a grey background which is inherited from the overall navigation container. All I need to do is modify the text colour however whatever I method I try it always modifies the drop-down text colour as well as the heading link colour.
My CSS can be found below along with an example of the current display and the html used to generate the menu:
/*CSS*/
#coolMenu,
#coolMenu ul {
list-style: none;
}
#coolMenu {
float: right;
}
#coolMenu > li {
float: left;
}
#coolMenu li a {
display: block;
/*height: 2em;
line-height: 2em;
*/
/*padding: 0 1.5em;*/
text-decoration: none;
color: #ffffff;
}
#coolMenu ul {
position: absolute;
display: none;
z-index: 999;
}
#coolMenu li:hover ul {
display: block;
}
.dropdown a li{
color: #124162 !important;
}
#style_me > li > a{
color: #124162 !important;
}
/HTML/
<nav id="navigation" class="navigation">
<ul>
<li class="current">Home</li>
<li>Who Are We?</li>
<li>Why Join Us?</li>
<li>Contact Us</li>
</ul>
/* This is the menu element that needs styling */
<ul id="coolMenu">
/* THis should be blue background white text */
<li>Login / Register
<ul id="style_me">
/* These should be grey background blue text */
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
<li>Link 4</li>
<li>Link 5</li>
<li>Link 6</li>
<li>Link 7</li>
</ul>
</li>
</ul>
</nav>
Any help would be greatly appreciated. It's been a couple of years since I've had to do any CSS and my memory is a bit flakey!
This should do what you want:
#style_me li a {
color: #124162 !important;
}
(just spaces instead of >) And, perhaps, you won't need that !important.
Update: try even more specific CSS selector if what you posted is being overridden.
#coolMenu li #style_me li a {
color: #124162 !important;
}