Cornelis
Cornelis

Reputation: 1839

p tag in button tag not allowed?

I have a <button> element and within it, a <p> element. The <p> element is used in combination with css, margin-top, in a class to vertical align the text within the button (the button has a specific height).

The html looks like this:

<button class="someClass">
    <img ... />
    <p class="anotherClass">Caption</p>
</button>

This works fine, the text is vertically aligned like it should be. However I get a warning inside visual studio 2012 saying:

Element 'p' cannot be nested inside element 'button'.


My questions: why isn't the <p> element allowed inside a <button> element? And what is the alternative?

Upvotes: 12

Views: 25959

Answers (4)

Dave BZ
Dave BZ

Reputation: 11

Since the p and some other tags cannot be used within the button tag, the best workaround, as others have stated, is to use a styled span tag.

You treat the button tag "as if" it was a container div of your span tags within. That way, you can style your whole button however you want. In my example, I styled it with a simulated icon, title, description, and button within the button.

I'm adding a little extra styling and formatting for visual purposes, but yours can be as simple or complex as you want.

/* CSS Styling and classes example */


/* style the main container */

button {
  background-color: transparent;
  outline: none;
  border: none;
  cursor: pointer;
  transition: 0.2s;
  padding: 10px 15px;
}


/* what happens when you hover - optional */

button:hover {
  background-color: #efefef;
}


/* what happens when it's active - optional */

button.active {
  background-color: #ccc;
}


/* global style for the contained span tags within */

button span {
  display: block;
  margin: 5px auto 10px;
}


/* individually styling the inner span tags by class identifiers */

button span.step {
  background: #c33;
  color: #fff;
  padding: 10px 2px 0 0;
  font-size: 1.75em;
  font-weight: 600;
  width: 40px;
  height: 40px;
  border-radius: 20px;
}

button span.title {
  font-size: 2em;
  font-weight: 600;
}

button span.desc {
  font-size: 1.05em;
}

button span.btn {
  margin: 20px auto;
  padding: 5px 10px;
  background: #c33;
  color: #fff;
}
<!-- html code -->
<button class="customClass">
        <span class="step">1</span>
        <span class="title">Title</span>
        <span class="desc">My cool button description</span>
        <span class="btn">Click Here</span>
    </button>

Of course, you can modify, add and remove span elements as you see fit, including images.

Upvotes: 0

Oriol
Oriol

Reputation: 288080

That is correct, it isn't allowed, because;

An alternative is getting rid of the p element, and instead using a span element with display: block:

.anotherClass {
  display: block;
}
<button class="someClass">
  <img ... />
  <span class="anotherClass">Caption</span>
</button>

Upvotes: 27

Jukka K. Korpela
Jukka K. Korpela

Reputation: 201558

Visual Studio is correct in this issue: no HTML specification allows p in button, not even the rather liberal definition in HTML5 CR.

However, browsers do not actually enforce this restriction (in the sense that they enforce e.g. the restriction that span cannot contain p: they implicitly close an open span element when they see a <p> tag). So your code “works”, though there is really no guarantee that it will keep working (or that it works on all browsers).

To make the code formally valid, replace the p element by a span element and style it. You might also put a <br /> tag before it, to ensure a line break even when CSS is disabled. To set a top margin on it, make it a block or an inline block. Example:

.anotherClass {
  display: block;
  margin-top: 1em;
}
<button class="someClass">
    <img src="http://lorempixel.com/100/50" alt="Some text" /><br />
    <span class="anotherClass">Caption</span>
</button>

Upvotes: 2

Jeffpowrs
Jeffpowrs

Reputation: 4540

Generally you're not supposed to put block elements inside of inline elements.

Upvotes: 3

Related Questions