The html snipped below renders a nested list of elements. On hover (mouse over) the elements background color changes. But a space is left uncolored on the left (due to the indentation).
How would I get that space to be colored as well?
I tried to add absolute
positioned elements to the li
elements with left:0
. But those partially hide the content of the li
elements :/
ul {
list-style: none;
padding: 0;
margin:0
}
li {
margin:0;
padding: 0;
padding-left: 20px;
}
li > div:hover {
background-color: #eee
}
<div style="position:relative">
<ul>
<li><div>Root</div>
<ul>
<li><div>A</div>
<ul>
<li><div>AA</div></li>
<li><div>AB</div></li>
</ul>
</li>
<li><div>B</div>
<ul>
<li><div>BA</div></li>
<li>开发者_如何学JAVA<div>BB</div></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
You could use this CSS to make your div's fill the indents so that space is not left uncoloured on the :hover effect, then set the overflow to hidden on the parent wrapper.
li div{
padding-left: 100%;
margin-left: -100%;
}
This way it is generic so that you can have as many sub <ul>
and <li>
tags as you need. Here is a link to a JSFiddle with a working example.
Add the padding to the divs instead of the <li>
:
ul { list-style: none; padding: 0; margin:0 }
li { margin:0; padding: 0;}
li > div:hover { background-color: #eee}
li div{padding-left:20px}
li li div{padding-left:40px}
li li li div{padding-left:60px}
Demo: http://jsfiddle.net/Madmartigan/MKK8v/
By setting it on the list item, you end up padding all the child list items as well. If you can alter your markup, I think there are better ways though.
There problem occurs,because you have applied padding-left: 20px;
,So that Hover will not applied to that part which contains 20px padding
from left.
As my suggestion,For proper html structure & css,You have to assign class or id name to <li>
& <div>
element,due to that you can easily detect problem & get powerful structure.
You can remove padding-left from li element and use jquery to add padding-left to div like this:
$("li>div").each(function(i, div){
var $li = $(div).parent();
var parentCount= $li.parents("li").length;
var padding = parentCount*20;
$(div).css("paddingLeft", padding + "px");
});
Demo
I think the most simple way here would be to put the padding and hover background on your div
elements. It puts a nasty hard limit on your tree nesting levels, as you have to write as many CSS rules as you have levels but... there's likely a horizontal limit for your content width anyways.
ul, li
{
margin: 0;
padding: 0;
}
ul div:hover {
background: #eee;
}
ul ul div { padding-left: 20px; }
ul ul ul div { padding-left: 40px; }
ul ul ul ul div { padding-left: 60px; }
/* et cetera*/
Can be achieved using jQuery.
I have used an invisible div which positions itself on the li
being hovered and fills the whole width
$(document).ready(function() {
$('li > div').hover(function(event) {
$("div#liSelect").show();
$("div#liSelect").css('height', $(this).height() + "px");
$("div#liSelect").css('top', $(this).position().top + "px");
event.stopPropagation();
},
function() {
$('div#liSelect').hide();
});
})
body {
margin: 0px;
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
li {
margin: 0;
padding: 0;
padding-left: 20px;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div style="position: relative">
<div id='liSelect' style='display:none;width:100%;height:100%;position:absolute;left:0px;opacity:0.3;background-color:#555;pointer-events:none;'></div>
<ul>
<li>
<div>Root</div>
<ul>
<li>
<div>A</div>
<ul>
<li>
<div>AA</div>
</li>
<li>
<div>AB</div>
</li>
</ul>
</li>
<li>
<div>B</div>
<ul>
<li>
<div>BA</div>
</li>
<li>
<div>BB</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Would be nicer with CSS, but using jQuery you could:
Add padding to the div
depending on level.
$('li').each((i, el) => {
$(el).children('div').css('padding-left', 30 * $(el).parents('ul').length)
});
https://jsfiddle.net/9ydr6b6z/
Please use this CSS code instead of your code.
ul {
list-style: none;
padding: 0;
margin:0
}
li > div:hover {
background-color: #eee
}
li div {
padding-left: 20px;
}
li li div {
padding-left: 40px;
}
li li li div {
padding-left: 60px;
}
Attempting to find a generic solution I tried with CSS Counters. Unfortunately it seems that counters can only be used in content
properties.
Maybe someone can figure out how to use the counter to get the corresponding padding-left
...
ul {
list-style: none;
margin: 0;
padding: 0;
counter-increment: level;
}
ul:after {
content: "";
counter-increment: level -1;
}
li div:hover {
background-color: #ddd;
}
li div {
padding-left: calc(20px * counter(level));
}
li div:before { /* Just for debugging purposes */
color: #bbb;
content: counter(level)" ";
}
<div style="position:relative">
<ul>
<li><div>Root</div>
<ul>
<li><div>A</div>
<ul>
<li><div>AA</div></li>
<li><div>AB</div></li>
</ul>
</li>
<li><div>B</div>
<ul>
<li><div>BA</div></li>
<li><div>BB</div></li>
<li><div>BC</div>
<ul>
<li><div>BCA</div></li>
<li><div>BCB</div></li>
</ul>
</li>
</ul>
</li>
<li><div>C</div></li>
</ul>
</li>
</ul>
</div>
精彩评论