search ]

Playing with Contact Form 7 Design

The Contact Form 7 plugin is one of the most popular form plugins for WordPress, with over five million active installations. Its description – “Simple but Flexible” – is spot on.

However, the plugin has no built-in design interface. The forms it generates inherit CSS from the active theme only, and many developers don’t realize how much customization is possible with CSS alone.

All changes in this guide are CSS-only – no need to modify the plugin’s PHP files. Add the CSS to your child theme stylesheet or enqueue it via wp_enqueue_style.

This post collects tips, ideas, and lesser-known tricks for styling Contact Form 7 forms. Some are straightforward, some are hidden features – but all of them are useful.

Understanding the HTML Structure of Contact Form 7

Before styling anything, it’s important to understand the HTML structure CF7 generates. Every CF7 form is wrapped in a .wpcf7 class, and the form element itself gets the .wpcf7-form class.

Each field in the form is wrapped in a <span> with the class .wpcf7-form-control-wrap. Knowing these classes is the key to precise styling.

Here are the main classes worth knowing:

  • .wpcf7 – The outer wrapper of every CF7 form
  • .wpcf7-form – The form element itself
  • .wpcf7-form-control – Every individual field (input, textarea, select)
  • .wpcf7-submit – The submit button
  • .wpcf7-spinner – The loading animation after submission
  • .wpcf7-response-output – The response message after submission

Styling Input Fields and Textarea

CF7 fields inherit theme styles by default, which sometimes leads to an inconsistent look. Here is CSS that creates a clean, minimal appearance:

.wpcf7 input:not([type="submit"]),
.wpcf7 textarea {
    border: none;
    border-bottom: 1px solid #545454;
    background: transparent;
    outline: none;
    border-radius: 0;
    width: 100%;
    padding: 8px 0;
    font-size: 16px;
    transition: border-color 0.3s;
}

.wpcf7 input:focus:not([type="submit"]),
.wpcf7 textarea:focus {
    border-bottom-color: #a3316f;
}

The approach here is to remove all borders and keep only a bottom line. When the user clicks on the field, the line color changes to provide visual feedback.

Setting font-size: 16px on input fields prevents automatic zoom on iOS devices. Below 16px, Safari zooms in on the field when it receives focus.

Textarea That Grows on Focus

A nice trick that saves screen space – the textarea starts small and expands when the user clicks on it:

.wpcf7 textarea {
    resize: none;
    height: 46px;
    transition: height 0.4s ease;
}

.wpcf7 textarea:focus {
    height: 120px;
}

Disabling resize prevents the user from manually dragging the field. Instead, the transition creates a smooth animation that expands the field on focus.

Styling the Submit Button

The CF7 submit button gets the class .wpcf7-submit. You can style it however you want, but it’s good practice to include hover and focus states for accessibility:

.wpcf7 input[type="submit"] {
    background: #a3316f;
    color: #fff;
    border: none;
    padding: 12px 32px;
    font-size: 16px;
    cursor: pointer;
    transition: background 0.3s;
}

.wpcf7 input[type="submit"]:hover,
.wpcf7 input[type="submit"]:focus {
    background: #8a2a5e;
}

Tip: Adding a Custom Class to the Submit Button

You can add classes directly through the CF7 shortcode tag. Instead of writing [submit "Send"], write:

[submit class:my-custom-btn "Send"]

This lets you target the button specifically with .my-custom-btn without affecting other buttons on the site.

Adding Custom Classes and IDs to Individual Fields

Something many developers don’t know – you can add custom classes and IDs directly to CF7 shortcode tags:

[text* your-name class:my-input id:name-field placeholder "Full Name"]
[email* your-email class:email-input id:email-field placeholder "Email"]

This allows targeting specific fields in CSS without relying on CF7’s generic classes. Especially useful when you have multiple forms on the same page and want to style each one differently.

Styling the Placeholder

In CF7, you can set a placeholder directly in the shortcode tag. To change the placeholder text color, use the ::placeholder pseudo-element:

.wpcf7 input::placeholder,
.wpcf7 textarea::placeholder {
    color: #999;
    opacity: 1;
}

The opacity: 1 declaration is important because some browsers (notably Firefox) display placeholders with reduced opacity by default.

Example: Two-Column Form with Submit Button at the Bottom

