Почему тег <p> не может содержать тег <div> внутри?

169

Насколько я знаю, это правильно

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

Но это неправильно

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

Первый может пройти валидатор W3C (XHTML 1.0), а второй - нет. Я знаю, что никто не напишет код, подобный второму. Я просто хочу знать почему.

А как насчет отношения сдерживания других тегов?

Генри Мяо
источник
9
Поскольку <p>это элемент уровня блока, и (предполагается, что) он используется для отображения текста, он не позволит использовать внутри него другие элементы уровня блока, а только встроенные, такие как <span>и <strong>.
Bojangles
22
JamWaffles: То pесть элемент уровня блока не имеет к этому никакого отношения. divтакже один и позволяет другие блоки.
Джои
возможный дубликат: stackoverflow.com/questions/4967976/… (без пометки): любой достойный ответ на этот вопрос ответит, как читать спецификацию HTML и, таким образом, также ответит на это.
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
Объявление стиля div как встроенного также не работает.
Трийнко

Ответы:

198

Авторитетным местом для поиска разрешенных отношений содержания является спецификация HTML. См., Например, http://www.w3.org/TR/html4/sgml/dtd.html . Он определяет, какие элементы являются блочными, а какие встроенными. Для этих списков найдите раздел с пометкой «Модели содержимого HTML».

Для элемента P это указывает следующее, что указывает, что элементам P разрешено содержать только встроенные элементы.

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

Это согласуется с http://www.w3.org/TR/html401/struct/text.html#h-9.3.1 , в котором говорится, что элемент P «не может содержать элементы уровня блока (включая сам P)».

Колин Кэмпбелл
источник
74
У меня есть привычка избегать спецификаций, самых авторитетных документов, которые у нас есть для подобных вещей, потому что их не интересно читать. +1 за то, что на самом деле их читал, понимал и использовал, чтобы отвечать на вопросы.
Stoutie
3
Это все еще верно для HTML 5? Связанная спецификация конкретно ссылается на HTML 4, а HTML 5 не имеет определения типа документа .
Ajedi32
2
@ Ajedi32 Да, здесь . HTML5 переименовал много терминов, но «Разрешенный контент: фразировка контента» означает то же, что и %inlineбит выше. Смотрите также ответ Ориола.
Мистер Листер
@ Stoutie Прямо с тобой, вот почему переполнение стека существует.
Капитан Гипертекст
69

Короче говоря, невозможно поместить <div>элемент внутри a <p>в DOM, потому что открывающий <div>тег автоматически закроет <p>элемент.

defau1t
источник
2
Ах, это объясняет, почему перед div находится огромное пространство внутри p, потому что p фактически заканчивается непосредственно перед div.
AaronLS
2
Вы можете поместить divэлемент внутри a p в DOM , например myP.appendChild(myDiv). Но анализатор HTML не сделает этого.
Oriol
1
Не делай этого. Вы понятия не имеете, как это отреагирует в будущих браузерах. Технология постоянно меняется. Там может быть динамический анализатор HTML, который сделает этот недействительным однажды. Цель веб-разработчика - создавать вещи, которые могут быть как желаемыми, так и несколько совместимыми. Если вы можете обойти то, что позволяет браузер, можно с уверенностью сказать, что вы не сможете гарантировать, что он будет работать вечно. Просто используйте span span. Если вам нужен div, прекратите использовать тег p.
39

В соответствии с HTML5, то модель содержимого из divэлементов содержимого потока

Большинство элементов, которые используются в основной части документов и приложений, относятся к категории потока содержимого.

Это включает pэлементы, которые могут использоваться только там, где ожидается поток содержимого .

Следовательно, divэлементы могут содержать pэлементы.


Тем не менее, модель содержимого из pэлементов содержимого Фразировка

Содержание фразы - это текст документа, а также элементы, которые размечают этот текст на уровне внутри параграфа. Запускается из формулируя контент формы абзацев .

Это не включает divэлементы, которые могут использоваться только там, где ожидается поток содержимого .

Следовательно, pэлементы не могут содержать divэлементы.

Поскольку конечный тег из pэлементов может быть опущен , когда pэлемент непосредственно следует divэлемент (среди прочих), следующих

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

анализируется как

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

и последнее </p>является ошибкой.

Ориоль
источник
Но если в CSS, если я установил div, чтобы быть встроенным, почему это не соблюдает это?
Санджай
Так как значения CSS применяются после синтаксического анализа dom ... даже если мы используем div as inline in CSSего, это бесполезно, так как новая разобранная структура <p>Text</p> <div>some words</div> <p></p> является ли мое понимание правильным?
Санджай
@ Санджай Да, похоже, ты прав. И более того, во время моих наблюдений, если вы поместите <span> внутрь <p>, а затем установите отображение span в «block», он будет отображаться как типичный блочный элемент без такого эффекта.
Андрей Наумович
-1

После X HTML условные обозначения были изменены, и теперь это смесь условных обозначений XML и HTML, поэтому второй подход неверен, и валидатор W3C принимает правильные вещи в соответствии со стандартами и соглашениями.

geekdev786
источник
XHTML не сильно изменился. Элементу p никогда не разрешалось содержать элемент div.
Квентин
-7

Потому что divтег имеет более высокий приоритет, чем pтег. pТег представляет собой тег абзаца , тогда как divтег представляет документ тег.

Вы можете написать много абзацев в теге документа, но вы не можете написать документ в абзаце. Так же, как файл DOC.

Гаурав Агравал
источник
2
На самом деле, это разделение. Иначе это было бы <doc>: D
Кайл
6
Приоритет - это не концепция, которая применяется к элементам html, а div представляет собой деление, как говорит @KyleSevenoaks :)
SimplGy
Что такое файл DOC? Microsoft Word файл?
Питер Мортенсен