如果一个块级元素中包含另一个块级元素,使用CSS将其改为内联元素是否有问题?

47

我知道在内联元素中放置块级元素是不对的,但以下内容怎么样呢?

想象一下这个有效的标记:

<div><p>This is a paragraph</p></div>
现在添加这个CSS:
div {
   display:inline;
}

这会导致内联元素包含块级元素(div 变成内联元素,默认情况下 p 是块级元素)。

页面元素还有效吗?

我们何时以及如何判断 HTML 是否有效 - 在应用 CSS 规则之前还是之后?

更新:我后来了解到,在 HTML5 中,将块级元素放入链接标记中是完全有效的,例如:

<a href="#">
      <h1>Heading</h1>
      <p>Paragraph.</p>
</a>

如果你想让一个大块的HTML作为链接,这实际上非常有用。


3
我很高兴HTML5能够将这个代码视为有效,但有效的代码并不是网络的全部。谷歌使用看起来像是错误标签混合的代码,但它却是可行的。 - JKirchartz
9个回答

31

来自CSS 2.1规范

When an inline box contains an in-flow block-level box, the inline box (and its inline ancestors within the same line box) are broken around the block-level box (and any block-level siblings that are consecutive or separated only by collapsible whitespace and/or out-of-flow elements), splitting the inline box into two boxes (even if either side is empty), one on each side of the block-level box(es). The line boxes before the break and after the break are enclosed in anonymous block boxes, and the block-level box becomes a sibling of those anonymous boxes. When such an inline box is affected by relative positioning, any resulting translation also affects the block-level box contained in the inline box.

This model would apply in the following example if the following rules:

p    { display: inline }
span { display: block }

were used with this HTML document:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HEAD>
  <TITLE>Anonymous text interrupted by a block</TITLE>
</HEAD>
  <BODY>
    <P>
      This is anonymous text before the SPAN.
      <SPAN>This is the content of SPAN.</SPAN>
      This is anonymous text after the SPAN.
    </P>
  </BODY>

The P element contains a chunk (C1) of anonymous text followed by a block-level element followed by another chunk (C2) of anonymous text. The resulting boxes would be a block box representing the BODY, containing an anonymous block box around C1, the SPAN block box, and another anonymous block box around C2.

The properties of anonymous boxes are inherited from the enclosing non-anonymous box (e.g., in the example just below the subsection heading "Anonymous block boxes", the one for DIV). Non-inherited properties have their initial value. For example, the font of the anonymous box is inherited from the DIV, but the margins will be 0.

Properties set on elements that cause anonymous block boxes to be generated still apply to the boxes and content of that element. For example, if a border had been set on the P element in the above example, the border would be drawn around C1 (open at the end of the line) and C2 (open at the start of the line).

Some user agents have implemented borders on inlines containing blocks in other ways, e.g., by wrapping such nested blocks inside "anonymous line boxes" and thus drawing inline borders around such boxes. As CSS1 and CSS2 did not define this behavior, CSS1-only and CSS2-only user agents may implement this alternative model and still claim conformance to this part of CSS 2.1. This does not apply to UAs developed after this specification was released.

你可以根据自己的理解来处理这个问题。显然,这种行为是在CSS中指定的,但它是否涵盖了所有情况,或者在今天的浏览器中是否实现一致,目前还不清楚。


仅供澄清,我认为这不是错误,而是CSS规范的一部分,你“可以”这样做。这需要浏览器额外的工作来创建匿名块。而且在各个Web浏览器之间也不一致。 - Chad
1
你好@Alohci。我遇到了一个类似于<div><a><span>Some text</span></a></div>的情况。这里所有元素都有它们正常的显示属性,但是我使用了带有一些文本内容的<span>::after 伪元素,并将该伪元素设置为块级元素。该元素是div的子元素,而div的子元素是aa的子元素是span。由于内联元素不支持宽度,所以在这里如何使宽度100%的块级元素起作用?我感觉自己像处于匿名盒子场景中,你能指点我正确的方向吗?谢谢。 - Marius Mucenicu
2
@George - 你经常会看到像“块级元素[在普通流中]占据其父元素宽度的100%”这样的语句。实际上并不正确。如果你查看 10.3.3 正常流中的块级非替换元素 这一部分,你会发现真正的含义是“块级元素[在正常流中]占据其包含块的宽度的100%”。像你的span这样的内联元素并不是块级容器。相反,最近的祖先块级容器元素(即你的div元素)用于确定100%的宽度。 - Alohci
@Alohci 的意见非常有道理。谢谢您! - Marius Mucenicu
1
@GeorgeMeijer - 严格来说,都不是,但这很微妙。针对上述引用文本的目的,body元素的内容被分成三个块级框,其中包含:1. span之前的P元素部分;2. span;3. span之后的P元素部分。1和3是匿名块级框。直接在P元素内部的文本(例如,“This is anonymous text before the SPAN.”)位于一个命名的内联框中(即命名为“P”),因此不需要任何匿名内联框。 - Alohci
显示剩余4条评论