A common layout is a contact form where the fields are arranged in two columns, with a full-width message field and a centered submit button at the bottom. Here is what it looks like:

CF7 two column form layout example

Form Code in the CF7 Editor

The following code goes directly into the form editor in the CF7 admin panel:

<div class="cf7-two-cols">
    <div>[text* your-name placeholder "Full Name"]</div>
    <div>[email* your-email placeholder "Email"]</div>
    <div>[text your-phone placeholder "Phone"]</div>
    <div>[text your-subject placeholder "Subject"]</div>
</div>

[textarea your-message placeholder "Message"]

<div class="cf7-submit-wrap">
    [submit class:cf7-btn "Send"]
</div>

The CSS

Add the following CSS to your child theme. It uses Flexbox to arrange the fields in two columns and center the submit button:

.cf7-two-cols {
    display: flex;
    flex-wrap: wrap;
    gap: 0 20px;
}

.cf7-two-cols > div {
    flex: 1 0 calc(50% - 10px);
    max-width: calc(50% - 10px);
    margin-bottom: 16px;
}

.cf7-submit-wrap {
    text-align: center;
    margin-top: 10px;
}

.cf7-btn {
    background: #a3316f;
    color: #fff;
    border: none;
    padding: 12px 40px;
    font-size: 16px;
    cursor: pointer;
    transition: background 0.3s;
}

.cf7-btn:hover,
.cf7-btn:focus {
    background: #8a2a5e;
}

@media screen and (max-width: 768px) {
    .cf7-two-cols > div {
        flex: 1 0 100%;
        max-width: 100%;
    }
}

In the media query, the fields switch to a single column on mobile for readability.

Example: Inline Email Form with Button

This layout is perfect for newsletters, signups, or anywhere you need a compact form with a single field and a button next to it. Here is what it looks like:

CF7 inline email form with button example

Form Code in the CF7 Editor

The following code creates a single-line form with an email field and a button side by side:

<div class="cf7-inline-form">
    <div class="cf7-inline-field">
        [email* your-email placeholder "Your Email"]
    </div>
    <div class="cf7-inline-btn">
        [submit class:cf7-subscribe-btn "Subscribe"]
    </div>
</div>

The CSS

The CSS uses Flexbox to align the field and button on the same row:

.cf7-inline-form {
    display: flex;
    max-width: 480px;
}

.cf7-inline-field {
    flex: 1;
}

.cf7-inline-field input {
    width: 100%;
    border: none;
    border-bottom: 1px solid #545454;
    background: transparent;
    padding: 10px 0;
    font-size: 16px;
    outline: none;
}

.cf7-inline-field input:focus {
    border-bottom-color: #a3316f;
}

.cf7-subscribe-btn {
    background: #a3316f;
    color: #fff;
    border: none;
    padding: 10px 24px;
    font-size: 16px;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.3s;
}

.cf7-subscribe-btn:hover,
.cf7-subscribe-btn:focus {
    background: #8a2a5e;
}

@media screen and (max-width: 480px) {
    .cf7-inline-form {
        flex-direction: column;
    }
    .cf7-subscribe-btn {
        width: 100%;
        margin-top: 10px;
    }
}

The white-space: nowrap on the button prevents the button text from wrapping. In the media query, the layout switches to a vertical stack on narrow screens.

Floating Validation Tips (Built-in Feature)

This is one of the least known features of CF7. By default, a validation error message appears below the field and pushes everything below it down, breaking the form layout.

CF7 includes a built-in solution – add the use-floating-validation-tip class to the form shortcode:

[[contact-form-7 id="xxx" html_class="use-floating-validation-tip" title="My Form"]]

This makes error messages appear as floating tooltips next to the field instead of pushing the layout. The plugin itself has built-in CSS that handles the tooltip positioning.

Styling the Error Messages

You can change the appearance of error messages using the .wpcf7-not-valid-tip class:

.wpcf7-not-valid-tip {
    color: #e74c3c;
    font-size: 13px;
    font-weight: 400;
}

.wpcf7 .wpcf7-not-valid {
    border-bottom-color: #e74c3c;
}

The .wpcf7-not-valid class is automatically added to fields that fail validation. You can use it to mark them with a red border.

Styling Response Messages After Submission

