Media Temple Hosting

HTML5′s New “form” Attribute

HTML5's New form AttributeOne challenge that developers have faced when creating forms is the inability to separate a form control from its parent <form> element without having to resort to some undesirable methods to get that form control to submit its data along with the form.

If you tried to do this in HTML4 or XHTML, the form would not submit the information from the form control that’s structurally outside the form.

As a result, if you wanted the data from the orphaned control to be submitted along with the rest of the form data, you’d have to implement some fancy JavaScript tricks to pass the information into the submission — which has many obvious drawbacks.

A Better Way

HTML5 now introduces a new form attribute that allows you to associate any orphaned form control with any <form> element on the page. You can read up on this technique on the WHATWG HTML5 spec in the section Association of Controls and Forms, but here’s how this is done:

<form id="contact_form" method="get">

	<label>Name:</label>
	<input type="text" id="name" name="name">

	<label>Email:</label>
	<input type="email" id="email" name="email">

	<input type="submit" id="submit" value="SEND">

</form>

<textarea id="comments" form="contact_form"></textarea>

Notice two things:

  1. The <textarea> element is outside the <form> element (i.e. it’s a sibling, not a child)
  2. The <textarea> element has a form attribute with a value that’s equal to the id of the form with which I want it to be associated

It Overrides the Default Behaviour

With this attribute, you can actually override the default form control association behaviour. For example, if there are two forms on a page, you can “steal” a form control from form #2 and make it submit along with form #1.

This would happen even if the form control is nested inside of form element #2. And as a result, form #2 would not submit the “stolen” form control’s data. So the form attribute will override what would naturally happen.

UPDATE (June 16, 2011) This technique works the same way with the submit button for the form. You can have the submit button outside the form, and associate it using the form attribute and it will work the same way. Thanks to Veera for asking about that.

Browser Support?

I’ve set up a demo page with a form that has its method attribute set to “get”. This will cause the submitted values to be sent to the same page in a query string. If you’re using a browser that supports this feature, then you should see three values appended to the URL. If you’re using a nonsupporting browser, then you’ll see only two values.

I couldn’t find too many sources that discuss browser support for this feature, but according to this page and the sidebar column in the WHATWG spec, browser support is as follows:

  • Opera 9.5+
  • Safari 5.1+ (according to Elliot)
  • Firefox 4+
  • Chrome 10+

From my own testing, I got pretty much the same results as described above, except I can’t confirm partial or buggy support; as far as I could tell, it works the same in FF, Opera, and Chrome. You can go ahead and try it in your browser of choice to confirm or correct anything written here.

So, if you want to use this feature, you’ll have to have an audience with low IE numbers, or else feature detect and then provide a JavaScript fallback that will get the same results. I don’t see a specific polyfill for this on the HTML5 Polyfills page but it’s possible one of the HTML5 forms polyfills implements this — I just didn’t bother to examine all of them. Would be an interesting thing to work on, as this is a pretty useful feature.

Update (June 25/2011): As pointed out by Paul Irish, the WHATWG annotations that list support as “buggy or partial” aren’t reliable, so I’ve changed the browser support list to reflect full support for the browsers mentioned. Also, I had added IE10 to the list (as per WHATWG), but I’ve now removed it because according to my own tests, it doesn’t work in IE10.