15

无论是否有效,元素结构都是错误的。不将块级元素放在内联元素中的原因是浏览器可以轻松预测元素的呈现方式。

即使它对HTML或CSS都没有违反任何规则,它仍会创建无法按预期呈现的元素。浏览器必须像处理无效的HTML代码一样处理这些元素。


4
那么,当您需要使表格中整行可点击时,该怎么做呢? - mgPePe
2
@mgPePe:有几个选项。您可以在行中的每个单元格中放置链接,您可以使用JavaScript捕获行上的点击事件,或者您可以使用与表格不同的东西。 - Guffa
是的,JS是一个很好的解决方案。我最终采取的方法是根据这个示例在a上嵌套了span display="block"。http://www.jakpsatweb.cz/css/css-vertical-center-solution.html - mgPePe
4
我给你点了个踩,因为你只是断言某些事情是“错误的”,而规范却说明它是有效的。我无法从你的回答中判断浏览器何时会出现正确的行为。也许我漏掉了什么,但在阅读完你的回答后,我并不清楚“它创建的元素无法按照预期渲染”这个说法是否正确,甚至不知道这是什么意思。 - Mark Amery
@MarkAmery:规范没有说明它是有效的。 - Guffa

5
HTML和CSS都将保持有效。理想情况下,您不需要这样做,但是那个特定的CSS位实际上是一个方便的(语法上有效但不符合语义要求)方法,用于解决Internet Explorer的双倍边距错误,而无需使用条件样式表或会使CSS无效的技巧。 (X)HTML比CSS具有更多的语义价值,因此CSS是否语义上有效并不那么重要。在我看来,这是可以接受的,因为它解决了一个令人烦恼的浏览器问题,而不会使您的代码无效。

1
HTML 与 CSS 是独立验证的,因此页面仍然有效。我相当确定 CSS 规范也没有提到它,但是不要引用我说的话。然而,我使用这种技术时会非常小心,因为虽然它可能在一些浏览器中呈现为预期,但你需要测试所有浏览器——我没有看到有很多保证。

1
页面元素仍然有效吗?
在HTML方面,“有效”是肯定的;HTML对CSS一无所知。
但是,在浏览器中呈现的方式在CSS规范中是“未定义”的,因此它可能看起来像任何东西。虽然您可以在针对特定浏览器的CSS hack中包含这样的规则(其中您知道该浏览器如何呈现此情况),但不应向普通浏览器提供此规则。

1
请问您...如何使表格的整行可点击? - mgPePe
@mgPePe:您在每个单元格中都放置了一个链接,并将其设置为 display:block,以使其填满单元格的宽度。 - bobince
出现了两个问题:我可以使用 <a><span style="display:block"></span>[..more spans]</a> 吗?另外,如果我将 vertical-align: middle 应用于 span 块,这样做是否有效? - mgPePe
@mgPePe:是的!为了更清晰,可能也要在<a>上加上"display:block"吗? - bobince
是的,这也是问题,但我仍然有一个问题,即“vertical-align: middle”在span上不起作用。:\ 据我所知,只有表格可以实现它。 - mgPePe
根据被接受的答案,这个行为未定义的说法(这是这个答案的核心)是错误的,不是吗? - Mark Amery

0

-1

如果你有一种逻辑并最终像这样实现它,那么它并不是错误的。奇怪的东西并不是因为它们奇怪就是“错误”的。是的,这很不寻常,但它有帮助,而且不是错误。这是有意为之的。HTML和CSS应该为您服务,而不是相反,所以永远不要听取评论,告诉您不要这样做,只因为它很丑陋。

通常会将解决方案称为“无效”,并建议绕过长路。有时您可以重新考虑自己的做法。但是可能有许多原因导致您这样做,而他们并没有考虑到。

我经常在内联中使用块。它是有效的,并且正在工作-在大多数情况下并不是必需的。那又怎样。还记得XHTML告诉我们始终在属性周围加上引号(如果你不这样做,每个人都会对你大喊大叫!),现在HTML5允许在没有空格的情况下省略它们。最后一个斜杠发生了什么?"<br />"?来吧。标准改变了。但是浏览器仍然支持非标准的东西。CENTER已被弃用;我们在2013年,它仍然有效。TABLE用于垂直居中?有时这是唯一的方法。DIV内部A使其像您计划的那样悬停?继续吧。

专注于重要的事情。


-2

我认为,(x)html是有效的,css也是有效的。结果是否有效?如果在浏览器中呈现的效果符合您的要求,那么是有效的。


1
使用浏览器来验证代码的问题在于,您需要为要使页面正常工作的每个系统上的每个新版本的每个浏览器重新验证页面。 - Guffa
是的,那是一个真正的问题,我知道。 浏览器不是验证器 :) 而且我认为,关于HTML+CSS结果验证的问题是品味的问题。人为因素。 - Sergei Kovalenko

-3
不,这不是错误的选择。我们可以根据需求使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接