Something many don’t realize – CF7 adds different classes to the form element itself based on the submission status. You can use these to create different styles for each state:

  • .wpcf7-form.sent – Submission succeeded
  • .wpcf7-form.invalid – Validation errors exist
  • .wpcf7-form.spam – Detected as spam
  • .wpcf7-form.failed – Submission failed

For example, to style the success message differently from the error message:

.wpcf7-form.sent .wpcf7-response-output {
    border-color: #27ae60;
    color: #27ae60;
    background: rgba(39, 174, 96, 0.05);
}

.wpcf7-form.invalid .wpcf7-response-output {
    border-color: #e74c3c;
    color: #e74c3c;
    background: rgba(231, 76, 60, 0.05);
}

Hiding the Form After Successful Submission

An advanced tip – you can hide all form fields after a successful submission and show only the success message:

.wpcf7-form.sent .wpcf7-form-control-wrap,
.wpcf7-form.sent .wpcf7-submit {
    display: none;
}

.wpcf7-form.sent .wpcf7-response-output {
    text-align: center;
    font-size: 18px;
    padding: 20px;
    margin-top: 0;
}

All of this is done with CSS only, no JavaScript needed.

Styling Checkboxes and Radio Buttons

CF7 wraps each checkbox and radio button in a <span> with the class .wpcf7-list-item. You can use this to create a custom look:

.wpcf7 .wpcf7-list-item {
    display: block;
    margin: 8px 0;
}

.wpcf7 .wpcf7-list-item label {
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
}

Customizing the Spinner (Loading Animation)

After clicking the submit button, CF7 displays a spinner. You can change its appearance or hide it entirely:

.wpcf7-spinner {
    display: none;
}

Or, if you want to change its position:

.wpcf7-spinner {
    position: absolute;
    margin: 0;
}

Additional Shortcode Tag Attributes

CF7 supports additional attributes in shortcode tags that not everyone knows about:

  • size:40 – Sets the visible width of the field
  • minlength:3 and maxlength:100 – Limits text length
  • autocomplete:name – Enables browser autocomplete
  • default:value – Sets a default value for the field

A combined example:

[text* your-name minlength:2 maxlength:50 autocomplete:name class:styled-input placeholder "Full Name"]

Using html_class and html_id in the Shortcode

You can add any class or ID to the form wrapper through the shortcode itself:

[[contact-form-7 id="xxx" html_class="my-form dark-theme" html_id="main-contact" title="My Form"]]

This allows styling each form uniquely when there are multiple forms on the site. For instance, a footer form can get a footer-form class with different styling from a contact page form.

FAQs

Common questions about styling Contact Form 7 forms:

Does Contact Form 7 include built-in design settings?
No. Contact Form 7 does not include a design interface. The forms inherit CSS styles from the active theme. All design customization is done by adding custom CSS to your child theme.
What does html_class="use-floating-validation-tip" do?
This is a built-in CF7 feature that makes field error messages appear as floating tooltips instead of being pushed below the field. It prevents the form layout from breaking when validation errors are displayed.
How do I add a custom CSS class to a specific CF7 field?
Add class:your-class-name directly in the field's shortcode tag. For example: [text* your-name class:my-input]. You can also add an ID using id:your-id in the same way.
How do I create a two-column CF7 form?
Wrap the fields in a div with a custom class in the CF7 editor, then use CSS Flexbox with flex-wrap: wrap and flex: 1 0 50% on each inner div. Add a media query to switch the fields to a single column on mobile.
Can I hide the form after a successful submission?
Yes. CF7 adds a .sent class to the form after a successful submission. You can use it in CSS to hide the form fields and display only the success message, with no JavaScript required.

Summary

Although Contact Form 7 does not include a design interface, it provides a predictable HTML structure with specific classes that allow full design customization through CSS. From built-in features like floating validation tips to dynamic classes that change based on submission status – there is much more here than meets the eye.

For more CF7 tips, check out the guide on optimizing CF7 for performance, and the explanation on redirecting to a different URL after form submission. It’s also recommended to protect your forms from spam using Akismet.

Join the Discussion
0 Comments  ]

Leave a Comment

To add code, use the buttons below. For instance, click the PHP button to insert PHP code within the shortcode. If you notice any typos, please let us know!

Savvy WordPress Development official logo