Grow your CSS skills. Land your dream job.

When To Use The Button Element

Published by Chris Coyier

You use it when, uhm, you want a button on your page that users can click, right? Well, unfortunately it's a bit more complicated than that. It's not too bad though, let's figure it out.

It looks like this:

<button>
  Do Something
</button>

What's the most common result of clicking something on a website? Moving to a new URL, like you would clicking a link (an <a href="/example/"></a>) element).

The <button> element, by itself, can't do that. There have been various conversations about allowing "href anywhere" over the years, but nothing has came of it.

Clicking on a button does do something though, when used in its natural environment...

Button is a Form Element

Web forms have submit buttons. You might think of that like this:

<form action="/" method="post">
  <input type="submit" value="Submit">
</form>

A <button> element in a <form>, by default, behaves identically to that submit input above.

<form action="/" method="post">
  <button>Submit</button>
</form>

However gross the UX, forms can have reset buttons as well. You can duplicate that behavior by changing the default submit type to reset.

<form action="/" method="post">
  <button type="reset">Reset</button>
</form>

Clicking that button will clear all the other inputs (and textareas) with the parent <form>.

Buttons can have content

The primary reason for using a <button> is that it has both and opening and closing (</button>) tag. Which means there can be stuff inside. A common use case would be something like:

<button>
  <img src="tiny_birthday_cake.png" alt="">
  Submit
</button>

While an input can be <input type="image">, this mixed content would be hard to pull off.

As far as I can tell, there is no limit to what kind of content you can put in a button, so feel free to get real weird with it. Pseudo elements can be used too.

Let's leave styling <button>s for another day, but different browsers generally have a special style they apply to buttons. You'll want to either leave that alone so the default comes through, or remove it thoroughly so your new styling can be consistent across browsers.

Let's consider: "if a button doesn’t have a meaningful href, it’s a <button>"

I said recently that I enjoyed that sentiment. That's what kicked off this article for me. At the time, I was thinking of how I enjoyed the semantics of it. As in:

<a href="#0">
  I'm kinda sick of doing this for buttons.
</a>

There is no meaningful href there. The 0 is just there so it doesn't jump the page, because ID's can't start with a number.

Chances are, HTML like the above means: I'm going to make clicking that do something with JavaScript. Somehow that feels better than a <div> whatever, because you get the cursor change and whatever else default styles.

If you don't like those meaningless href's, a <button> can seem like a nice alternative. But unfortunately outside of the context of a <form>, a <button> is equally meaningless.

<button>
  Outside of a <form>, I'm just as useless.
</button>

But <button> feels better anyway

Even if a <button> doesn't do anything outside of a form without the help of JavaScript, it still feels better for things you can click that do stuff other than change pages. A bogus href link definitely doesn't feel right.

Alright. Let's insert it with JavaScript then.

That's probably the best solution. If JavaScript is required for the clickable-thing to do anything at all, it might as well not even be there at all unless JavaScript runs. We can do:

// 1. Create the button
var button = document.createElement("button");
button.innerHTML = "Do Something";

// 2. Append somewhere
var body = document.getElementsByTagName("body")[0];
body.appendChild(button);

// 3. Add event handler
button.addEventListener ("click", function() {
  alert("did something");
});

You could easily have "button adding" be a part of your JavaScript workflow.

When links make more sense

If there is any kind of href you could put on that link that makes sense, by all means, use an anchor. Even if you override that behavior with JavaScript. That's progressive enhancement at it's finest. For instance:

  • A search button normally triggers a type-ahead ajax-search thingy - but the href could just point to a /search/ page.
  • A publish button triggers the the next stage of publishing something a user built - but the href could just point to a /publish/ page.
  • A thumbnail button opens a lightbox with a larger version - but the href could just point to the URL of that larger version.

If nothing makes sense, insert the button with JavaScript.

Accessibility concerns

Let's say using an anchor link does make sense. After you give yourself a nice little back-pat for being good at progressive enhancement, there is accessibility to consider as well.

You might be like, I got this!

<a href="#meaningful" class="button" role="button">
  I'm good
</a>

But you aren't out of the woods yet. MDN covers it well:

Warning: Be careful when marking up links with the button role. Buttons are expected to be triggered using the Space key, while links are expected to be triggered through the Enter key. In other words, when links are used to behave like buttons, adding role="button" alone is not sufficient. It will also be necessary to add a key event handler that listens for the Space key in order to be consistent with native buttons.

