Reputation: 589
I'm sure there are similar questions out there but I haven't been able to find a conclusive answer. I have an HTML script with nested divs:
<ul id="navbar">
<li><a href='#' class='dropdown'>Rules</a>
<div class='rules'>
<ul>
<li>Rules Explanation Here</li>
</ul>
</div>
</li>
</ul>
I believe that the div class 'rules' is a child of the class 'dropdown'. However when I was working on my css file, I couldn't get a hovering action on the dropdown class to effect my rules class unless I used the ~ connector.
This works in my CSS file:
.dropdown:hover ~ .rules{
opacity: 1;
}
But this does not work:
.dropdown:hover .rules{
opacity: 1;
}
As I understand it the ~ should only work if the classes are siblings which I do not believe they are.
Could someone explain why these classes are siblings here or link me to an easy to understand explaination.
Upvotes: 0
Views: 82
Reputation: 5013
Here's a fully indented version of your code, which I think will help you visualize the answer better:
<ul id="navbar">
<li>
<a href='#' class='dropdown'>Rules</a>
<div class='rules'>
<ul>
<li>Rules Explanation Here</li>
<li>Second list item</li>
</ul>
</div>
</li>
</ul>
First of all, let's explain the difference between the concepts:
li
is a child of
the ul
. ul
is the parent.ul
has 2 children li
(in my example, not yours). And those children li
are siblings.So what happens with .dropdown
and .rules
? They are both children of the same li
element. Notice that the a.dropdown
is opened and closed before .rules
starts. So they are children of the same parent, and as in real life, that makes them siblings.
Upvotes: 2
Reputation: 361
You can try this.
ul#navbar {
list-style: none;
background-color: lightblue;
margin: 0;
padding: 0;
display: inline-block;
}
ul#navbar li {
position: relative;
float: left;
}
ul#navbar li a {
display: inline-block;
padding: 10px 20px;
text-decoration: none;
text-align: center;
color: #fff;
}
div.rules {
display: none;
min-width: 200px;
position: absolute;
left: 0;
top: 102%;
background: lightblue;
}
div.rules ul {
margin: 0;
padding: 0;
list-style: none;
}
div.rules li {
float: none;
}
div.rules ul li a {
padding: 10px;
text-align: center;
color: #fff;
}
.dropdown:hover > .rules {
display: block;
}
<ul id="navbar">
<li class='dropdown'><a href='#' >Rules</a>
<div class='rules'>
<ul>
<li><a href="#" >Rules Explanation Here</a></li>
</ul>
</div>
</li>
</ul>
Upvotes: 0
Reputation: 940
.parent{
padding: 20px;
background:tomato
}
.dropdown{
background: yellow
}
.rules{
padding: 15px;
background: green
}
.grandchildren{
background: blue
}
<ul id="navbar">
<li class="parent">
<a href='#' class='dropdown'>Dropdown - children 1</a>
<div class='rules'>
Rules - Children 2
<ul class="grandchildren">
<li>Rules Explanation Here</li>
</ul>
</div>
</li>
</ul>
It is a sibling combinator case where the logic takes place within the same parent element, both .dropdown
and .rules
are children of li
which makes them siblings
. General sibling combinator doesn't need to immediately succeed the first element but can appear anywhere after. For more info, check out >> https://css-tricks.com/child-and-sibling-selectors/
Upvotes: 0
Reputation: 60563
Its correct, because .rules
is child of the li
but not the a.dropdown
that you have as well as child of the li
, therefore 2 children make them siblings
.rules
as sibling.dropdown+.rules {
border: red solid/* only affect the first sibling */
}
.dropdown~.rules {
background: yellow/* afects all siblings */
}
<ul id="navbar">
<li><a href='#' class='dropdown'>Rules</a>
<div class='rules'>
<ul>
<li>Rules Explanation Here</li>
</ul>
</div>
<div class='rules'>
<ul>
<li>Rules Explanation Here</li>
</ul>
</div>
</li>
</ul>
.rules
as child.dropdown .rules {
border: red solid;
background: yellow
}
<ul id="navbar">
<li><a href='#' class='dropdown'>Rules
<div class='rules'>
<ul>
<li>Rules Explanation Here</li>
</ul>
</div>
</a>
</li>
</ul>
Upvotes: 1
Reputation: 4394
It is because your class .dropdown
is a clas of a tag and inside a tag you only have text "Rules". Element that has class .rules
is nested inside li element not a.
To achieve what you want, do this
<li class='dropdown'>
<a href='#'>Rules</a>
<div class='rules'>
<ul>
<li>Rules Explanation Here</li>
</ul>
</div>
</li>
With css that you wrote without ~ sign.
Upvotes: 0