【问题标题】:Is putting a div inside an anchor ever correct?将 div 放入锚内是否正确?
【发布时间】:2010-12-22 03:03:49
【问题描述】:

我听说将块元素放在内联元素中是一种 HTML 罪:

<a href="http://example.com">
    <div>
        What we have here is a problem. 
        You see, an anchor element is an inline element,
        and the div element is a block level element.
    </div>
</a>

但是,如果您在样式表中将外部锚定为display:block 会怎样?还是错了吗? block-level and inline elements 上的 HTML 4.01 规范似乎是这样认为的:

样式表提供了一种方法 指定任意渲染 元素,包括是否一个元素 呈现为块或内联。在 某些情况,例如内联样式 对于列表元素,这可能是 合适,但一般来说, 不鼓励作者 超越常规 HTML 元素的解释 这边。

有人对此问题有任何进一步的提示吗?

【问题讨论】:

  • @DisgruntledGoat - 感谢您的链接 - 希望我能早点看到 :-)
  • 锚点和\或链接元素是浏览器自动化控件。因此它具有浏览器预定义的呈现和行为。包装一个真正的纯 html 元素:然而 span 内的 div 是一种罪过。 A 标签不添加任何级别行为的原因是在不干扰文档流的情况下标记部分文本的要求,而不是因为它们应该是内联元素。从那个观点来看,A 是一个无所事事的标签。它的存在超出了问题的范围,也不是罪过,但可能会导致代码丑陋和/或模棱两可。
  • 以后检查这里的其他人,请注意,虽然在 HTML5 中锚标签可以包含块级元素,但它们不能包含包含其他锚标签的块级元素!因为基本上,锚标签里面不能有其他锚标签。你可以在这里阅读更多内容:stackoverflow.com/questions/13052598/…

标签: html


【解决方案1】:

取决于您要满足的 HTML 版本:

  • HTML 5 声明 &lt;a&gt; 元素“可以围绕整个段落、列表、表格等,甚至整个部分,只要没有交互内的内容(例如按钮或其他链接)”。

  • HTML 4.01 指定&lt;a&gt; 元素只能包含inline elements&lt;div&gt;block element,因此它可能不会出现在 &lt;a&gt; 中。

    当然,您可以随意设置内联元素的样式,使其看起来 是一个块,或者确实设置一个块的样式,使其内联呈现。在 HTML 中使用术语 inlineblock 是指元素与文档语义结构的关系,而 CSS 中的相同术语更多地与元素的视觉样式相关。如果你让内联元素以块状方式显示,那很好。

    但是,您应该确保文档的结构在 CSS 不存在时仍然有意义,例如通过屏幕阅读器等辅助技术访问时 - 或者在强大的 Googlebot 检查时。

【讨论】:

【解决方案2】:

不,它不会验证,但是它通常可以在现代浏览器中工作。话虽如此,在您的锚点内使用一个跨度,并在其上设置display: block,这肯定会在任何地方都有效,并且会验证!

【讨论】:

  • 如果你设置display: block,从技术上讲,它不就变成了一个块元素吗?
  • @hugo 这在技术上重要吗?
  • 嗯,HTML 4.01 规定 a 元素只能包含内联元素。如果您将 span 元素设为块元素,从技术上讲,它不应该位于锚点内。
  • @Hugo:HTML4 中的限制似乎是语义上的,而不是表现形式的。从语义上讲,&lt;div&gt; 是块级的,&lt;span&gt; 是内联的,即使文档随附的 CSS 另有规定。
  • 添加了 style="display:block;"在跨度标签中,它就像一个魅力。刚刚玩了填充以获得我想要的结果
【解决方案3】:

W3C 文档没有使用 wrongsin 之类的概念,但确实使用了诸如 provide the means 之类的概念可能是合适的不鼓励

其实在section 4的第二段中,4.01的规范将其字词逐条列举如下

在本文档将按照 [RFC2119] 中的描述进行解释。但是,为了便于阅读,这些词在本规范中并未全部以大写字母出现。

考虑到这一点,我相信最终的声明是在 7.5.3 块级和内联元素中,它说

通常,内联元素可能只包含数据和其他内联元素。

条件“一般”似乎引入了足够多的歧义,表明 HTML 4.01 确实允许内联元素包含块元素。

当然,CSS2 有一个显示属性值inline-block,似乎适合您描述的目的。我不确定它是否曾得到广泛支持,但似乎有人预料到需要这种行为。

