Search code examples
formsaccessibilitywcag2.0

Web Accessibility - Control submit button not in the <form> is correct HTML structure?


I follow WCAG 2.1 Level A on the project, and want to work great "without JavaScript" include any <form> element.

This is my sample code:

// cart.html

<div class="wrapper">
    <!-- Form A -->
    <form action="checkout-step1.html">
        <h2>A form</h2>
        <label for="input1">input1</label>
        <input type="text" name="input1" id="input1" value="Cart Data">
        <input type="hidden" name="coupon-use" value="XXXXXX">
        <!-- Hide Submit Button -->
        <button id="btnCheckout" type="submit" style="display: none;">Checkout Cart</button>
    </form>

    <!-- Form B -->
    <form action="cart.html">
        <h2>B form</h2>
        <label for="coupon">coupon</label>
        <input type="text" name="coupon" id="coupon" value="CouponId">
        <button class="btn" type="submit">use</button>
        <div>
            <!-- Use label to submit another form -->
            <label class="btn" for="btnCheckout">Checkout</label>
        </div>
    </form>
</div>

I used Google Lighthouse, The W3C Markup Validation Service, WAVE Web Accessibility Evaluation Tool to validated page. Something looked great, but got some alert about the label that is control another form submit on tool WAVE.

Orphaned form label

A form label is present, but it is not correctly associated with a form control.

Could I use the label to submit another <form>? Is this correct HTML structure?


Solution

  • Short Answer

    For this to work without JavaScript you would need to move everything into one form or you need to handle everything server side and submit the forms separately.

    Could I use the label to submit another ? Is this correct HTML structure?

    The error is because you are sending information between two forms, a label in one form is technically not valid if it points to another form.

    Also I have never seen a label associated with a button before, but to my surprise it is valid HTML. Yet again, that is not expected though (I will have a read and see if I can find definitive guidance on whether a label is valid for a button).

    However you technically can do this, I mean, it works (surprisingly) but this is not a good practice.

    There are bigger issues though.

    Users cannot tab to the label for a start and also it would be unexpected behaviour for the label to submit a form (and expected behaviour is a large part of accessibility). Also pressing "enter" to submit the form would not work as you have no submit button for the second form, so that is more missing behaviour.

    If your submit button is display:none it cannot be accessed so that is another problem you need to correct.

    Finally even if you submit the first form, you can't get the second form information without JavaScript.

    Option 1

    Make it all one form. That way when you submit the form everything will get sent together.

    This is by far the easiest and cleanest way to do this, but obviously you may need a slight redesign for that.

    Option 2

    Handle multiple form submissions server side.

    You would have to set a session on the server so you can correctly associate the two forms.

    On the first form you would have to have a checkbox that says "I have a coupon to use" and initially hide the second form.

    Then when the first form is submitted you would have to either route them to the next checkout page if this checkbox is not checked or route them back to the same page, this time with the coupon section showing.

    Repopulate the first form (with all forms disabled) so they can see that their information is correct and hide the submit button on that form.

    Then when they submit the coupon form use your session ID to match the data and redirect to the new page.


    As you can see the second option is messy and fraught with issues (you need a back button so they can edit the initial form for example).

    I would just put everything in one form.