<div>嵌套在<p>中

时间:2017-06-29 21:37:51

标签: html tags

在学习网络开发时,我遇到了问题。 那是我的代码:

<div class="row">
  <div ng-mouseover="infoModalOpen = !infoModalOpen" ng-mouseleave="infoModalOpen = !infoModalOpen" class="trigger">|</div>
  <div ng-show="infoModalOpen">Tooltip content here</div>
</div>

由于某些原因,浏览器会将<!DOCTYPE html> <html> <head> <style type="text/css"> p { background: blue; } .primary { color: red; } </style> </head> <body> <p> text1 <div class="primary"> text </div> text2 </p> </body> </html> 转换为<p><p>text</p>。因此,而不是</p>嵌套在<div>(我在源代码中真正写过的内容!),我得到了这个:

<p>

正如我想的那样,因为... <body> <p> text1 </p> <div class="primary"> text </div> text2 <p></p> </body> ... 既可以是emty元素(如<p>)也可以是空元素(如<br>)。你能解释一下这个问题并给出解决方案吗?谢谢。

2 个答案:

答案 0 :(得分:3)

<div>标记与<p>类似,是一个块级元素,这意味着它被设计为包含它自己的块,并在其周围添加换行符。尝试将<div>嵌套在<p>内并不可能做到你想要的,因为它没有多大意义。 <p>是一个段落,它不应包含块级元素。这个问题可能是相关的:

https://stackoverflow.com/questions/4291467/nesting-block-level-elements-inside-the-p-tag-right-or-wrong

请尝试使用<span>,因为<span>是一个内联元素,旨在显示在段落中。如果您确实需要多个块级元素,请考虑根本不使用<p>,或者将它们用作最内层块元素而不是外部元素。

答案 1 :(得分:1)

开始时有Standard Generalized Markup Language (SGML)。 SGML定义了语法的某些方面,例如标点符号和标签,但是每个用户应用程序都定义了语法的某些部分,例如标签名称,属性,嵌套。

几十年后,SGML简化为创建XML标准。今天,XML用于许多特定于应用程序的数据格式的方式与过去使用SGML的方式类似。 SGML和XML本质上是元语言-它们是许多特定于应用程序的语言的语法模板。

HTML最初被设计为SGML的应用程序,因此了解HTML的历史需要了解SGML的一些规则。 SGML旨在在文本编辑器中进行编辑,因此它包括许多功能,这些功能减少了代码,使人类的书写和阅读更加方便。仅举几个例子:

  • 诸如<br>之类的某些元素是自终止的,因此永远不会有相应的</br>结束标记。
  • 诸如<tbody>之类的某些元素被隐式插入,例如<table><tr><td></td></tr></table>成为<table><tbody><tr><td></td></tr></tbody></table>
  • 诸如<p>之类的某些元素不能彼此嵌套,因此从一个元素开始将终止旧的元素:<p><p>变成<p></p><p></p>

这些元素/标签级语法功能通过SGML声明和document type definition (DTD)启用/禁用。直到4.01版的HTML肯定都有DTD,这被认为是解析器应如何解释标记代码的真相。 DTD还可以告诉我们类似的信息(不是详尽的清单):

  • 允许每个元素具有什么属性。
  • 属性是可选属性,必需属性还是默认值。
  • PCDATA和CDATA之间的区别,这会影响字符的转义方式。
  • 确切地允许哪些元素嵌套在什么内容中。

DTD是我们可以找到答案的地方,至少从历史上讲,HTML 4.01 Strict

<!ELEMENT P - O (%inline;)*            -- paragraph -->

<!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">

上面的代码说<p>元素只能包含%inline内容,该内容进一步定义为#PCDATA%fontstyle%phrase%special%formctrl。后4个的定义是31个元素的集合,例如<tt><strong><img><textarea>等。请注意,这些所谓的内联元素不包括像<div><ul>之类的块元素-换而言之,<p>不能包含<div>

我不知道SGML解析器在每种情况下的行为细节,但是看起来当一个元素不允许包含另一个元素时,第一个元素终止,然后第二个元素开始。这解释了为什么<p><div></div></p>成为<p></p><div></div><p></p>的原因。

快进到HTML5,它不再基于SGML。尽管HTML5是一种定制的,唯一的语法标准,但它旨在与HTML 4向后兼容。HTML5复制正确的HTML 4代码的语义,并另外规定一种统一的方法来解析错误的标记代码( “标记汤”),以便所有浏览器的行为都相同。因此,<p><div></div></p>的解释从SGML时代开始就没有变化。

特别是对于<p>,此规则在here中得到了非常清晰的解释:

如果p元素后紧跟地址,文章,旁白,blockquote,details,div,...

,则可以省略p元素的结束标签。

此外,<p>只允许包含"phrasing content"(请注意缺少<div>):

短语内容是文档的文本,以及在段落内级别标记该文本的元素。段落内容的表述形式。 a,abbr,区域(如果它是地图元素的后代),音频,b,bdi,bdo,br,按钮,画布,引用,代码,数据,数据列表,del,dfn,em,嵌入,i,[ ...],自定义元素,文本