217

I am doing the following:

 <a href="www.stackoverflow.com">
   <button disabled="disabled" >ABC</button>
 </a>  

This works good but I get a HTML5 validation error that says "Element 'button' must not be nested within element 'a button'.

Can anyone give me advice on what I should do?

Andrew Moore
  • 93,497
  • 30
  • 163
  • 175
Marie
  • 2,283
  • 2
  • 14
  • 5
  • 9
    The validator already answered your question for you, and even told you why it's not valid in that error message. – Useless Code Jun 18 '11 at 04:43
  • 1
    But is there an alternative if I want Google to be able to see that as a link. As an example of button usage I have buttons called "<<" and ">>" for next record and previous record. I believe these should be buttons but the functionality is that they link to new pages. – Marie Jun 18 '11 at 04:52
  • 5
    my question is DOES it matter..if you make this one well Deserved exception. – Muhammad Umer Jul 17 '14 at 02:11
  • 1
    If i put it doesnt work on Internet Explorer 11 or Firefox. – dutraveller Aug 26 '14 at 09:52
  • actually, if you want to have a button that links to an html page just create a button and have it call a js function that redirects to where you want to go – DCR Mar 18 '22 at 22:52

11 Answers11

325

No, it isn't valid HTML5 according to the HTML5 Spec Document from W3C:

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

The a element may be wrapped around entire paragraphs, lists, tables, and so forth, even entire sections, so long as there is no interactive content within (e.g. buttons or other links).

In other words, you can nest any elements inside an <a> except the following:

  • <a>

  • <audio> (if the controls attribute is present)

  • <button>

  • <details>

  • <embed>

  • <iframe>

  • <img> (if the usemap attribute is present)

  • <input> (if the type attribute is not in the hidden state)

  • <keygen>

  • <label>

  • <menu> (if the type attribute is in the toolbar state)

  • <object> (if the usemap attribute is present)

  • <select>

  • <textarea>

  • <video> (if the controls attribute is present)


If you are trying to have a button that links to somewhere, wrap that button inside a <form> tag as such:

<form style="display: inline" action="http://example.com/" method="get">
  <button>Visit Website</button>
</form>

However, if your <button> tag is styled using CSS and doesn't look like the system's widget... Do yourself a favor, create a new class for your <a> tag and style it the same way.

Community
  • 1
  • 1
Andrew Moore
  • 93,497
  • 30
  • 163
  • 175
46

If you're using Bootstrap 3, this works quite well

<a href="#" class="btn btn-primary btn-lg active" role="button">Primary link</a>
<a href="#" class="btn btn-default btn-lg active" role="button">Link</a>
Siyual
  • 16,415
  • 8
  • 44
  • 58
user2197018
  • 593
  • 4
  • 2
17

I've just jumped into the same issue and I solved it substituting 'button' tag to 'span' tag. In my case I'm using bootstrap. This is how it looks like:

<a href="#register"> 
    <span class="btn btn-default btn-lg">
        Subscribe
    </span>
</a> 
gobeltri
  • 329
  • 3
  • 10
14

No.

The following solution relies on JavaScript.

<button type="button" onclick="location.href='http://www.stackoverflow.com'">ABC</button>

If the button is to be placed inside an existing <form> with method="post", then ensure the button has the attribute type="button" otherwise the button will submit the POST operation. In this way you can have a <form> that contains a mixture of GET and POST operation buttons.

Peter Wilson
  • 377
  • 3
  • 5
8

It would be really weird if that was valid, and I would expect it to be invalid. What should it mean to have one clickable element inside of another clickable element? Which is it -- a button, or a link?

Steve Jorgensen
  • 11,725
  • 1
  • 33
  • 43
  • Thanks Steve. This was a method suggested to me by a team-worker. The method does work. Is there some better way I could do this? – Marie Jun 18 '11 at 04:34
  • 1
    @Marie If you want to make a link look like a button it is easy to use CSS styles to make it look as such. Add a border style similar to this: `border: 2px outset`. If you want to round the corners a bit you could use a [border-radius](http://www.css3.info/preview/rounded-border/) on it as well. A simple `` tag would work well too. – Useless Code Jun 18 '11 at 04:50
6

These days even if the spec doesn't allow it, it "seems" to still work to embed the button within a <a href...><button ...></a> tag, FWIW...

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
3

Another option is to use the onclick attribute of the button:

<button disabled="disabled" onClick="location.href='www.stackoverflow.com'" >ABC</button>

This works, however, the user won't see the link displayed on hover as they would if it were inside the element.

LaserCat
  • 150
  • 1
  • 17
0

You can add a class to the button and put some script redirecting it.

I do it this way:

<button class='buttonClass'>button name</button>

<script>
$(".buttonClass').click(function(){
window.location.href = "http://stackoverflow.com";
});
</script>
divHelper11
  • 2,090
  • 3
  • 22
  • 37
0

why not..you can also embeded picture on button as well

<FORM method = "POST" action = "https://stackoverflow.com"> 
    <button type="submit" name="Submit">
        <img src="img/Att_hack.png" alt="Text">
    </button>
</FORM> 
  • 3
    The problem is that as the OP asked back then is a bit restrictive in what it allows to be within its boundaries. See the accepted question there. – Thomas Dec 16 '15 at 13:43
-1

Explanation and working solution here: Howto: div with onclick inside another div with onclick javascript

by executing this script in your inner click handler:

 if (!e) var e = window.event;
 e.cancelBubble = true;
 if (e.stopPropagation) e.stopPropagation();
Ruwen
  • 3,008
  • 1
  • 19
  • 16
-7

Use formaction attribute inside the button

PS! It only works if your button type="submit"

<button type="submit" formaction="www.youraddress.com">Submit</button>
Moonfly
  • 11
  • 4