Get that? You activate links and buttons with different keys, so consider that.

Go forth and uhm, make clickable things correctly.

Comments

  1. Good article. I too find myself using <a> tags with dead links far too often when I could easily use a <button> instead, especially when considering mobile development.

  2. Permalink to comment#

    Aside from using buttons with forms as mentioned I don’t quite see the benefit in most cases, unless you’re looking for the default styling that comes with it (or like the semantics of using <button> tags for buttons).

    I like the sentiment behind “if a button doesn’t have a meaningful href, it’s a <button>” , but typically I instead use <div> rather than <button> in those cases. The only drawback I’ve noticed with using <div> for buttons is that you have to set the CSS to “cursor:pointer” or it won’t be clickable on some mobile devices like the iPhone. Still, I prefer using <div> to button usually because I don’t like having to reset the button’s default styling.

    • Permalink to comment#

      Greg,

      Using a div is completely inaccessible. It is not focusable by keyboard and is not announced as button by assistive technology. Divs are meaningless and unusable by many users.

    • Flunch
      Permalink to comment#

      Then you should also add role=button and a valid “tabindex” to all your “button div” to make it really behave like a button (be accessible for keyboard users for examples, etc …)
      And you still won’t have access to css properties like :active …
      Is it reallly worth it ?

    • Ben
      Permalink to comment#

      I agree with Flunch. To properly imitate native < button > functionality will usually take more time than you would have spent resetting styles, and it’s also more likely to break without you knowing about it. I think this is true of most native elements that a user can interact with in some way. If you’re not prepared to research all the accessibility implications and test that your hack will work across all browsers, devices and assistive technologies, you’re probably better off styling the semantic element (even if that has its challenges too).

    • Permalink to comment#

      That’s a great tip, thanks! All cases where I’ve used a <div> adding a :hover/:active state has never been a problem because I wanted to stylize those states anyhow either (changing the text color, adding a box-shadow etc). It has been a problem with <a> tags however because I need to then remove the underline, the blue color, the red color when active and the purple color when the link is visited. The :visited selector is the one thing that links have that <div> don’t have going for them and it’s not a concern as it does not benefit the user is situations where I am using this approach.

      With <button> there are other styles I would have to reset as well, plus fun cross-browser quirks like this one: http://doctype.com/submit-element-text-moves-over-few-points-active-firefox-only which are a joy to troubleshoot.

    • DanielGoransson
      Permalink to comment#

      Also, add both Space and Enter keys for executing the function.
      And even if you do all this extra work, the speech controlling app Nuance Natural Speak won’t recognize the “button” since it don’t read the Accessibility API and don’t care about ARIA (role=button). It only reads the DOM and looks for either the button or a elements.

      Please use the <button>!

    • Permalink to comment#

      So long as this is an issue: http://stackoverflow.com/questions/3110564/remove-the-complete-styling-of-an-html-button- <button> is not an acceptable option unless you are ok with that behavior (I am not). I will however consider using <a> tags instead when necessary, as suggested in the article. I am fine with going through ‘all the extra work’ if it means I have control over how an element functions cross browser. And at the risk of sounding insensitive (probably too late by this point) how come Nuance Natural Speak’s inability to recognize Accessibility API and role=button the fault of the developer? Shouldn’t the guilt fall on them for not improving their paid service?

  3. Jason
    Permalink to comment#

    Just a side note related to the comment: “IDs can’t begin with a number”… Now with HTML5, IDs can be any non-space character, and can begin with any character so desired.

    • That may be true as far as standards are concerned, but I’ve recently run into Sass errors trying to compile css containing ID’s that began with numbers.

      Just a heads up.

    • That’s true, but if you want to use CSS to style that element by its ID, you’re out of luck. The ID in a CSS ID selector can’t start with a digit.

    • Chris
      Permalink to comment#

      For what it’s worth, it would be unwise to create variable names or ID’s, or names of anything beginning with numbers in any language.

    • T.J. Crowder wrote:

      if you want to use CSS to style that element by its ID, you’re out of luck.

      Luckily, you’re not.

      The ID in a CSS ID selector can’t start with a digit.

      When you read the very section in the spec you’ve linked to carefully, you’ll notice that it’s described there what to do in these cases:

      As always with characters that have a special meaning in a given context, you need to escape them, as MaxArt has already pointed out.

      For practical reasons, it might be a good advice to start an identifier with a letter, though.

    • Permalink to comment#

      Roman Numerals FTW.

  4. Permalink to comment#

    Very nice article, pretty clever the way you explain the difference between a tag and button tag.

  5. This is a good article with a superbly misleading start. Buttons exist in HTML to either send off a form or to trigger script functionality, neither of which is what an anchor element is meant to do. This means making a button act like a link is using it because of its looks and not because of its semantic meaning.

    Think of BUTTON as the DIV of interaction. It has no predefined way to act – you have to add that using it either inside a form or by applying an event handler to make it call a script. Using a button to have an href would be as bad as using a link with a javascript: href.

    • with a superbly misleading start.

      I re-read it several times. It makes sense to me. I feel like I am trying to make the exact same points as you are making here. But sorry if I’m ruining the internet or whatever.

  6. Greg: a DIV is also not keyboard accessible – something links and buttons have built in.

    • Permalink to comment#

      Ah good to know. I wonder how many use cases there are though where that’s a concern, I haven’t used the Tab button on my keyboard to navigate a page since I had my computer mouse taken away as a kid.

  7. Julien Cabanès
    Permalink to comment#

    How have I lived so far without this href="#0" thing ?

    Thanks for this article ! I hesitate everytime about this…

  8. Greg, then you are lucky that you don’t have a disability that prevents you from using a mouse. “Works for me” is not how accessibility works.

    • Greg might want to read this: http://webaim.org/articles/visual/blind

    • Permalink to comment#

      Greg will look at article. You can reply to the comment made and not start a whole new one, would prevent having to reference my name each time. I am aware that screen readers exists also, I suppose I could have phrased things differently. I believe there are websites that do exist that cannot be made accessible for all parties no matter how many alt tags you add to images etc. For news sites, blogs etc. that provide enough content to the user to be worthwhile a blind people to have in interest in them, yes, accessibility is definitely a concern. Other sites, like codepen.io I doubt this would be a problem since it’s highly unlikely the site would useful in anyway to them that would be worthwhile to try and modify it to be accessible for screen readers.

  9. Another very worrying hint in here is to use links to trigger form submission like a save button. Doing any form submission using GET (which is what a link like save/ would be) is a massive security issue as nothing would prevent me from doing that from the CLI instead of your page. That’s why buttons are in most CMS.

    • Permalink to comment#

      Concerning form submission using GET, this could lead to problems with browsers that prefetch existing links in the page. As far as I know, this wouldn’t be an issue if you’re using a button.

    • Exactly Mike. I remember when Google had the web accellerator toolbar for IE and Firefox (long ago) which prefetched links. Opening an old WordPress back then deleted your whole DB as “delete post” was just a link.

    • That’s fair. It’s generally not a good plan to have a saving action be a GET. I’ll change it to something more realistic. But I think the point stands, it’s about hrefs that point somewhere that would do the same thing as the JavaScript-powered action would do.

    • A button has no href and never was meant to have one. That is the confusion here. We’ve been continuously mixing up what buttons and what anchors are for:

      Anchors: provide a link to another location, pointing to another document or a target in the page.
      Buttons: either submit form data and define what action should be done with the data once it is sent (i.e. add, delete, update all being in the same form) or being an interaction element that JavaScript needs.

      Having an href with lots of GET parameters is a very bad idea, as links get indexed. That’s why A make terrible buttons.
      Having a button simply redirect to another page either means you need to define the URL to go to in a form field or you need to use JavaScript and document.location.

      Both buttons and anchors are awesome for accessibility as they support a multitude of input formats (touch, click, keyboard). Buttons are meant to be the thing to use if you want to fire off script functionality in an accessible manner in HTML – there is no other element that is there to do that.

      All this would not be a question at all if

      a) OldIE wouldn’t have been utter crap at styling buttons or really supporting them without the double submission quirks
      b) Anchors wouldn’t allow crap like inline event handlers or “javascript:” pseudo protocols.

    • Permalink to comment#

      Just wanted to add that Chrome on IOS has the option to preload pages.

      See here: Bandwidth management on Chrome for mobile

  10. Permalink to comment#

    Awesome. I’ve used <button> for a long time in my projects so that I can use icons and such. From my own testing I came to the same conclusions, and it always worked in IE7+, but I’m glad it’s now official :).

  11. Beben Koben
    Permalink to comment#

    This is a case…hihihi :D

    <a href="">
        <button>Submit</button>
    </a>
    
  12. Eric
    Permalink to comment#

    Just be careful if you’re working in the .NET Framework. Most pages are all forms and using a button will cause a callback unless you explicitly prevent it in your button click action. This always trips me up with SharePoint development.

    • ShirtlessKirk
      Permalink to comment#

      Only if you’re using ASP.NET WebForms. MVC and Razor pages don’t need that awkward break-the-web mucking around of yesteryear…

    • Gaby
      Permalink to comment#

      Hi Eric, I think the easiest way to override the default behavior (submit .NET form) is to use

      <button type="button"> </button>
      

      If you want to have it fall back to “submit” for progressive enhancement, you shouldn’t do this, but I like it for the “do something with JS” type of button that Chris is describing. I find this a little easier than always having to prevent default in the click actions.

      Rodney mentioned it below as a fix for buttons outside forms, but it also solves our .NET problem.

  13. Chris
    Permalink to comment#

    What if I want to use input type=”submit”, but also have buttons that do other stuff in my form block… will those extra buttons act like Submit buttons?

    Eg. a form with dynamic number of input rows, like when clicking a button to add another browse box for multiple file uploading.

    • Permalink to comment#

      If your buttons are all inside a form but some aren’t for submission use type=button on them. This suppresses the submission behavior.

      Testing in CSS:

      form button:not([type]):after {
      

      content: “warning…”;

    • Chris D.
      Permalink to comment#

      @Heydon, thanks.

      Does that mean we are supposed to write; <button type=”button” role=”button” … just seems odd, it’s a button element dang it.

      If this is the case, then I’d find it much easier to just have a js script that auto adds those attributes to each <button> element on page, unless it specifically has type submit. Or, include in coding convention for team to follow.

  14. michael
    Permalink to comment#

    I’ll often have a form that submits as part of a jquery function, so a button makes more sense to avoid the default SUBMIT action. The button element also makes a nice trigger for an accordion or other javascipt control.

  15. Permalink to comment#

    First of all I totally agree on what Chris H is saying in his comments and secondly it’s role="button" not aria-role="button" :)

    • Thanks I fixed that. That can be confusing, because they are commonly called “ARIA Roles” and many of the attributes do start with aria-, but just not role.

  16. As far as I can tell, there is no limit to what kind of content you can put in a button…

    button elements can contain phrasing content, so there are lots of things you can’t put in there. Any flow content, for instance, such as blockquote, div, p, nav, hr, …

  17. MaxArt
    Permalink to comment#

    Hey, Chris, I know it’s a little off-topic but there’s another way to make a selector for elements with an id beginning with a number:

    #\31 23hello {...}
    

    This matches all the elements with the id “123hello”. In addition to the other one you suggested in the linked article:

    [id='123hello'] {...}
    

    But it should be supported by IE6 too… for those who still have to do with it! (I pray for their souls.)

    By the way, I’ve been using <button>s more and more lately, but the problem is that they’re heavily styled by browsers by default, so you may never know what styles are going to be used and you’d like to reset. Until the appearance style property will be universally adopted. Ugh.

  18. DS
    Permalink to comment#

    One thing that doesn’t come up in discussions about links or button are states. I really like the possibility to simply disable a trigger element under certain circumstances. To do that with links it takes more code that is less easily maintainable.
    A link should be used when it´s a link. A button when it´s not a link.

  19. Please note that the <button>‘s default type is “submit”. If you want to use a <button> to invoke things other than submit / reset a form, please specify it properly: <button type="button">.

    Internet Explorer (at least up to 9, haven’t checked on newer versions) will f*ck things up when it encounters a submit <button> outside of a <form>. It will try to submit the previous form (if available) when the button is clicked. This can be annoying to debug.

  20. Adam T
    Permalink to comment#

    In HTML5, using a outside a form is perfectly valid, and is a much better bet for tab order, accessibility and so on. Null links are semantically misleading.

    Important! You really must specify a type attribute (usually type=”button”) because IE8- assumes it’s a submit if you don’t…

  21. Efraim
    Permalink to comment#

    I like this approach:

    var button = document.createElement("button");
    button.innerHTML = "Do Something";
    

    But now there’s content that belongs in the markup in the javascript! How about translations? CMS editable button labels? What’s considered best practice to solve this? Output strings as js variables in the markup inside ?

  22. Permalink to comment#

    Hey Chris:

    You say that “ID’s can’t start with a number” but I think that its a bit inexact.

    Any css selectors can’t start with a number in the style sheets or into the html style element, yes.
    But into the html attribute (id=” or class=”) yes.

    So your example html code its ok and valid (no error in validator)

      <a href="#0">
        I'm kinda sick of doing this for buttons.
     </a>

    and for it, we have the scape character in the css: # {/*nice styles */}

    I think

  23. Any particular reason for storing var body = document.getElementsByTagName("body")[0] instead of just calling document.body directly?

    • I thought of that for a second and then couldn’t remember if there was a way to directly access the body without querying for it or not. My grasp of the DOM is NEWB. I’m sure document.body is better.

    • MaxArt
      Permalink to comment#

      In more recent browsers, there’s document.head too. Too bad this isn’t supported by IE8 (or Firefox 3.x, but whatever).

      document.body is supported since forever, instead. Just remember that it may not be defined yet depending on the ready state of the document.

  24. Hey CHRIS, nice article!

    I also use “button” for actions in same page and “a” for links.

    ; )

  25. Permalink to comment#

    On a recent site, we had <button> elements with content inside which was revealed upon clicking the button. A reasonable use case, since we wanted the entire content tile to be clickable.

    It worked correctly everywhere that was tested, but a link that was nested inside of the button was not clickable only in Internet Explorer 8. IE8 (and below, most likely) does not register click events on elements inside of a <button>, and therefore links within a button are not supported.

    Example code:

    <button class="Tile">
        <h1>Heading</h1>
        <p class="Content">
            Lorem Ipsum... 
            <a href="http://google.com/">Google</a>
        </p>
    </button>
    

    I tried to track the target of the click, but IE8 only registered the button as clicked. I even went as far as trying to grabbing the coordinates of the click and comparing that to the coordinates of the links within the button. However, the simplest solution was swapping out <button> with <div>.

    Just leaving this here in case anyone else gets stuck on that issue.

    • MaxArt
      Permalink to comment#

      I think it sort-of makes sense. You have a clickable element inside another clickable element. While you may have your reasons for that, it looks more like a flawed UX interface.

      And at Microsoft thought it was ok to mess up with the default behaviour. Figures.

  26. @Chris

    Lets we have following button element in form

    <button name="test" value="val1">val2</button>

    which value test variable will hold val1 or val2

  27. Alex
    Permalink to comment#

    Good article Chris. It just confirmed my always believe “using of native HTML elements is preferred to ARIA roles”. So, if you have a button make it a button don’t place a link with role=”button”, it’s better both semantically and performance wise.

  28. Permalink to comment#

    What about <button onclick="ajaxload(this.firstChild.getAttribute('href'))"><a href="/stuff">Go to stuff</a></button> ?
    :D

  29. Tom
    Permalink to comment#

    Thanks for the info, Chris! I often had this same discussion with myself internally, but you added even more depth and info to. I hadn’t known about the different keyboard triggers, which is pretty important.

    I also wanted to share something I came across today. In IE 8 (possibly others – haven’t tried), when a button is in the :active state, it adds some formatting to give that “3D press” effect, shifting the text 1px right and down, and sliding the background position 1px left and up. Seems to also add some margin. The only way to really get around it cleanly is to use an <a> instead. (You could do some styling on button:active to undo some of it, but that didn’t work in my case, since I had an :after that was getting messed up as well).

    Since I’m using the buttons to trigger actions on the page, rather than navigate, I wanted to use a <button>, but since I had to switch, I’m thinking of wrapping them in a <menu> list for a bit more semantics.

  30. True story:

    In my HTML mockups I do: <button class="btn">Search Products</button>.

    Hand off the HTMLs to the off-shore developers and now the button is: <input type="submit" value="Search Products" class="btn">

    ¬¬

    Dude!

  31. Permalink to comment#

    Great article. Still wondering what makes the so attractive to a lot of developers ^^

    • Permalink to comment#

      Still wondering what makes the <input type="submit"> so attractive to a lot of developers ^^ (forgot to use the inline code)

    • Because they didn’t know there was an HTML element called <button>, so they kept using the only thing they knew (and many still only know), <input type="submit">.

  32. joan
    Permalink to comment#

    Well, buttons can be triggered using either the space key or the enter key, right?

  33. Alex
    Permalink to comment#

    @Brecht

    The preference for<input type="submit"> is commonly used because <button> was notoriously buggy in Internet Explorer.

  34. Your note about the “reset” button is a little misleading

    Clicking that button will clear all the other inputs (and textareas) with the parent

    <

    form>.

    The Reset button is actually a pretty powerful tool when used correctly – it resets the form to the loaded state. So if I’m editing an existing form with existing values (think editing an existing database entry), clicking “Reset” sets the values BACK to the originals – NOT clear them. Again, when used appropriately, this can save users when they make mistakes on a form.

    • Every time I see a Reset button next to a Submit button, I pray to the Gods of User Experience, Usability and Interaction Design to enlighten the users to correctly aim their cursors and fat fingers to click/tap that glorious Submit button.

  35. Permalink to comment#

    To get a button element inside a form to NOT act like a button, you can also do this:
    <button type="button>action</button>
    This will stop it from trying to submit your form and is much faster than adding the jquery preventDefault(); method.

  36. Permalink to comment#

    One point I am missing in the article is that (for me) it makes more sense to use buttons in forms because they allow me to specify a value that differs from the text that is displayed on the button. So one could do something like this:

    <form method="post">
        <button name="action" value="save">Save this article</button>
        <button name="action" value="publish">Publish this article</button>
        <button name="action" value="save,publish">Save and publish this article</button>
    </form>
    

    This works because only the value of the button that was used will be sent to the server. I am not sure if it was meant to be used that way, but it proved to be very usefull for me. Not only is this impossible to do with inputs, it makes programming a backend a lot easier because you can reformulate the button text without affecting the code that is sent to the server. Very usefull in multi-lingual environments too.

  37. Great article Chris! What if instead of creating our buttons through javascript, we simply “display:none” they with a “no-js” body class approach? Do You think this can cause any problems?

  38. Permalink to comment#

    Alright. Let’s insert it with JavaScript then.
    That’s probably the best solution.

    Chris, I don’t think mixing Content Layer (HTML) and Behavior Layer (JS) would be a nice idea or, at least, not the best solution as you point. Besides it doesn’t scale well, if you’re concerned about accessibility you might concern about people who don’t have javascript enabled as well.

    I think, as the web moves forward, not all HTML elements must have a predefined behavior. Say, not all buttons must do something without having JS, i.e. submit, reset, …

    • I think you’re being too dogmatic about JavaScript’s role. We’re discussing a button here that has no functionality whatsoever if not for JavaScript. Having that be on the page at all is what is bad for accessibility. And regarding scaling, I’m not sure what the thinking there is. I can imagine perfectly well a JavaScript file in my app which handles the injection of buttons in the places they need to be, using a nice extensible template.

  39. Sometimes being a web programmer can really give you headaches and the button tag has long been an annoyance to many. Hopefully as web standards continue to evolve (do try to keep up, Microsoft), the issues with buttons won’t be as widespread as they have been.

    With responsive design as it is today, they SHOULD be an aspect that’s all about enhancing the user experience with little or no effort from the website developer – we shouldn’t be having to hack and debug such things in this day and age, surely?

  40. jsdev
    Permalink to comment#

    DISCLAIMER: I do not have to worry about IE8 and below.

    I develop for the mobile web for all mobile devices [all smart phones and tablets except Blackberry and Opera Mini]. From the codebase I inherited over a year ago, converting links that acted like buttons to button type=button, shrunk code base and a lot of device specific issues went away, going forward since been very smooth.

    Yes <button> tag does not work for older IE browsers, and issue Greg linked to was specific to <input type=”button”> which IS NOT the same as <button type=”button”>, you will often need to define the type as Chris points out within context of a form <button> will default to type submit so hitting enter will anywhere within the form will have consequences.

    Al my buttons trigger natively on click, tap, space and enter, are all focusable, accessibly tab-able without a tabindex. I don’t need to listen for keypress or prevent defaults like I would for a link styled as a button acting as a button.

    I highly recommend if you don’t have to support older browsers, and when I say support I mean make it look exactly the same. Most clients can be convinced now better a site looks good and functional on a table than making IE8 and below look [as] good.

    • jsdev
      Permalink to comment#

      And yes button styles will likely need to be reset with CSS, that shouldn’t be a big concern.
      Also worth noting is while you may not have to worry about 508 compliance, doing so surprisingly makes supporting all the various devices easier.

      When I say easier for instance I don’t have to listen for tap. everything I do is click, keypress will call click, tap will call click, assuming I use the correct element [and attributes] for the task.

      One of the nuggets I recently learned was I couldn’t play sound automatically on IOS devices. it had to come from user clicking/tapping to allow sound to play the first time, you couldn’t call click via javascript, had to be from user, which is good for 508 as user gets chance to have screen read, then choose to click.

  41. A well-timed article for me. Some stuff to consider that I hadn’t yet. I just started using <button> and I had to learn a few things. Started freaking when it didn’t work in IE8, but that was easily fixed. Besides all the practical reasons mentioned, it just feels so much better than using inputs or styled anchor tags.

  42. Alex Bondarev
    Permalink to comment#

    Thanks, Chris. I agree on most of the points you wrote about. Although I’m quite surprised at one of the things you describe in the “When links make more sense” section.

    A search button normally triggers a type-ahead ajax-search thingy – but the href could just point to a /search/ page.

    I seriously doubt this applies to a link tag even though you may try to give it a meaningful href. Can you clarify this part a bit? It’s a bit misleading :)

    The action attribute of the form tag contains the URL (normally) and the browser will load this URL by default after submitting.

    • Right, that’s not a great example, sorry about that. The example should be a type-ahead ajax-searchy input with actions triggered by a submit button, but it’s built as a real <form> (as you suggest) with an action attribute that goes to a page that does what it needs to do server-side and renders a useful page. The poster-child of progressive enhancement, really.

  43. i just read your linked article “ID’s Cannot Start With a Number” and you say in it that “Class identifiers are allowed to start with a number” !! when that’s not true .. i know cause i tried to have class names start with numbers several times before i realize i can’t.. so is that a mistake or is there a way to actually make that work?

    • Chris
      Permalink to comment#

      I know several languages, and I cannot recall any that allow a number at beginning of a Variable/ID name.

      Note that everything you place on a HTML page is going to become something in “the DOM”… that means language, code, ID’s, variable names, etc.

      Starting ID’s with a number should be avoided at all costs, even if you find a browser or situation where it works, you would be treading on thin ice.

      PS: for people that are cycling through elements on page with JS – such as #myRow1, #myRow2… then 1) just place number at the end, 2) alternatively, don’t use ID’s and learn the better way to cycle through those elements doing it with “selectors”, and something like the .each() function, using a JS library (such as jQuery)

    • Jason
      Permalink to comment#

      IDs and classes can easily begin with a number (any non space character at all, including all of unicode). Simply escape the particular character or use the unicode codepoint as already described: http://css-tricks.com/use-button-element/#comment-1066440

      This is per the HTML spec. Only HTML <=4 had restrictions on these attributes.

      As to the matter that HTML source becomes DOM; the DOM is more than capable of handling unicode. Special characters are a matter that ALL language lexers/parsers deal with. And they deal with it the same way: escaping. Special characters are only special when serialized as text. When read into their memory constructs (as DOM or ASTs or other), there is nothing special about them. They’re just characters (or tokens).

    • I forgot to say I was talking only about css class names

    • Jason
      Permalink to comment#

      I’m not sure I follow you. I assume you mean the HTML class attribute (since there is no such thing as css classes).

      But the HTML spec states that both id and class attributes have the same character requirements; with the exception being, of course, that id cannot contain spaces, whereas class is a list of spec-separated tokens. But the tokens themselves adhere to the same rules. Which is, any character is valid (at any position) except space.

      So a leading digit in class name selector would need to be escaped via the same rules as an id selector: by using the unicode code point.

      Long detailed post on the specifics of escaping tokens in CSS and JS

  44. Gregor
    Permalink to comment#

    Nice! +10 for a complete explication, so many articles that I read for nothing, this have everything that I needed.

    In my work, everyone use some “dirty code” just to put an image in the buttons, even using tables to make it fit like they wanted and using links inside to send the user to another page.

    I was having problems because the button always “submit” the forms when they are inside a form, but we dont “submit” anything, now we managed the values of the form with javascript or jquery and later send it with xajax.

Leave a Comment

Current day month ye@r *

*May or may not contain any actual "CSS" or "Tricks".