35

This is a problem resulting from trying to keep my html semantics as correct as possible.

I have a parent button that does both a function in the same page, and acts as parent tag for a big container that nests an anchor -- which redirects to another page -- and a div tag that also acts as a parent for another button that is suppose to perform some actions.

<button>
  <div id="the-most-big-container"
    <a href="http://www.RedirectMeToAnotherPage.com"></a>
   <div>
     <button> do some action </button>
   </div>
  </div>
</button>

I tried nesting the button, gave it a class and id and none of the properties that I apply to the class and the id get performed on the child button, more Also the child button gets completely out of the big container and lays itself in the DOM just like it is a complete independent tag not nested by any other tag.

[Update]

Apparently this is prohibited to nest a button inside another, but furthermore I would like an explanation to why the nested button's behavior being not responsive to the css styles, and how exactly it is laying itself regarding the DOM now, is it now a complete independent tag by itself or what ?

Also now I will be forced to change the parent button tag into any other tag so that I can nest child buttons inside. I would like a suggestion for a substitute tag for the parent button tag ex: I could change the parent button into a div tag,

but I need a tag that would be more descriptive semantically (something other than just a div),I had that parent button in the first place to act as a toggle button so that when I click it it displays and hides the most-big-container-div.

AndrewMk
  • 623
  • 2
  • 6
  • 16

3 Answers3

31

It is not valid to put a <button> inside a <button> element.
In the W3C recomendation for the button element you can read:

Content model:
Phrasing content, but there must be no interactive content descendant.

[source: w3.org (emphasis mine)]

Interactive content includes:

  • a
  • audio (if the controls attribute is present)
  • button
  • embed
  • iframe
  • img (if the usemap attribute is present)
  • input (if the type attribute is not in the hidden state)
  • keygen
  • label
  • object (if the usemap attribute is present)
  • select
  • textarea
  • video (if the controls attribute is present)
Kobi
  • 135,331
  • 41
  • 252
  • 292
web-tiki
  • 99,765
  • 32
  • 217
  • 249
  • In addition to that, the w3c validator throws this error: `Error: Element div not allowed as child of element button in this context. (Suppressing further errors from this subtree.)` – roberrrt-s Sep 08 '16 at 09:00
  • The context being that a button is "display:inline-block". Change the button to display:block and it would be "valid". Should you do it, no, better not to do it. – Patrick Aleman Sep 08 '16 at 09:06
  • 2
    @PatrickAleman the fact it is valid or not doesn't depend on the `display` property but on the fact that the ` – web-tiki Sep 08 '16 at 09:07
  • @web-tiki I understand that, thats why i set "valid" in double quotes. – Patrick Aleman Sep 08 '16 at 09:13
  • 1
    I believe it is `W3C`, not `WC3`. – naveedk Sep 30 '18 at 19:50
1

With CSS, we can style it to look like a button inside a button:

.buttons-wrapper {
  position: relative;
}

.seemingly-outer-button {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  height: 40px;
  width: 100%;
  background: black;
  color: lightblue;
}

.seemingly-inner-button {
  position: absolute;
  top: 8px;
  bottom: 8px;
  height: 24px;
  left: 20px;
  color: lightcyan;
  background: brown;
}
<div>
  <h4>Try clicking these buttons:</h4>
  <div class="buttons-wrapper">
    <button class="seemingly-outer-button" id="outer" onclick="alert('outer')">
          The Seemingly Outer Button
        </button>
    <button class="seemingly-inner-button" id="inner" onclick="alert('inner')">
          The Inner Button
        </button>
  </div>
</div>

React example on StackBlitz.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Aakash
  • 21,375
  • 7
  • 100
  • 81
-8

You can not do this. A button is not meant to contain other elements. However, you can style a div element to have the look and the feel of a button, here is what it looks like with bootstrap:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
    <div class="btn btn-default">
        outer button
        <br />

        <button class="btn btn-primary">
            inner button
        </button>
    </div>
</body>
</html>
Bender
  • 1
  • 2
  • 10
    A button isn't meant to contain other elements?That's resoundingly wrong. Are you saying that button elements aren't allowed to have SVG's and spans? Even right under your code example... the 'Run code snippet' button has elements. – jscul Jul 09 '18 at 02:18