为什么嵌套的锚标签是非法的?

时间:2013-09-06 21:34:22

标签: html tags dtd

我了解到嵌套锚标签不符合标准HTML。

从W3开始:

  

A元素定义的链接和锚点不能嵌套; A元素不得包含任何其他A元素。

     

由于DTD将LINK元素定义为空,因此LINK元素也不能嵌套。

看起来像this question中选定答案中建议的那些替代品会比仅仅嵌套锚点更有可能产生意外行为!

使用onclick事件处理程序只是为了重定向JS中的页面似乎有点过分。更不用说使用脚本解决方案会导致用户在禁用脚本时浏览时出现问题。

修改

有趣的是,我正在研究fiddle进行演示而我忽略了Chrome实际上正在重构DOM:

<div id="container">

    <a href="http://yahoo.com"></a>
    <div class="parent">
        <a href="http://yahoo.com">Parent Element</a>
        <a href="http://google.com">
            <div class="child">Child Element</div>
        </a>
        <a href="http://bing.com">
            <div class="child">Other Child</div>
        </a>
    </div>

</div>

我忽略了这一点,因为我看到悬停工作并且我的鼠标放在文本上。现在知道这一点并不一定会改变我的问题,但它确实证明它甚至不像我想的那样工作。

4 个答案:

答案 0 :(得分:35)

请记住,锚不仅仅是一个链接,它也是一个可以链接的东西。 (虽然以前的使用比后者更常见。)引用W3C(陈旧但相关):

  

锚是一段文本,用于标记超文本链接的开头和/或结尾。

为此,请不要将锚视为链接。将其视为文档中连接到(和/或来自)另一个点的点(在同一文档或其他文档中,它没有区别)。某些非物理空间中的两个点由非物理线程连接。

鉴于此,锚点不应包含大量内容。如果它包含很多内容,它就不再成为一个“点”并开始成为一个“区域”。例如,想象一个锚点,当渲染时占用的空间比浏览器一次显示的空间大。如果有东西链接到那个锚,它应该去哪里?一开始?中间?结束? (直觉上你可能会想到开头,但你明白了。)

此外,锚点绝对不应包含其他锚点。非物理点之间的非物理连接可能变得模糊不清。子锚点是否连接到另一个点,或者父锚点是否连接到另一个点?在大多数情况下,这个可能并不会导致大问题,因为今天浩大的大多数锚点都是从锚点到另一个文档的单向链接。但锚的目的不仅仅是与另一个文档的单向链接,因此该定义继续体现这一目的。

答案 1 :(得分:7)

spec for <a>的内容模型为:

  

透明,但必须没有interactive content后代。

因此规范实际上比你说的复杂。这也适用于<button> - 基本上你不能在按钮内的链接或按钮内部有工作链接。

不幸的是,我对你的问题没有强烈的答案为什么 - 我只能推测。一个明显的原因是它引起的模糊性(例如,当单击内部时应该遵循哪个锚点?)

这不仅会产生功能歧义,还会产生语义模糊。 <a>的内容是其超链接的标签。那么这是否意味着内部超链接是外部链接内容标签的一部分?

答案 2 :(得分:1)

标准不建议使用锚嵌套(尽管我测试的所有浏览器似乎都会导致最里面的点击目标),因为模糊不清。

说一个重要部分应该导致某个页面是不合逻辑的,在这部分中,一个小部分应该引导到其他地方。我仍然需要看到这种行为的任何用例。随着可用脚本语言的发展,这种迭代或遗产可以起作用(例如,在div上的javascript点击事件),但代码永远不会想要指向某个URL然后指向另一个(父锚点'href)。 / p>

编辑:看看你在你的引用中提出的问题,堆叠2个指向完全相同的href的锚点是完全没用的。只需删除嵌套的一个,一切都会好的。如果是因为你做了像a a{color:red;}这样的CSS规则,请使用跨度!或者甚至是一个带有display:inline的div但是,请相信,锚点应该去某个地方,不应仅仅用于造型目的或其他东西。

答案 3 :(得分:0)

社区中的其他好人给出了很好的答案, 我想贡献 ,并举一个例子来说明如何 模拟嵌套锚标签 ,而无需将它们实际嵌套在 markup 中,而是通过使标签看起来像是在另一个人的区域内一样

.parent{
  position: relative;
  width: 300px;
  height: 150px;
  border: 1px solid salmon;
}

.parent .main-link{
  display: block;
  margin-bottom: 2em;
}

/* 
  expands the clickable area of the main link 
  to fill the parent container, because it's the nearest
  ancestor with "position:relative"
*/
.parent .main-link::before{
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

.parent a:hover{
  color: green;
}

/* bring other links "forward" to make them clickable */
.parent .secondary-link{
  position: relative;
  z-index: 1;
}
<div class='parent'>
  <a href='#111' class='main-link'>main link, full area</a>
  <a href='#222'class='secondary-link'>secondary link</a>
</div>