p3nchan
p3nchan

Reputation: 1534

Difference result for a heading within p and div tag

I was trying to make a paragraph for an email address. But I cannot make style for it.

.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 is here.

I've never realised there's some more difference between p and div other than semantic meaning or properties like margin or line-height.

Okay, I'll use div instead of p tag. But here are the questions in my mind:

  1. What do you call this difference, and why does it work like this?
  2. Are there any other examples of this behaviour? (I hope I wouldn't miss anything else like this.)

Upvotes: 2

Views: 80

Answers (2)

Hidden Hobbes
Hidden Hobbes

Reputation: 14173

This is occurring because the h3 element cannot belong inside a p element. The end tag of a p element can be omitted if it is followed by certain elements:

Tag omission

The start tag is mandatory. The end tag may be omitted if the <p> element is immediately followed by an <address>, <article>, <aside>, <blockquote>, <div>, <dl>, <fieldset>, <footer>, <form>, <h1>, <h2>, <h3>, <h4>, <h5>, <h6>, <header>, <hr>, <menu>, <nav>, <ol>, <pre>, <section>, <table>, <ul> or another <p> element, or if there is no more content in the parent element and the parent element is not an <a> element.

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

Effectively, your p tags are closing before the h3 tags are opened so this:

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

Actually becomes this:

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

As a result your .mail a rule no longer applies to the a tag which causes it to be un-styled.

To fix, simply remove the p tags and add the mail class to the 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>

There are other tags where the end tag is optional (shown below), however, the rules as to when they are automatically closed differ:

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

(HTML: Include, or exclude, optional closing tags?)

For example, li will autoclose if a new li is opened:

Tag omission

The end tag can be omitted if the list item is immediately followed by another <li> element, or if there is no more content in its parent element.

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

While tds will close automatically if followed by a th or td:

Tag omission

The start tag is mandatory. The end tag may be omitted, if it is immediately followed by a <th> or <td> element or if there are no more data in its parent element.

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

A useful list of the elements and whether they need to be closed can be found on the W3C site: http://www.w3.org/TR/REC-html40/index/elements.html

Upvotes: 3

Joel Almeida
Joel Almeida

Reputation: 8037

This has nothing to do with the way both tags work.

It has to do with the fact you have an h3 inside the p. Why?

It is impossible to put a heading element inside a p element in HTML markup, not just formally but because browsers implicitly terminate an open p element when they encounter a heading.

Source

Working sample with p tag without 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>

Upvotes: 2

Related Questions