2

Code sample:

<a href="//google.com/"><button>Click me</button></a>

Why?

I want buttons. But I also want it so that it behaves like a link. This means when I middle-mouse-click it, it opens in a new tab. When I shift-click it, it opens in a new window. When I ctrl-click, it opens in a new tab. When I click with no modifiers, it opens in the current tab.

This is to be done without frameworks.

Styling a link to look like a button is not acceptable, because "looking like a button" is browser- and device-specific.

So what?

As far as I can test right now, it seems to work consistently well. What is the state of browser support for this behaviour, including mobile browsers? In what ways do non-supporting browsers mess it up, eg. by moving the button outside of the link in the DOM?

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592

3 Answers3

3

According to the HTML5 spec, a button tag cannot be nested inside an a tag. While browsers "may" render what you're trying to achieve, it's technically invalid HTML and has no guarantee to work in the future.

"'Looking like a button' is browser- and device-specific" is incorrect. Looking like a button is completely dependent on CSS assuming you aren't using the browser default styled buttons. If you want valid HTML and the effect you're describing, you need to simply use CSS to style an a tag to look like a button.

EDIT:

You may find some use of the appearance CSS property, which forces native UI rendering of certain elements, but it's not widespread or standard, and each browser's implementation will vary, and can completely break or change between versions. In other words, I wouldn't recommend it, but it's the closest thing to what you're asking for without using custom CSS.

