寻找嵌套超链接:如何实现这种效果?

In search of nested hyperlinks: how to achieve this effect?

我们经常遇到 use-case 似乎被规范禁止。

众所周知,HTML 规范禁止嵌套的 hyperlink。与规范的大多数其他部分不同,这是一个硬性要求,因为浏览器将新 hyperlink 的开头视为旧 hyper

的结尾。

为什么要使用嵌套的 hyperlink? 如果像我一样,您希望 HTML 特别简洁,那么您经常会发现自己使用锚点作为 block-level 元素来定义较大的可点击区域。出于可用性原因,大的可点击区域是好的:我敢肯定我们都参加过那些令人尴尬的客户会议,客户试图毫无结果地点击看起来像按钮但不能点击的东西,因为你的锚点定义了 text-level 跨度,而不是周围的 button-looking parent 块。你知道,点击大的东西而不是小的东西只会让事情变得更容易。

在我们的大型可点击块中,设计师想要嵌套一些与 parent 块相关但未映射到它的较小修饰符 link 的情况并不少见。很好的例子是这样的 "Click here to go to or click here to go to (which thing is a child of"。或者更好:"Click here to go to or click here to a child of that ",例如评论部分或其他内部锚点。

示例 #1:link 的 Child ed object

这里我们有一个典型的例子来说明为什么嵌套锚是有用的。出于可用性原因,整个卡片都是可点击的,并将用户带到 linked 文章。它由单个 block-level 锚点元素组成,样式采用主题框架的水平布局 类。评论计数器符号(far-left 底部)必须将用户直接带到 linked 页面的#comments 部分。

这是一个标记示例:

<a class="row" href="article.html">
    <img src="" class="col-4">
    <div class="col-2">
         <div class="category">Top stop</div>
         <h1>Article title</h1>
         <time>Date</time>
         <div class="desc">Article lead</div>
         <a class="commentbml" href="article.html#comments">2</a>
    </div>
</a>

Eagle-eyed 观察者会注意到浏览器会这样解释上面的 HTML:

<a class="row" href="article.html">
    <img src="" class="col-4">
</a>
<div class="col-2">
    <div class="category">Top stop</div>
    <h1>Article title</h1>
    <time>Date</time>
     <div class="desc">Article lead</div>
    <a class="commentbml" href="article.html#comments">2</a>
 </div>

示例 #2:linked object

的类别

link 卡片媒体框由样式为 block-level 的单个外部元素组成。这通过使卡片的整个表面可点击来提高可用性。但是,NEWS link top-right 应该将用户带到该类别。除了提供快速导航帮助外,这与网站上文章类别主题的其他实例一致。

这是一个标记示例。

<a class="box" href="article.html">
    <a class="category" href="article-category.html">News</a>
    <img src="">
    <div class="caption">Article title</div>
</a>

同样,浏览器会这样解释上面的内容:

<a class="box" href="article.html"></a>
<a class="category" href="article-category.html">News</a>
<img src="">
<div class="caption">Article title</div>

所以。如果客户给了你这份简介,考虑到规范的缺陷,完成它的最佳方法是什么?

最简单的方法是模拟嵌套外观,单独使用 HTML 和 CSS(因为您表示不愿意使用 JavaScript);只需将包含的 <a> 元素包裹在外部容器中,例如 <div>,使用 CSS 将该容器定位到非静态 属性 值并定位'nested' 个元素使用绝对定位。

为此,我将元素插入到 'nest' 作为包含 <a> 元素的原始元素的相邻兄弟,给出:

<div class="item">
  <a href="http://whosebug.com">
Block-level link filling the enclosing &lt;div&gt; element, linking to Stack Overflow.
</a>
  <ul>
    <li><a href="http://whosebug.com/help" class="pseudoNested">Help center</a></li>
    <li><a href="http://whosebug.com/help/mcve" class="pseudoNested">MCVE</a></li>
    <li><a href="http://whosebug.com/company/about" class="pseudoNested">About SO</a></li>
  </ul>
</div>

以及以下内容(已删除基本的所有美学)CSS:

.item {
  /* a defined height to allow the child <a> element to
     fill the height of its parent, using 'height: 100%' */
  height: 10em;

  /* to allow descendants to be position in relation to this
     element, any value other than 'static' would suffice for
     this: */
  position: relative;
}

.item a {
  /* to horizontally fill its parent: */
  display: block;
  /* to vertically fill its parent: */
  height: 100%;
}

.item > a {
  padding-right: 10em;
}

.item ul {
  /* moving the element(s) out of the normal flow of
     of the document, and positioning according to
     its closest non-static ancestor: */
  position: absolute;

  /* adjust to taste: */
  top: 1em;
  right: 1em;
}

.item {
  height: 10em;
  position: relative;
}
.item a {
  display: block;
  height: 100%;
}
.item > a {
  padding-right: 10em;
}
.item ul {
  position: absolute;
  top: 1em;
  right: 1em;
}
<div class="item">
  <a href="http://whosebug.com">
Block-level link filling the enclosing &lt;div&gt; element, linking to Stack Overflow.
</a>
  <ul>
    <li><a href="http://whosebug.com/help" class="pseudoNested">Help center</a>
    </li>
    <li><a href="http://whosebug.com/help/mcve" class="pseudoNested">MCVE</a>
    </li>
    <li><a href="http://whosebug.com/company/about" class="pseudoNested">About SO</a>
    </li>
  </ul>
</div>

重新引入了一些基本的美学,这可以改进为以下内容,使事情更加明显:

.item {
  background: transparent url(http://i.stack.imgur.com/KqZksl.jpg) center center no-repeat;
  height: 10em;
  position: relative;
  padding: 1em;
  background-color: #fff;
}
.item a {
  display: block;
  height: 100%;
  color: #fff;
  font-weight: bold;
  text-decoration: none;
}
.item > a {
  padding-right: 10em;
}
.item ul {
  position: absolute;
  top: 1em;
  right: 1em;
  min-width: 5em;
  padding: 0;
  margin: 0;
  list-style-type: none;
}
.item ul li {
  background-color: rgba(0, 0, 0, 0.6);
  height: 1.5em;
  line-height: 1.5em;
  margin: 0 0 0.5em 0;
  border-radius: 0.5em;
  text-align: center;
  box-shadow: 0 0 0 0 transparent;
}
.item ul li:hover {
  background-color: rgba(0, 0, 0, 0.4);
  box-shadow: 0 0 0.5em 0 #fff;
}
.item a.pseudoNested {
  margin: 0.5em 0.25em;
}
<div class="item">
  <a href="http://whosebug.com">
Block-level link filling the enclosing &lt;div&gt; element, linking to Stack Overflow.
</a>
  <ul>
    <li><a href="http://whosebug.com/help" class="pseudoNested">Help center</a>
    </li>
    <li><a href="http://whosebug.com/help/mcve" class="pseudoNested">MCVE</a>
    </li>
    <li><a href="http://whosebug.com/company/about" class="pseudoNested">About SO</a>
    </li>
  </ul>
</div>

External JS Fiddle demo.