Can I nest a <button> element inside an <a> using HTML5?
Asked Answered
V

12

230

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?

Victualler answered 18/6, 2011 at 4:18 Comment(5)
The validator already answered your question for you, and even told you why it's not valid in that error message.Hematuria
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.Victualler
my question is DOES it matter..if you make this one well Deserved exception.Kelby
If i put <button><a href="dsada.html">Test</a></button> it doesnt work on Internet Explorer 11 or Firefox.Work
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 goScoggins
H
339

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.

Hartzel answered 18/6, 2011 at 4:26 Comment(14)
@Andrew Moore - Is there another way. I believe this gave problems and that was why it was changed to be inside of an <a> link. Not sure what the problem was but we have many of these buttons like this on a page. Maybe it was because we wanted to improve SEO by using <a> links.Victualler
@Marie: There is no other way other than styling your links to look like buttons.Hartzel
@Marie: No. That's why you are better off using a link, and styling the link to look like a button. Why do you want the system widget look anyway?Hartzel
Styling a link to look like a button and making it look good in all browsers is I believe impossible. I tried for a long time. Nothing came close to the real buttons and I had many variations of CSS.Victualler
@Andrew Moore, @Useless code - Just to clarify. Do you think Google will notice the link if it is a button within a form?Victualler
@Marie: Will follow, MAYBE. Will rank, NO.Hartzel
it's better to use method="post" to get rid of question mark - "?"Copolymerize
user25 not is is not better to use method="post" because the browser asks for resending a post form when navigating back and forth. As GET is the default method of a form one can leave method="get" out for brevity.Bronez
Why is there a <div> in the list of elements which you can't nest inside an <a>? <div> isn't interactive and I'm pretty sure that it is valid in HTML5 to nest a <div> inside an <a> tag?Reimport
How about opening link in a new tab? can you bind target attribute to form element?Sotos
@AndrewMoore: styling a link to look like a button creates its own set of problems, such as for accessibility. A button should execute when it has focus and you hit spacebar. A link does not. If you care about ADA (or are required to pretend to care) then this may bite you.Maccabean
As @jonaspas suggested, a <div> inside an <a> is absolutely valid in HTML5: validator.w3.org/nu/…Froufrou
If using a form to act like a button, please don't forget that you won't have the "follow through" features like right click + copy URL or open in new tab.Mcbride
I am trying to understand why is it a rule to not have nested interactive elements? Are there any usability issues?Barron
S
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>
Sweetie answered 17/12, 2014 at 20:43 Comment(2)
doesn't work well with a round button font awesome icon insideRuysdael
Using class='btn btn-default' matched the other buttons (MVC6).Photofluorography
A
18

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> 
Aquilegia answered 6/10, 2014 at 13:59 Comment(3)
You don't need the span at all with bootstrap. Just move the whole class part to the <a> and you will have a link button. eg <a href="#register" class="btn btn-default btn-lg">Subscribe</a>Intrude
The original poster asked if it's possible to place a button inside an anchor tag. The accepted answer notes that it goes against W3C specs to place an <a> inside an <a>. I think that's why golbeltri was demonstrating styling a <span> as a button.Aurelia
This makes sense if there is other content inside the <a>, which is part of the link, but not styled like a button. For example, any click within a div (image, background, text, etc) goes to a link, but only the span looks like a button.Foodstuff
D
13

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.

Deduce answered 23/2, 2015 at 1:51 Comment(5)
onclick will not work on file protocol, so it is'nt useful for static presentation, in example. in this case form action propety is the way to go.Freddyfredek
If the button is linked to a page, then it's not a button, it's an anchorEscapee
@Escapee it's so common to see these days. Just look at the landing page for every web development framework in existence. I'm all for the purist argument usually, but even I'm having to admit that a big rectangular button has better, more obvious affordance than a link, even if it links to a page instead of initiating a true form action.Trauma
Right now I have an <a> inside the <button> (with the same href) as a backup if JS is disabled, and six months from now I'm definitely going to be embarrassed that I admitted that.Trauma
@TheDudeAbides I'm not talking about the aspect of it, I'm taking about the markup you want to use. What prevents you from styling this link as a big rectangular button? Unless your site doesn't use any styles at all? btw the answer above the one we're commenting about is a perfect example of it. It's an anchor tag, styled as a button.Escapee
M
9

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

Markitamarkka answered 21/10, 2017 at 21:44 Comment(2)
This works when the <button> is not contained within a <form>. However, as soon as the button is contained (eg, <form>...<a><button>) this stops working, unless one disables the button's on-click handler. This is enough gyrations to warrant avoiding this scenario.Galle
@Galle it works fine in a form, just specify the type: <button type="button">Codeine
I
7

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?

Initiate answered 18/6, 2011 at 4:27 Comment(2)
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?Victualler
@Victualler 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 on it as well. A simple <img> tag would work well too.Hematuria
O
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.

Orna answered 11/11, 2014 at 14:30 Comment(0)
F
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>
Faraday answered 5/12, 2015 at 20:20 Comment(0)
B
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> 
Bb answered 16/12, 2015 at 12:2 Comment(1)
The problem is that <a></a> as the OP asked back then is a bit restrictive in what it allows to be within its boundaries. See the accepted question there.Faris
L
-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();
Lotuseater answered 10/7, 2017 at 8:47 Comment(0)
L
-1

my answer is link this

a[role=button] {
  align-items: center;
  background-color: #0A66C2;
  border: 0;
  border-radius: 100px;
  box-sizing: border-box;
  color: #ffffff;
  cursor: pointer;
  padding:15px;
  margin:10px;
}
<a role="button">
    GO BACK
</a>
Louvre answered 23/12, 2023 at 19:32 Comment(0)
S
-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>
Skantze answered 16/9, 2013 at 16:27 Comment(1)
you also need to put the button in a <form> tag.Vtol

© 2022 - 2024 — McMap. All rights reserved.