Using Gravity Forms with Bootstrap Styles

I use Bootstrap as a starting point for a lot of the themes that I build as a great starting point for reusable components. But one of the problems I’ve run into is trying to integrate Gravity Forms with Bootstrap. By default, Gravity Forms does not include Bootstrap classes, so the two don’t end up working very well together.

Fortunately, with a little bit of elbow grease, there’s a way to tweak Gravity Forms markup and styles to match a default Bootstrap form. The solution I’ve found is a combination of a single hook and some SASS / CSS tweaks to get everything off the ground.

For reference, a typical Bootstrap form should be marked up something like this:

<form>
  <fieldset class="form-group">
    <label for="formGroupExampleInput">Example label</label>
    <input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input">
  </fieldset>
  <fieldset class="form-group">
    <label for="formGroupExampleInput2">Another label</label>
    <input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input">
  </fieldset>
<button type="submit" class="btn btn-primary">Submit</button>
</form>

I’m using version 4 of Bootstrap, but things are pretty much the same in older versions of Bootstrap as well. There are really two things that are important in this markup. The first is that a class of form-group is used on an input’s wrapper element (fieldset in this case). The second is that a class of form-group is added to each input. Cool, let’s step through this.

The first step is to wrap inputs in an element with a class of form-group then. That’s actually pretty simple. There’s a Gravity Form filter called gform_field_container that can be used to change the markup of the list item for each input. So all we have to do is ensure that the form-group class is added here, which we can do with a simple one-line function:

add_filter( 'gform_field_container', 'add_bootstrap_container_class', 10, 6 );
function add_bootstrap_container_class( $field_container, $field, $form, $css_class, $style, $field_content ) {
  $id = $field->id;
  $field_id = is_admin() || empty( $form ) ? "field_{$id}" : 'field_' . $form['id'] . "_$id";
  return '<li id="' . $field_id . '" class="' . $css_class . ' form-group">{FIELD_CONTENT}</li>';
}

Now each input will be wrapped in the proper form-group class, along with any classes Gravity Forms wants to add.

The second part, adding a form-group class to every input element, is a little trickier. There are actions that let you edit the actual markup of inputs, but there’s nothing that just lets you filter input classes, which means you’ll end up rewriting the entire input function. Things get complicated fast, and I just haven’t found that to be a very smart way to go. Here’s the solution I’ve found works best: Instead of adding Bootstrap classes to Gravity Forms, we customize Gravity Forms classes to match Bootstrap classes.

If you’re using SASS, this is super easy thanks to @extend, which allows you to apply styles from one class to another. So we just need to extend Bootstrap styles to the Gravity Form’s CSS. Which looks like this:

.gform_fields {
  @extend .list-unstyled;
  @extend .row;
 
  input, select, textarea {
    @extend .form-control;
  }
 
  textarea {
    height: auto;
  }
 
}
 
.gfield_description {
  @extend .alert;
}
 
.validation_error {
  @extend .alert;
  @extend .alert-danger;
}
 
.validation_message {
  @extend .alert;
  @extend .alert-success;
}
 
.gform_button {
  @extend .btn;
}
 
.gfield_required {
  color: $alert-danger-text;
}
 
.gform_wrapper ul.gfield_radio li, .gform_wrapper ul.gfield_checkbox li {
  @extend .form-check;
}
 
.gform_validation_container {
  display: none;
}
 
.gfield_error .ginput_container {
  margin-bottom: 10px;
}

This will apply the styles from Bootstrap classes to the proper elements inside of Gravity Forms and make everything look just as it should. You may need to tweak a bit here and there on individual elements but this tends to get things working pretty well.

Looking for the fully compiled, vanilla CSS version of this? I set up a gist for you to drop into your project.

Note: Updated on August 22, 2016. Thanks to Josh Cranwell for some much-needed additions!

17 Comments

  1. Hi there, congrats for great article.

    I wasn’t able to make it work, I’m unfamiliar with this SASS. I don’t think I’m able to use it. Should I just add CSS on the theme options for example?

    Did you guys tried to use the Boostrap Style on inputs like this example with URL Address? I’m unable to reproduce it on my website. :/
    http://v4-alpha.getbootstrap.com/components/input-group/

    Cheers!

    1. Unfortunately, to do it the way I’m proposing requires SASS for now. I’m thinking about publishing a compiled version of that CSS here as well.

      “Did you guys tried to use the Boostrap Style on inputs like this example with URL Address?”
      — The problem with this is Gravity Forms doesn’t let you edit the styles of the inputs themselves, just the style of the wrapper element. So there’s no way to apply the default Bootstrap styles, which means you have to take Bootstrap CSS and apply it to default Gravity form classes.

      1. I would really love to see the CSS without sass! Currently using some bootstrap 3 classes but it’s fairly outdated.

  2. I had edited your filter function to switch out the field sizes using Bootstrap’s columns for my form, and found that it was replacing the classes of my admin-side Gravity Forms editor. So I added a check to make sure that the admin side always displays exactly what Gravity Forms expects:

    https://gist.github.com/rynokins/8089d4d5641edd11fe09cbc50765df7c

    (I’m doing all my gform class overrides in SASS with Bootstrap loaded locally, in case you’re wondering why I removed the ‘form-group’ class)

    Thanks for your post – really helped me out!

  3. Overall, the SCSS stuff works reasonably well, but with the `add_bootstrap_container_class` hooked in, I found that conditional logic on the form stopped working completely. Took a moment to work out what had borked it.

Leave a Reply