Por que a tag <p> não pode conter uma tag <div>?

169

Tanto quanto eu sei, isso está certo:

<div>
  <p>some words</p>
</div>

Mas isso está errado:

<p>
  <div>some words</div>
</p>

O primeiro pode passar no validador W3C (XHTML 1.0), mas o segundo não. Eu sei que ninguém escreverá código como o segundo. Eu só quero saber o porquê.

E o relacionamento de contenção de outras tags?

Henry H Miao
fonte
9
Como <p>é um elemento no nível do bloco e é (supostamente) usado para exibir texto, ele não permitirá outros elementos no nível do bloco, mas apenas elementos inline como <span>e <strong>.
Bojangles
22
JamWaffles: Esse pé um elemento no nível do bloco não tem nada a ver com isso. divtambém é um e permite outros blocos.
Joey
possível duplicação de: stackoverflow.com/questions/4967976/… (sem bandeira): qualquer resposta decente que responderá como ler a especificação HTML e, portanto, também responderá a isso.
Ciro Santilli escreveu
Declarar o estilo da div como embutido também não funciona.
Triynko

Respostas:

198

Um local autorizado para procurar relações de contenção permitidas é a especificação HTML. Veja, por exemplo, http://www.w3.org/TR/html4/sgml/dtd.html . Ele especifica quais elementos são elementos de bloco e quais estão em linha. Para essas listas, procure a seção marcada "modelos de conteúdo HTML".

Para o elemento P, ele especifica o seguinte, que indica que os elementos P só podem conter elementos embutidos.

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

Isso é consistente com http://www.w3.org/TR/html401/struct/text.html#h-9.3.1 , que diz que o elemento P "não pode conter elementos em nível de bloco (incluindo o próprio P)".

Colin Campbell
fonte
74
Eu tenho o hábito de evitar as especificações, os documentos mais autorizados que temos para coisas assim, porque eles não são divertidos de ler. +1 para realmente lê-los, entendê-los e usá-los para responder a perguntas.
Stoutie
3
Isso ainda é válido para o HTML 5? A especificação vinculada faz referência especificamente ao HTML 4 e o HTML 5 não possui uma definição de tipo de documento .
Ajedi32
2
@ Ajedi32 Sim, aqui . O HTML5 renomeou várias terminologias, mas "Conteúdo permitido: conteúdo de frases" significa o mesmo que o %inlinebit acima. Veja também a resposta de Oriol.
Lister
@Stoutie Bem com você, é por isso que o Stack Overflow existe.
Captain Hypertext
69

Em resumo, é impossível colocar um <div>elemento dentro de um <p>no DOM porque a <div>tag de abertura fechará o <p>elemento automaticamente .

defau1t
fonte
2
Ah, isso explica por que existe um espaço enorme antes de uma div dentro de um ap, porque ep realmente termina logo antes da div.
AaronLS
2
Você pode colocar um divelemento dentro de um p no DOM , por exemplo myP.appendChild(myDiv). Mas um analisador de HTML não fará isso.
Oriol
1
Não faça isso. Você não tem idéia de como isso responderá em navegadores futuros. A tecnologia está mudando constantemente. Pode haver um analisador de html dinâmico que o tornará inválido um dia. O objetivo no web dev é criar coisas que possam ser desejáveis ​​e compatíveis. Se você pode ignorar o que o navegador permite, é seguro dizer que você não pode garantir que ele funcione para sempre. Basta usar um span pessoal ... Se você precisar de uma div, pare de usar a tag p.
39

De acordo com o HTML5, o modelo de conteúdo dos divelementos é o conteúdo do fluxo

A maioria dos elementos usados ​​no corpo dos documentos e aplicativos é categorizada como conteúdo de fluxo.

Isso inclui pelementos, que podem ser usados ​​apenas onde o conteúdo do fluxo é esperado.

Portanto, divelementos podem conter pelementos.


No entanto, o modelo de conteúdo dos pelementos é o conteúdo de frases

O conteúdo do fraseado é o texto do documento, bem como os elementos que marcam esse texto no nível intra-parágrafo. Executa de fraseado de conteúdo do formulário parágrafos .

Isso não inclui divelementos, que podem ser usados ​​apenas onde o conteúdo do fluxo é esperado.

Portanto, os pelementos não podem conter divelementos.

Como a tag final dos pelementos pode ser omitida quando o pelemento é imediatamente seguido por um divelemento (entre outros), o seguinte

<p>
  <div>some words</div>
</p>

é analisado como

<p></p>
<div>some words</div>
</p>

e o último </p>é um erro.

Oriol
fonte
Mas se em CSS, se eu definir div para estar em linha, por que não está respeitando isso?
Sanjay
Como os valores CSS são aplicados após a análise de dom ... mesmo que façamos div as inline in CSSseu uso, como nova estrutura analisada, <p>Text</p> <div>some words</div> <p></p> meu entendimento está correto?
Sanjay
@Sanjay Sim, parece que você está certo. Além disso, durante minhas observações, se você colocar <span> dentro de <p> e definir a exibição do span como "block", ele será renderizado como um elemento de bloco típico sem esse efeito.
Andrii Naumovych
-1

Após o X HTML, as convenções foram alteradas e agora são uma mistura de convenções de XML e HTML; é por isso que a segunda abordagem está errada e o validador W3C aceita as coisas corretas, de acordo com os padrões e convenções.

geekdev786
fonte
XHTML não mudou muito. O elemento p nunca teve permissão para conter um elemento div.
Quentin
-7

Porque a divtag tem precedência mais alta que a ptag. A pmarca representa uma marca de parágrafo, enquanto a divmarca representa uma marca de documento.

Você pode escrever muitos parágrafos em uma tag de documento, mas não pode escrever um documento em um parágrafo. O mesmo que um arquivo DOC.

Gaurav Agrawal
fonte
2
Na verdade, é divisão. Caso contrário, seria <doc>: D
Kyle
6
Precedência não é um conceito que se aplica a elementos HTML, e div representa uma divisão, como @KyleSevenoaks diz :)
SimplGy
O que é um arquivo DOC? Um arquivo do Microsoft Word ?
Peter Mortensen