这里的 DTD 似乎不太宽容,但 text of the DTD 遵循规范:

HTML 4.01 规范包括额外的 无法在其中表达的句法约束 DTD。

在另一条评论中,您建议您希望通过将块包装在锚中来使其处于活动状态。我不相信 HTML 禁止这样做,而 CSS 显然允许这样做。因此,要回答关于它是否正确的标题问题,我说是的。按照标准,它有时是正确的。

【讨论】:

  • 在你提到 doctype 之前,你有我。
  • 你可能是对的 - 我应该使用 doctype.com。 Opps - 下次我会尽量记住。 PHP -> SO, HTML -> doctype.com
  • 我对这个问题没有强烈的论坛偏好。不过,我对 Robert Harvey 对 doctype 的看法很感兴趣。
  • 我的看法是没有“在 doctype.com 上投票结束”选项(也不应该有)。
  • 我同意 Rob - Stack Overflow 用于编程。 HTML/CSS 在我看来当然是编程。
【解决方案4】:

使用 HTML5 规范...现在可以将块级元素放入内联元素中。所以现在将 'div' 或 'h1' 放在 'a' 元素内是非常合适的。

【讨论】:

  • 仅在 flow(默认 = block)元素或 transparent 元素(如 a i>) 与允许 flow 元素的父级。例如,p 不允许 flow 元素(如 div),而只允许 phrasing 元素(默认 = inline),所以 p 中的 a 不能包含 div。但是,div 中的 a 可以包含 ps、divs 或任何其他 flow 元素。
【解决方案5】:

&lt;div&gt; 这样的块级元素可以用HTML5 中的&lt;a&gt; 标签包装。尽管根据MDN&lt;div&gt; 被认为是container/wrapper for flow content,而&lt;a&gt; 被认为是flow content。从语义上讲,创建充当块级元素的内联元素可能会更好。

【讨论】:

  • 由于a元素是透明的,只有当a的父元素允许flow i>(默认为 block)元素。
【解决方案6】:

您不能将 &lt;div&gt; 放入 &lt;a&gt; - 它是无效的 (X)HTML。

即使您使用 display: block 设置 span 的样式,您仍然不能在其中放置块级元素:(X)HTML 仍然必须遵守 (X)HTML DTD(无论您使用哪个),无论如何CSS 如何改变事物。

浏览器可能会按照您的意愿显示它,但这并不正确。

