I wanted to create an anchor that would popup a div with anchor children when hovered. In order to achieve that, I created something like this:
.dropdown-content {
display: none;
}
.dropdown:hover .dropdown-content {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Dropdown</title>
</head>
<body>
<a class="dropdown" href="#">
<span>Community</span>
<div class="dropdown-content">
<a href="contact.html">Contact</a>
<a href="faq.html">FAQ</a>
</div>
</a>
</body>
</html>
However, it failed to work.
While trying to find a solution, I found this similar issue, where it was suggested to create a div wrapper around the root anchor, and use that as the target of :hover. However, I wanted to keep looking into it, in order to understand why the original code would not work. After some trial and error, I discovered that:
1. Using any type (at least from those I tried) other than anchor as children of .dropdown-content made the above code work as intended. However, as soon as an anchor child is inserted into .dropdown-content, it stops working again. So this works:
<div class="dropdown-content">
<p href="contact.html">Contact</p>
<p href="faq.html">FAQ</p>
</div>
While this does not:
<div class="dropdown-content">
<p href="contact.html">Contact</p>
<a href="faq.html">FAQ</a>
</div>
2. The .dropdown-content can be displayed properly with anchor children, if the descendant selector is replaced by an adjacent sibling combinator. That is, doing this:
.dropdown:hover + .dropdown-content {
display: block;
}
instead of this:
.dropdown:hover .dropdown-content {
display: block;
}
effectively solves the original issue.
Having tested this in various browsers (Chrome, Firefox, Edge, IE11), I can safely assume that this is not a browser-specific bug. However, this has led me to the following questions:
- It may be cross-browser compliant, but is it normal behavior? That is, is it stated or implied somewhere (e.g. W3C) that this is how anchors should work? I searched various sources, but I could not find an answer.
- If it is a normal behavior, why is .dropdown-content treated as a sibling when it contains an anchor element, whereas it is treated as a child without one.
- Is it possible to make .dropdown-content (or a div in general) have consistent behavior (i.e. treat nested elements as children), regardless of its parent and child elements?