Результат разницы для заголовка в тегах p и div

Я пытался сделать абзац для адреса электронной почты. Но я не могу создать для него стиль.

.mail a {
    margin: .7rem 0;
    padding: .3em .8em;
    border: 1px solid #ddd;
    transition: all .2s;
    color: #aaa;
}

    .mail a:hover {
        background-color: #ddd;
    }


    .mail a:hover {
        color: #333;
    }
<p class="mail"><h3><a href="mailto:[email protected]">[email protected]</a></h3></p>
  <hr>
<div class="mail"><h3><a href="mailto:[email protected]">[email protected]</a></h3></div>

JSBin находится здесь.

Я никогда не понимал, что между p и div есть еще какая-то разница, кроме семантического значения или свойств, таких как margin или line-height.

Хорошо, я буду использовать тег div вместо p. Но вот вопросы в моей голове:

  1. Как вы называете эту разницу и почему она так работает?
  2. Есть ли другие примеры такого поведения? (Надеюсь, я не пропущу ничего подобного.)

person chenghuayang    schedule 03.08.2015    source источник
comment
Это не имеет ничего общего с тем, как работают теги div и p. Это связано с тем, что у вас есть заголовок (h3) внутри тега p. stackoverflow.com/ вопросы/15656785/   -  person Joel Almeida    schedule 03.08.2015
comment
Спасибо! Я этого не заметил. Не совсем знаком с общей практикой компоновки.   -  person chenghuayang    schedule 03.08.2015
comment
@JoelAlmeida Есть ли статья о практике формального макета? Хотелось бы узнать об этом побольше, чтобы не пропустить ничего важного.   -  person chenghuayang    schedule 03.08.2015
comment
@ChenghuaYang Я добавил в свой ответ немного больше информации о других элементах, которые можно закрыть самостоятельно. Надеюсь, это поможет.   -  person Hidden Hobbes    schedule 03.08.2015


Ответы (2)


Это происходит потому, что элемент h3 не может принадлежать элементу p. Конечный тег элемента p можно опустить, если за ним следуют определенные элементы:

Отсутствие тега

Начальный тег обязателен. Конечный тег можно опустить, если за элементом <p> сразу следуют <address>, <article>, <aside>, <blockquote>, <div>, <dl>, <fieldset>, <footer>, <form>, <h1>, <h2>, <h3>, <h4>, <h5>, <h6>, <header>, <hr>, <menu> , <nav>, <ol>, <pre>, <section>, <table>, <ul> или другой элемент <p>, или если в родительском элементе больше нет содержимого и родительский элемент не является элементом <a>.

(https://developer.mozilla.org/en/docs/Web/HTML/Element/p)

По сути, ваши теги p закрываются до того, как открываются теги h3, поэтому так:

<p class="mail"><h3><a href="mailto:[email protected]">[email protected]</a></h3></p>

На самом деле становится так:

<p class="mail"></p>
<h3><a href="mailto:[email protected]">[email protected]</a></h3>

В результате ваше правило .mail a больше не применяется к тегу a, из-за чего он не стилизован.

Чтобы это исправить, просто удалите теги p и добавьте класс mail к h3:

.mail a {
  margin: .7rem 0;
  padding: .3em .8em;
  border: 1px solid #ddd;
  transition: all .2s;
  color: #aaa;
}
.mail a:hover {
  background-color: #ddd;
}
.mail a:hover {
  color: #333;
}
<h3 class="mail"><a href="mailto:[email protected]">[email protected]</a></h3>
<hr>
<div class="mail">
  <h3><a href="mailto:[email protected]">[email protected]</a></h3>
</div>

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

</HTML>
</HEAD>
</BODY>
</P>
</DT>
</DD>
</LI>
</OPTION>
</THEAD>
</TH>
</TBODY>
</TR>
</TD>
</TFOOT>
</COLGROUP>

(HTML: включать или исключать необязательные закрывающие теги?)

Например, li автоматически закроется, если будет открыт новый li:

Отсутствие тега

Конечный тег можно опустить, если за элементом списка сразу следует другой элемент <li> или если в его родительском элементе больше нет содержимого.

(https://developer.mozilla.org/en/docs/Web/HTML/Element/li)

В то время как tds автоматически закрывается, если за ним следует th или td:

Отсутствие тега

Начальный тег обязателен. Конечный тег может быть опущен, если за ним непосредственно следует элемент <th> или <td> или если в его родительском элементе больше нет данных.

(https://developer.mozilla.org/en/docs/Web/HTML/Element/td)

Полезный список элементов и информацию о том, нужно ли их закрывать, можно найти на сайте W3C: http://www.w3.org/TR/REC-html40/index/elements.html

person Hidden Hobbes    schedule 03.08.2015

Это не имеет ничего общего с тем, как работают оба тега.

Это связано с тем, что у вас есть h3 внутри p. Почему?

Невозможно поместить элемент заголовка внутри элемента p в HTML-разметке не только формально, но и потому, что браузеры неявно завершают открытый элемент p при встрече с заголовком.

Источник

Рабочий образец с тегом p без h3:

.mail a {
    margin: .7rem 0;
    padding: .3em .8em;
    border: 1px solid #ddd;
    transition: all .2s;
    color: #aaa;
}

    .mail a:hover {
        background-color: #ddd;
    }


    .mail a:hover {
        color: #333;
    }
<p class="mail"><a href="mailto:[email protected]">[email protected]</a></p>
  <hr>
<div class="mail"><h3><a href="mailto:[email protected]">[email protected]</a></h3></div>

person Joel Almeida    schedule 03.08.2015