【讨论】:

    【解决方案7】:

    http://www.w3.org/TR/REC-html40/sgml/dtd.html 有一个 HTML 4 的 DTD。此 DTD 是规范的机器可处理形式,其限制是 DTD 管理 XML 和 HTML 4,尤其是“瞬态”风格,允许许多不是“合法”XML 的东西。不过,我认为它接近于编纂说明符的意图。

    <!ELEMENT A - - (%inline;)* -(A)       -- anchor -->
    
    <!ENTITY % inline "#PCDATA | %fontstyle; | %phrase; | %special; | %formctrl;">
    
    <!ENTITY % fontstyle "TT | I | B | BIG | SMALL">
    
    <!ENTITY % phrase "EM | STRONG | DFN | CODE | SAMP | KBD | VAR | CITE | ABBR | ACRONYM" >
    
    <!ENTITY % special "A | IMG | OBJECT | BR | SCRIPT | MAP | Q | SUB | SUP | SPAN | BDO">
    
    <!ENTITY % formctrl "INPUT | SELECT | TEXTAREA | LABEL | BUTTON">
    

    我会将此层次结构中列出的标签解释为允许的标签总数。

    虽然规范可能会说“内联元素”,但我很确定这并不是您可以通过将块元素的 显示类型 声明为内联来绕过意图。内联标签无论你如何滥用它们都有不同的语义。

    另一方面,我觉得有趣的是,包含 special 似乎允许嵌套 A 元素。规范中可能有一些强烈的措辞不允许这样做,即使它在 XML 语法上是正确的,但我不会进一步探讨这一点,因为这不是问题的主题。

    【讨论】:

    • 你知道- - 是什么意思吗?我试图找到一个解释,但我找不到。
    【解决方案8】:

    如果你想避免将 div 放置在锚标签中的语义问题,只需将锚标签放在与 div 相同的级别,用一个容器将它们全部包裹起来,位置:相对,使你的锚标签位置:绝对和展开它以填满容器。此外,如果它不在内容流的末尾,请确保在其中放置一个 z-index 以将其置于内容之上。

    按照建议,我添加了一个标记代码:

    <div class="div__container>
      <div class="div__one>
      </div>
      <div class="div__two">
      </div>
      <a href="#"></a>
    </div>
    

    还有css:

    .div__container {
      position: relative; 
    }
    .div__container a {
      position: absolute;
      top: 0;
      bottom: 0;      
      left: 0;
      right: 0;
      z-index: 999;
    }
    

    【讨论】:

    • 虽然你的答案可能是正确的,但如果你用标记说明它会有所帮助。
    • 以上代码有效。我在这个小提琴中测试了它:jsfiddle.net/h1uvo6nk
    【解决方案9】:

    如果你要努力制作&lt;a&gt; 块,为什么不把&lt;a&gt; 放在div 中,作为块元素它会给你同样的效果。

    【讨论】:

    • 因为我可能希望锚点包含多个 div。
    【解决方案10】:

    如果您将其更改为块样式元素,那么不,它不再“错误”,但它可能不会验证。但是做你正在做的事情并没有多大意义。您应该将锚标记保留为没有内部 div 的块级元素,或者将 div 放在外部。

    【讨论】:

      【解决方案11】:

      2021 年 11 月更新:最新 HTML5 版本

      这是我从他们的网站上拿的一个例子:

      <a href="/components/badge">
        <div class="mat-list-item-content">
          <div mat-ripple="" class="mat-ripple mat-list-item-ripple"></div>
          <div class="mat-list-text"></div>
        </div>
      </a>
      

      【讨论】:

        【解决方案12】:

        我认为大多数时候人们问这个问题时,他们已经建立了一个只有 div 的网站,现在其中一个 div 需要是一个链接。

        我看到有人在锚标记中使用透明的空图像 PNG,只是为了在 div 中创建链接,并且图像与 div 大小相同。

        其实挺难过的……但确实有效……

        【讨论】:

          【解决方案13】:

          你可以通过添加“::before”伪元素来实现这一点

          纯 CSS 技巧 ;)

          a:before{
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            z-index: 1;
            pointer-events: auto;
            content: "";
            background-color: rgba(0,0,0,0);
          }
          <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"/>
          <div class="card" style="width: 18rem;">
            <img src="https://via.placeholder.com/250" class="card-img-top" alt="...">
            <div class="card-body">
              <h5 class="card-title">Card with stretched link</h5>
              <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
              <a href="#" class="btn btn-primary stretched-link">Go somewhere</a>
            </div>
          </div>

          【讨论】:

            【解决方案14】:

            这是错误的。使用span

            【讨论】:

            • rofl 这与使用 div 是一样的。我想我已经在 blip.tv 上看到了这一点(使用 div),但是正如其他人根据规范 block=block 如果 div 或 span 或任何相同的东西提到它的错误!
            【解决方案15】:

            仅供参考。

            如果您的目标是让您的 div 可点击,您可以使用 jQuery / Java Script。

            像这样定义你的 div:

            <div class="clickableDiv" style="cursor:pointer">
              This is my div. Try clicking it!
            </div>
            

            你的 jQuery 会像这样实现:

             <script type="text/javascript">
            
                $(document).ready(function () {
            
                    $("div.clickableDiv").click(function () {
                        alert("Peekaboo"); 
                    });
                });
            </script>
            

            这也适用于多个 div - 根据 Tom 在此线程中的评论

            【讨论】:

            • 这太可怕了,它不能与键盘一起使用,悬停时看不到链接。它几乎像链接一样工作,但不是真正的链接。您也不能中键单击它,也不能右键单击它作为链接。
            • 它当然有它的用途。您可以在 div 内放置一个锚点,并将 div-click 重定向到子锚点的位置。通过将 div 上的光标设置为指针,您因此具有锚点的外观和感觉,加上一个有效的后备解决方案,如果不允许使用 javascript 或出于可访问性原因,则只有 div 内的锚点。您可以获得语义和语法正确的 html,并且您不必摆弄显示样式的可疑更改。
            • 如果您有一个包含链接的 div,您可以让点击处理程序捕获该事件,找到锚点(确保只有一个)然后使用它。可通过普通锚标签访问。例如,这将允许有一桶带有图像和标题的数字以及“阅读更多”链接。想法?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-30
            • 1970-01-01
            • 2015-08-20
            • 1970-01-01
            • 2021-04-26
            • 2021-08-20
            相关资源
            最近更新 更多