49 Responses

  1. Neat trick!

    Also, it’s supported in Safari 5.1.

  2. Łukasz:

    Firefox 4+ (buggy or partial support)
    Is listed twice

  3. Supported in Webkit Nightly r88778.

  4. For my understanding, why would you want to structurally place a control outside of form tags, yet do want its value to be submitted? What would be viable reasons?

    • I think the primary reason is for styling, If you want a group of form controls to appear visually separated from other controls on the same form, it would be easier this way, without resorting to hacking the positioning.

      Also, I suppose there could be some complex web app functionality that could benefit from this. I think overall it’s a good feature, because it at least opens up a few doors, even if it’s not something that will be used too often.

      • Thanks for explaining. Agreed that there may be cases where it is good that this is possible, although I would argue that changing markup for the sake of style is not semantically correct. Yet, web development is all about tradeoffs.

        • Well, keep in mind that a form control being outside a form element is not necessarily incorrect semantically.

          In fact, in XHTML strict you can put inputs, select elements, and textareas outside of the <form> element and the page would still validate.

    • Heruan:

      It’s useful for nesting forms. For example, I use it like this:

      
      <form id="form1" action="/echo/html/" method="post"></form>
      <form id="form2" action="" method="post"></form>
      <input form="form1" type="text" name="html" />
      <fieldset>
          <legend>Attachments</legend>
          <input form="form2" type="file" name="upload" />
          <input form="form2" type="submit" value="Upload" />
      </fieldset>
      <!-- Other form="form1" elements -->
      <input form="form1" type="submit" value="Edit"/>
      
  5. WebKit shares this sort of code across ports, so I would expect Safari, webkit nightly and Chrome to have the same support. Btw Chrome 12 is now the stable build. :)

  6. It’s interesting, but, how much complexity is added in order to have such a flexibility ?

    Added complexity was/is the death of many as such initiatives. I think <object>, for example, never reached its full potential because of that.

    And what’s next ? Tie the sub-elements across the page with a nav=”primary” ? It’s a dangerous shortcut with the obvious design-related misuse.

  7. Dave:

    HTML5 defines over a dozen new input types that you can use in your forms. And when I say “use” I mean you can use them right now without any shims, hacks, or workarounds. Now don’t get too excited; I don’t mean to say that all of these exciting new features are actually supported in every browser. Oh goodness no, I don’t mean that at all. In modern browsers, yes, your forms will kick all kinds of ass. But in legacy browsers, your forms will still work, albeit with less ass kicking. Which is to say, all of these features degrade gracefully in every browser. Even IE 6.

  8. Vince:

    That’s handy to know :-)

    Who’s actually going to start using this though?

    For browsers where this isn’t supported (lots) how do I use this technique if JS is disabled in those target browsers?

  9. Wow. that is cool.

    Same way, is there an option to separate the submit button from the <form> tag and keep it outside the form? Is the ‘form’ attribute applies to the submit buttons also?

    • Good question! I didn’t even think of that.

      I just tested it, and yes, you can have the submit button outside the form and use the form attribute to associate it with the form, and it will still work. I’ll add a note to the article. Thanks.

  10. Why would you want to do this? Talk about messing your code up, it’s not very semantic.

  11. Great Job, Keep it up

  12. Firefox 5.0 Beta works just fine. ^^ Just as Chrome 10+ does (forgot to update for some time ^^), however Safari 5.0x doesn’t

    But anyways – very nice example, thanks :)

  13. This is great. I had to use different tricks for styling forms, now it is not needed.
    As for the browsers that do not support this: it is not bad to educate our users. Let us tell them that the browser they are using is too old for the current web. There is nothing wrong or bad in this. And the user who browses the web, today, with a IE6 deserves what he sees…
    Keep it going, great article!

  14. It remains weird. There may be some edge cases where it makes the job a little easier, but submitting a form field that’s positioned outside a form is quite tricky from a usability perspective.

    So you have two forms, and you’re submitting form fields from the second form together with the form fields of the first field. And you’re not submitting them with the first form. How in god’s name are users going to try and anticipate this behavior?

    One additional question: how about screenreader support? They usually lag behind a little, so I guess support is pretty much non-existent so far.

    Not really happy with this option, it seems to downgrade the focus on correct structure in your html pages. Whether it validates or not is besides the point, the fact that you’re positioning a form field structurally outside a form which it belongs too feels wrong.

    (I guess now they can start putting newsletter checkboxes underneath form submits and submit them along with the form without too much hassle).

  15. I’d like to see this implemented in polyfills in the future. This has always been under my skin but it was something I just learned to live with. NO MORE!

  16. I don’t see the practical point/purpose for this feature, can someone enlighten me as to why this is necessary to have?

    • Paul d'Aoust:

      Here’s a situation that I’m struggling with this very moment. I’ve got a form that looks like this:

      
      <form action="order.php" method="POST" id="shipping">
      	<ul class="formfields">
      		<li>
      			<label for="name">Name</label>
      			<input type="text" name="name"/>
      		</li>
      		<li>
      			<label for="city">City</label>
      			<input type="text" name="city"/>
      		</li>
      		[and so forth...]
      	</ul>
      </form>
      
      <div id="orderActions">
      	<input type="submit" name="← Review order" form="shipping">
      	<input type="submit" name="↻ Calculate tax" form="shipping">
      	<form action="http://paypal.com/yadayada" method="POST>
      		<input type="submit" value="Process payment"/>
      		[ PayPal Website Payment data here... ]
      	</form>
      </div>
      

      As you can see, for good UI design purposes, I want all the order actions to be contained inside one <div>, but if I try to close the form element just after the “Calculate tax” button (so that the PayPal form isn’t included as a child of the big form) it cuts that <div> in half and makes it non-valid markup.

      At present, I’m at a loss for how to mark this up. I don’t want to create generic buttons and add onclick() event handlers to them, because (1) that only works for Javascript-enabled users, and (2) it doesn’t handle events triggered by keyboard navigation. If all browsers supported the new form attribute, I’d be very happy!

      • I may be wrong but it look like you only have two form elements: And they are both already closed. As far as I can see, there isn’t a form element inside the div “orderActions” before the paypal form. So if you try to close a form right after “Calculate Tax” it will mark it as invalid because there is no form to close.

  17. luci:

    hi,
    imho to fully test if it works properly on the demo page, you’d need at least two forms there with different id and see how it works …

    this way you cannot be sure if it works because it is supported or because the browser is “too clever” and ignores the fact it is outside of the form element and submits it anyway.

    • Well, not necessarily. It clearly works differently on different browsers, and this is based on support for that specific feature. But yeah, it probably would be good to see how it responds with different forms on the same page. I don’t think the results would be any different though.

  18. @Niels Matthijs “How in god’s name are users going to try and anticipate this behavior?”

    They aren’t, because users don’t give two craps about which form they’re submitting to. They won’t even realize that there’s more than 1 form, or that the controls are outside of the form. They’ll just fill out the damn thing, then hunt for the “Do Something” button that matches whatever it is that they are trying to accomplish.

  19. David:

    I worked on a site that had multiple listings on a page for hotel rooms. Each listing was a form in itself, yet there was common information on the page as well that needed to be submitted with every form. This feature would have made things a lot easier!

  20. Martijn:

    “Browser Support”
    Doesn’t that make it completely useless for at least another 5 years? It’s nice to be aware of these things, but looking at the state of things, it seems we still have to revert to javascript to get this working. The only advantage to custom javascript is, well, this is a standard, and one that can be implemented in javascript.

    All we need now is a way to detect whether the browsers supports the form attribute, and preferrably a a way to detect whether the browsers is not too bugy about it.

  21. Tom Keenoy:

    I’m surprised at the number of “don’t like because it’s not semantically correct” types of responses. Application structure has historically been forced to conform to “controls inside form” convention (or rely on hacks to work otherwise). The fact that this is no longer a requirement is a GOOD thing. Just because you can’t think of a good use case doesn’t mean there aren’t any out there. Having additional freedom to build GUIs that meet design needs while still being semantically correct is only a positive change in my book.

    Regarding how to shim this for backwards compatibility, I can see a jquery plugin that writes hidden fields to the corresponding form element as a useful tool. One of you javascript gurus should get on it!

  22. Hi Louis

    I’ve tried the form attribute in Firefox and Chrome and it seems to be working well in them. But my tests weren’t rigorous – could you give us more information on how their support is “buggy”?

    I haven’t been able to cajole Safari on Windows to support the form attribute.

    bruce

    • Bruce,

      I’m the same way — I haven’t done many rigorous tests so I can’t say exactly why it’s considered “partial” or “buggy” support. I just didn’t want to contradict the sidebar support info on the WHATWG spec. For everything except Opera, it says:

      [browser] has partial support for this feature, but might have bugs and certainly doesn’t support all aspects of this feature.

      And interestingly, since I published this post, they’ve now updated that info to include IE’s latest Beta as having partial support. So it looks like IE10 PP has also added this…?

      But as far as I know, it works fine in all supporting browsers, so I can’t tell you what’s meant by “partial” on WHATWG.

      • Thanks Louis. I guess the FF and Chrome reps in WHATWG need to update that if necessary)

      • I spoke to ms2ger, who maintains the tests that annotate the whatwg spec. He indicates they shouldn’t be taken as fact. They rely on comprehensive unit tests (which in this case don’t exist) and get published without human eyes confirming.

        So, especially for this feature, your own tests are more reliable than what those annotations indicate.

  23. Nice one. as HTML 5 is still in development i wonder what else they have in stock.
    this one is very helpfull, i didn’t know that it’s possible thank you for sharing.

  24. It works in Chrome 14 and Firefox 7

    • Larry:

      Firefox 19, with the following code:

      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      <html>
        <head>
          <meta charset="utf-8" />
          <title>input_form_attr</title>
        </head>
        <body>
          A:<input type="number" id="a" value="50" form="output_x">
          <form id="output_x" oninput="x.value=a.value">
            X=<output id="x" for="a"></output>
          </form>
        </body>
      </html>
      

      doesn’t work. It allows entering data into the input field (e.g. changing
      the initial 50 to 4); however, as soon as enter is pressed, the value
      reverts to 50 and nothing appears after the ‘X=’.

      Am I doing something wrong or is Firefox19 not implementing
      this feature correctly?

      TIA.

      -regards,
      Larry

      • Larry:

        To be more specific, the Firefox used was that with, IIUC,
        an update version. The synaptic installer shows:

        Available versions:
        19.0+build1-0ubuntu0.10.04.1 (lucid-updates)
        3.6.3+nobinonly-0ubuntu4 (lucid)

        So I guess the real Firefox is 3.6.3

        Sorry for any confusion this may have caused.

        BTW, I also tried the Opera found in the deb file:

        opera_12.14.1738_amd64.deb

        which shows Version: 12.14.1738

        and that browser showed same behavior as the
        Firefox browser mentioned previously. IOW,
        no output is produced and the value entered
        in the input fields revert to the original value.

        Surely that’s not the expected behavior.

        -regards,
        Larry

      • I’m not sure exactly what you’re trying to do with that code. If you want to see the variables in the query string, you have to use a “name” attribute on the form input, and you have to set the method to “get”.

        If you do that, you’ll see that all browsers (including FF4+) will display the “a” input value in the query string. But if you actually have FF3.6, then it won’t work, because this feature isn’t supported in that version of FF.

        • Larry:

          Thanks very much for your reply Louis.

          The code was modified from that here:

          http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_output

          The code’s intent is to just display the sum of the
          two input numbers using the javascript code
          which is the value of the oninput attribute of
          the output element.

          I understand that if I actually have FF3.6 it won’t
          work; however, why doesn’t the opera version
          12.14.1738 work as expected?

          TIA.

          • Larry:

            Strangely enough, with the *same* Firefox
            browser, the following .html file, with an
            input element outside the …,
            works as expected producing:

            Last name: [last ]
            First name: [first ]FirstLast name: first last

            I’m baffled why the previous example failed
            and now this one succeeds :(

            The code follows:

            <!DOCTYPE HTML>
            <html>
              <head>
                <title>FirstNameLastName_form_attr</title>
                <!-- 
                  modified from:
                      http://swatelier.info/at/forms/HTML5attrib.asp
                -->
              </head>
              <body>
                Last name: <input type="text" id="lname" form="formID">
                <form oninput="flname.value=fname.value+' '+lname.value" id="formID">
                First name: <input type="text" id="fname">
                FirstLast name: <output type="text" id="flname">
                </form>
              </body>
            </html>
            
          • Larry:

            Removing the for=”…” from output element
            makes the form behave as expected.

            That must be a bug, right?

            -regards,
            Larry

          • Larry:

            In my synaptic package manager, updated *all*
            packages to latest available. Now my Firefox
            does *not* process the
            FirstNameLastName_form_attr.html
            (that’s the one shown above derived from
            your example)
            properly; however, the Opera browser does.

            I’ve no idea what Synaptic update caused
            this change :(

  25. supported in safari 5.1 …..Awesome

  26. That’s nice, though, I don’t see a reason not to put textarea from demo inside form.

    That would be useful if inputs are scattered across page.

  27. Herc:

    Just to say I have been waiting for this feature for such a long time. Symantically it means you group inputs through an attribute rather than nest inside a single form tag. It solves all the problems of integrating third party forms into asp.net pages, and frees up the layout of pages. It is great in Mvc.

    I can’t see it as hard to implement or confusing to use. It is, for me, the best feature of HTML 5.

    But of course Microsoft missed the point, left it out of ie9, and seem to be tying ie10 to windows 8. I just can’t use it!

  28. Thank you!
    This tutorial was very useful to me.

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field. If you use keywords, your comment will be deleted, or your name will be replaced with the alias from your email address. No foul language, please. Thank you for cooperating.

Instructions for code snippets: Wrap inline code in <code> tags; wrap blocks of code in <pre> and <code> tags. When you want your HTML to display on the page in a code snippet inside of <code> tags, make sure you use &lt; and &gt; instead of < and >, otherwise your code will be eaten by pink unicorns.