How to set up an accessible form using Contact Form 7 in WordPress

Update and disclaimer, April 29, 2021: Gravity Forms 2.5 had a huge accessibility overhaul and a content manager can create accessible forms with this plugin now. Also this is a very old post and doesn’t include recent updates by Contact Form 7 itself.

Recently I discovered Contact Form 7 (CF7) by Takayuki Miyoshi. A plugin to create forms on a WordPress website. I was looking for an accessible alternative for Gravity Forms, and discovered that Contact Form 7 does an excellent job!

Contact Form 7 recently (version 3.6) added accessible WAI-ARIA to the forms, e.g. for error messages and required fields. Also the plugin gives you complete control over the HTML output of the form.

A second advantage of Contact Form 7 is that the backend is fully accessible, so a visually impaired content manager can build her own forms.

The only drawback is that the default form, provided by the plugin needs to be changed to make the form fully accessible, but that’s easily done, unlike with Gravity Forms.

For example, you want to add a small contact form with name and email.

Change the default form from:

<p>Your Name (required)<br />
[text* your-name] </p>
><p>Your Email (required)<br />
[email* your-email] </p>
<p>Subject<br />
[text your-subject] </p>
<p>Your Message<br />
[textarea your-message] </p>
<p>[submit "Send"]</p>


<label for="name">Name (required)</label>
[text* your-name id:name]
<label for="e-mail">Email address (required)</label>
[email* your-email id:e-mail]
[submit "I want your newsletter"]


The shortcode [response] is the space where the error messages are placed, nicely above the input fields. You can move and/or repeat it if you want.

A fieldset was added to the HTML, if you want you can add a legend here too.

Each input field has a proper label connected:

  • the label has a for=”name”
  • the input field has a id:name

The generated HTML inside the form element then will be:
<label for="name">Name (required)</label>
<span><input type="text" name="your-name" value="" size="40" id="name" aria required="true" aria-invalid="false" /></span>
<label for="e-mail">Email address (required)</label>
<span><input type="email" name="your-email" value="" size="40" id="e-mail" aria-required="true" aria-invalid="false" /></span>
<input type="submit" value="I want your newsletter" />

UPDATE March 2015: Joe Dolson wrote a very useful plugin for adding this HTML by default: Contact Form 7: Accessible Defaults

Change some settings

By adding constants to wp_config.php you can disable the plugin’s CSS and JavaScript.
With WPCF7_AUTOP you can prevent CF7 adding a <p> with each line in the HTML.

The amount of CSS is conveniently small, but if you like to add your own style in your theme style.css, you can disable it.

Disabling the JavaScript has the advantage that the page is refreshed and the focus is set to the top of the form, so if there are form errors, the visitor will see (or hear) the form errors right away in a new page. This may not be a accessibility requirement, but I find it more usable.

* Contact form 7 constants.
define( 'WPCF7_AUTOP', false ); // no extra <p>
define( 'WPCF7_LOAD_JS', false );  // disables JavaScript
define( 'WPCF7_LOAD_CSS', false ); // disables the default CSS

And you can add a class of your own to the form, by adding something lik this to your functions.php:

/* Add class to wpcf7 form */
add_filter( 'wpcf7_form_class_attr', 'prefix_form_class_attr' );
function prefix_form_class_attr( $class ) {
$class .= ' prefix-wpcf7-form';
return $class;


This plugin is great for building accessible forms. However, the content manager needs to know some HTML to keep it accessible.

It would be more convenient to provide options for the auto p, CSS and Javascript in a settings page. Changing the wp-config.php for a plugin is a bit of a kludge.

Contact Form 7 provides a good set of tags, including a CAPTCHA (combined with Really Simple CAPTCHA),  a large amount of extra plugins, e.g. for integrating with Askimet and MailChimp. It is well documented, maintained and supported.

It may not have the range of possibilities and visual effects of Gravity Forms, but it does what it’s supposed to do: build a good form with decent HTML.


  1. Hi, I’m building a website and using contact form 7 for someone using a screen reader.
    I’ve added the fieldset and labels as above, but he said he couldn’t enter text in the fields using a screen reader. He also said he wasn’t sure of the command. What can I do to help him?
    Thoroughly enjoy your blogs!

    1. Hi Kristin,
      Thanks for trying this out 🙂
      What is the code exactly you filled out with Contact Form 7?
      And which screen reader / browser is your client using?

      1. Hi,
        Thanks for replying Rian, I actually used the plug in Contact form: Accessible defaults.

        My client is getting back to me to let me know what screen reader he uses.

        1. Hi Kim, I looked at your site and also let a blind WordPress developer who uses a screen reader look at it and we cant’t find any issues with it. If you could ask your client what the exact problem is?

          1. Hi Rian,

            Thanks so much for looking into this for me. I am glad you couldn’t find any problems. My client hasn’t got back to me yet regarding what screen reader he uses, so I may ask for advice on commands if he can’t figure it out.

            Thanks again, Kristin

  2. Thanks. I would not switch out the JS. But it would be important that after submit button, the focus go to the response. Do you have any idea how to do that?

  3. I did what you posted above nut still it is showing that “there is no label for submit button”. What should I do now?

  4. Hello Rian,

    thank you for sharing the right way to make Contact Form 7 forms accessible.

    For Spam protection I would like to add a Honeypot Field and installed the plugin CF7 Honeypot from the WordPress repo ( It adds a new field [honeypot trapname] but I’m not sure whether I should add a label at all as it actually isn’t meant to be filled out by humans. Yet an empty form field without description might be confusing, too? The field gets hidden using inline styling style="display:none !important; visibility:hidden !important;".

    It would be lovely to get your advise.

    1. Hey Bego,

      If the style is set to style display:none it is also hidden for a screen reader. So the field is not announced.
      So that should be ok for screen reader users.
      I’m not familiar with CF7 Honeypot, so I can’t give you a reliable answer.

      1. Great! If display: none is recognized by screen readers as “ignore this”, it should perfectly work.
        Thank you very much.

Comments are closed.