首页 > 解决方案 > 嵌套在 Anchor 中的 Div 被视为兄弟姐妹

问题描述

我想创建一个锚,当悬停时会弹出一个带有锚子的 div。为了实现这一点,我创建了这样的东西:

.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>

但是,它失败了。

在尝试寻找解决方案时,我发现类似的问题,建议在根锚周围创建一个 div 包装器,并将其用作 :hover 的目标。但是,我想继续研究它,以了解为什么原始代码不起作用。经过反复试验,我发现:

1.使用除锚以外的任何类型(至少我尝试过的类型)作为 .dropdown-content 的子项,使上述代码按预期工作。但是,一旦将锚子插入到 .dropdown-content 中,它就会再次停止工作。所以这有效:

<div class="dropdown-content">
  <p href="contact.html">Contact</p>
  <p href="faq.html">FAQ</p>
</div>

虽然这不会:

<div class="dropdown-content">
  <p href="contact.html">Contact</p>
  <a href="faq.html">FAQ</a>
</div>

2.如果后代选择器相邻的兄弟组合器替换,则 .dropdown-content 可以与锚子正确显示。也就是说,这样做:

.dropdown:hover + .dropdown-content {
  display: block;
}

而不是这个:

.dropdown:hover .dropdown-content {
  display: block;
}

有效解决了原来的问题。

在各种浏览器(Chrome、Firefox、Edge、IE11)中对此进行了测试后,我可以放心地假设这不是特定于浏览器的错误。然而,这让我想到了以下问题:

  1. 它可能是跨浏览器兼容的,但这是正常行为吗?也就是说,它是否在某处(例如W3C)声明或暗示这是锚应该如何工作的?我搜索了各种来源,但找不到答案。
  2. 如果这是正常行为,为什么 .dropdown-content 包含锚元素时被视为兄弟,而没有锚元素则被视为子元素。
  3. 是否可以使 .dropdown-content (或一般的 div )具有一致的行为(即将嵌套元素视为子元素),而不管其父元素和子元素如何?

标签: htmlcss

解决方案


也就是说,它是否在某处(例如 W3C)声明或暗示了锚应该如何工作?

请参阅显示“内容模型:透明,但不得有交互式内容或元素后代”的 a 元素。

你不能把一个锚放在另一个锚里面。

如果这是正常行为,为什么 .dropdown-content 包含锚元素时被视为兄弟,而没有锚元素则被视为子元素。

浏览器重新排列 DOM 以尝试使其有效。您可以使用浏览器中的开发人员工具查看生成的结构。

是否可以使 .dropdown-content (或一般的 div )具有一致的行为(即将嵌套元素视为子元素),而不管其父元素和子元素如何?

确实……问题是你试图让另一个a人成为后代的尝试一开始a就失败了。


推荐阅读