michael
  • 748
  • 4
  • 10
  • Well, I *am* using the browser default styled buttons. There's a thing I like to call "native UI" and there's a very good article by none other than Jeff Atwood about how [non-native UI sucks](http://blog.codinghorror.com/non-native-ui-sucks/). So unfortunately, simply using CSS is not going to work here. – Niet the Dark Absol Feb 04 '16 at 04:55
  • Then HTML will not work for you. I understand it's not the answer you want, but it is the correct answer. If you're unwilling to use CSS, you cannot get the behavior you're describing. – michael Feb 04 '16 at 04:56
  • You can use the `appearance` CSS property, but please read my edit for more information. – michael Feb 04 '16 at 05:01
  • Thank you. Unfortunately it would seem that `appearance` is even less supported than the "button in a link hack"... – Niet the Dark Absol Feb 04 '16 at 05:06
  • Technically, the button in a link hack has no support whatsoever, it's just pure coincidence that some browsers render it "correctly" and by correctly I mean how you're wanting it to be rendered. But ultimately I understand what you mean. Unfortunately, you'll need to use CSS to accomplish what you're trying to do. I'd also urge against even using CSS; however, as styling a link as a button isn't necessarily good for usability in terms of semantics. Users have specific expectations for a link and a button, and mixing the two together isn't necessarily a good idea. – michael Feb 04 '16 at 05:09
  • The best advice I can offer as someone who does UX design for a living, don't style links as buttons, style links as links. Secondly, CSS is not evil or bad, and in all honesty, I would never use browser defaults unless you care absolutely nothing about your design or the user experience. CSS is there for a reason, and it can accomplish what you're trying to do perfectly, efficiently, and elegantly. – michael Feb 04 '16 at 05:11
  • To elaborate a little, my personal preference is for the native controls to be used, but the site's skinning feature allows the user to have their skin-defined colours apply to otherwise native elements to fit their chosen style if preferred. Also, these buttons are along the lines of "Edit", basically things that would probably be ideal for `class="btn"` in Bootstrap... if I were using it... Anyway, I'll play around with some options. – Niet the Dark Absol Feb 04 '16 at 05:22
  • Yeah, ultimately using a framework like Bootstrap will be the easiest option, but you can still easily create your own CSS if you don't want to use a framework. You can style a super simple button with just a couple lines of CSS, and best of all, it's cross browser, so you won't have 15 different renderings of your button, it'll look the same, but perhaps this is a disadvantage to you since you want native rendering on each platform. – michael Feb 04 '16 at 05:26
  • Just a side-thought on that `appearance` attribute: is it any different from the CSS `display` property, other than being defined at the document/element level? – Anthony Feb 04 '16 at 05:29
2

The problem is that you want something that is both a "true button" (in the sense that the browser renders it visually like a button, it triggers like a button, etc) but that also has "true anchor" qualities (eg it can be right-clicked to open in a new tab, can be styled, etc.) But buttons and anchors are not (obviously) the same thing. They are similar, but both exist as separate ideas because they aren't the same.

Maybe one could imagine an attribute like "type=link" that might achieve what you imagine, but that doesn't currently exist in the HTML spec.

Furthermore, in terms of why this wouldn't be something that "just worked", some reasons might be:

  1. A button doesn't inherently have a target, in the sense of directing the browser to a new location/URL. A button might have this affect, but a button is generally intended to do things like trigger a script or submit a form. Neither of these things implicitly instruct the browser to go to a new location.

    Imagine the button was intended to trigger a javascript function and inside that function, there is a line that redirects the browser using location. The button did not redirect the browser, the javascript function did this. The browser didn't know ahead of time that this would happen.

    Now imagine that the button instead triggers a function that changes the background color of the page from red to blue. No change to the browser's location/URL.

    If there was some way to have the button to behave like an anchor, and the user used ctrl+click to click the button, what would the new browser window do in this new window/tab exactly? Open the same exact content as before but with a blue background? Or open a blank window with no content but just having a blue background?

  2. If you nested a button inside of a link as you describe:

    <a href="//google.com/"><button>Click me</button></a>

    You are actually telling the browser to do two actions. One of them being "follow this link" and the other being "execute this button click". Just like nesting anchor elements has unexpected and unsupported results, so would nesting buttons and anchors. How would the browser know which element the user "really meant" or which parts to use from each?

  3. If you want a way to have a UI control that informs the browser to open a new location, allowing the browser to have options like right-click and copying that location, bookmarking that location, or opening that location in a new tab, this already exists. It's called an anchor and looks like <a>. If you want something that looks like a button but feels like an anchor, this would mean an anchor styled to look like a button. Style should be done via CSS, not via elements that look more like what you want. I'm sure Jeff was advocating the value of letting elements have their native style (like not trying to over style a link or a paragraph or an input and allowing the element to just follow the look-and-feel the browser/user-based-style-options uses by default), not so much suggesting that inappropriate elements be used in order to piggy-back off the built-in style for that other element instead of using the correct one.

  4. Finally, this kinda-sorta came up in a related SO answer about not styling divs to look like buttons that I saw just yesterday. Something in the HTML spec that might work as an intended middle-ground like you're wanting could be the menu element, but it is so far not implemented in any mainstream browsers in the correct (following the spec) way. But that's probably because there are no outspoken advocates for the use-cases it could have. So maybe this could be one of them and you could rally for this element to get adopted rather than passed over yet again.

Community
  • 1
  • 1
Anthony
  • 36,459
  • 25
  • 97
  • 163
  • Thank you for your `` (bad joke is bad). The last point actually nudged me in a new possible direction. Namely, I have menus elsewhere on the site, perhaps I shouldn't be using buttons at all and instead use the same kind of menu as I am elsewhere? That's good for consistency, and I use `` in those menus for items that navigate the user. – Niet the Dark Absol Feb 04 '16 at 05:42
  • If you mean semantically/abstractly you should be thinking of these parts of the page/document as "menus" instead of as "links", that is very possibly a good direction to go to help you keep things tidy and semantic. If you mean "should i be using `` elements instead of buttons?" unfortunately that would require browsers to actual implement the `` element first ( http://caniuse.com/#feat=menu ) , which none of them really do. Firefox sorta does, but not following the spec. But if you have some concept of "menus" already on your site, sounds like a good fit. – Anthony Feb 04 '16 at 05:53
0

If you are using bootstrap then it's view is amazing..like this

<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div>
    <a href="//google.com/" class="btn btn-success">Click me</a>
</div>

or you can do like this,

<div>
    <a href="//google.com/"><button>Click me</button></a>
</div>
dekts
  • 744
  • 4
  • 19