Multi-Column Gravity Forms With CSS

Update 7/1/2016

For a better solution, check out our more recent article about multi-column Gravity Forms implementation: Revisited: Multi-Column Gravity Forms

There is no built-in way for the Gravity Forms plugin for WordPress to generate a true, multi-column form layout. However, this can easily be accomplished using a single filter hook and some accompanying CSS.

Occasionally, the mockups I’m using to build a WordPress site call for a multi-column form. Natively, Gravity Forms doesn’t support something likes this. Sure, they have what they call “CSS ready classes” for fields that will arrange form inputs in multiple columns when they’re ordered one right after the other. But what if the fields I want to appear side by side shouldn’t contextually be one right after the other?

From a user experience standpoint, it might make more sense to complete a form’s left column of fields before continuing on to the right column. You may be able to get away with using Gravity Form’s CSS ready classes to arrange them how you want but you wouldn’t be considering situations when the form has to go to a single column layout, such as for mobile devices. It’d really make more sense to group what you want to go in each column together so you may lay out each group side by side.

What We’re Working With

When looking at the HTML output by Gravity Forms, you’ll notice that all fields are organized into an unordered list with the class of .gform_fields:

<ul id="gform_fields_1" class="gform_fields top_label description_below">
 	<li id="field_1_1" class="gfield"><label class="gfield_label" for="input_1_1">Field 1</label>
<div class="ginput_container"><input id="input_1_1" class="medium" tabindex="1" name="input_1" type="text" value="" /></div></li>
 	<li id="field_1_2" class="gfield"><label class="gfield_label" for="input_1_2">Field 2</label>
<div class="ginput_container"><input id="input_1_2" class="medium" tabindex="2" name="input_2" type="text" value="" /></div></li>
 	<li id="field_1_3" class="gfield"><label class="gfield_label" for="input_1_3">Field 3</label>
<div class="ginput_container"><textarea id="input_1_3" class="textarea medium" tabindex="3" cols="50" name="input_6" rows="10"></textarea></div></li>

The most logical way of splitting the third field off from the first two would be to separate it into its own list. If we can get the form’s fields to be organized into two separate lists, we could specify them to float left to get a two column layout while still being able to easily revert to a stacked layout for narrower devices.

Splitting the Columns

In order to split the fields list, first we’ll need to designate where we want these splits to occur. This can be achieved by adding special section break elements to our form using the form editor. We can mark these as column breaks by adding a special class to these section breaks, such as .gform_column. For example, for a two column layout, we’d have a section break as the first form field and another section break wherever we need the right column’s field to start. It’s also a good idea to specify the type of layout the form will take on by providing a class to the form itself, such as .two-column. Not only will we use these classes for styling the columns via CSS, we will use these classes to selectively target the correct column break points when generating the form’s HTML.

Using Gravity Forms’ gform_field_content filter hook, we can add the breaks to the unordered list to designate column breaks:

function gform_column_splits($content, $field, $value, $lead_id, $form_id) {
if(IS_ADMIN) return $content; // only modify HTML on the front end

$form = RGFormsModel::get_form_meta($form_id, true);
$form_class = array_key_exists('cssClass', $form) ? $form['cssClass'] : '';
$form_classes = preg_split('/[\n\r\t ]+/', $form_class, -1, PREG_SPLIT_NO_EMPTY);
$fields_class = array_key_exists('cssClass', $field) ? $field['cssClass'] : '';
$field_classes = preg_split('/[\n\r\t ]+/', $fields_class, -1, PREG_SPLIT_NO_EMPTY);

// multi-column form functionality
if($field['type'] == 'section') {

// check for the presence of multi-column form classes
$form_class_matches = array_intersect($form_classes, array('two-column', 'three-column'));

// check for the presence of section break column classes
$field_class_matches = array_intersect($field_classes, array('gform_column'));

// if field is a column break in a multi-column form, perform the list split
if(!empty($form_class_matches) &amp;&amp; !empty($field_class_matches)) { // make sure to target only multi-column forms

// retrieve the form's field list classes for consistency
$ul_classes = GFCommon::get_ul_classes($form).' '.$field['cssClass'];

// close current field's li and ul and begin a new list with the same form field list classes
return '
<ul class="'.$ul_classes.'">
 	<li class="gfield gsection empty">';}
}return $content;
add_filter('gform_field_content', 'gform_column_splits', 10, 5);

Note how we’ve added the field’s CSS class to the new <ul>. This will allow us to target that list for applying a CSS float.

After this filter is applied, we should end up with something like this:

<ul id="gform_fields_1" class="gform_fields top_label description_below">
 	<li id="field_1_1" class="gfield gsection gform_column"></li>
<ul class="gform_fields top_label description_below gform_column">
 	<li class="gfield gsection"></li>
 	<li id="field_1_2" class="gfield"><label class="gfield_label" for="input_1_2">Field 1</label>
<div class="ginput_container"><input id="input_1_2" class="medium" tabindex="1" name="input_2" type="text" value="" /></div></li>
 	<li id="field_1_3" class="gfield"><label class="gfield_label" for="input_1_3">Field 2</label>
<div class="ginput_container"><input id="input_1_3" class="medium" tabindex="2" name="input_3" type="text" value="" /></div></li>
 	<li id="field_1_4" class="gfield gsection gform_column"></li>
<ul class="gform_fields top_label description_below gform_column">
 	<li class="gfield gsection"></li>
 	<li id="field_1_5" class="gfield"><label class="gfield_label" for="input_1_5">Field 3</label>
<div class="ginput_container"><textarea id="input_1_5" class="textarea medium" tabindex="3" cols="50" name="input_5" rows="10"></textarea></div></li>

We’ve successfully split the third field into it’s own list!

Column Styling

Now that we have the fields we want grouped together in separate lists, we can style the form so both of these groups appear side by side. The actual CSS will vary from project to project, depending on the site’s design, but this would be one way of accomplishing the two-column layout:

.gform_wrapper.two-column_wrapper ul.gform_fields {
display: none;
.gform_wrapper.two-column_wrapper ul.gform_fields.gform_column {
display: block;
float: left;
width: 50%;
.gform_wrapper.two-column_wrapper ul.gform_column li.gsection:first-child {
display: none;

The first style definition hides the unecessary field list at the beginning of the form by hiding all .gform_fields lists. The next definition overrides the previous just for .gform_column lists. The final style definition hides the empty <li> elements at the beginning of each column list.

We now have a multi-column form that can easily be restructured into a single column while keeping each column’s fields grouped together!


  1. This is awesome! Very useful. Thanks, Jordan.

    For anyone else reading this, you can enable multiple column sizes by adding a new item to the $field_class_matches array and then update the CSS.

    $field_class_matches = array_intersect($field_class, array('gform-column', 'gform-one-column'));

    .gform_wrapper.two-column_wrapper ul.gform_fields.gform-one-column {
    display: block;
    float: left;
    width: 100%;

    1. Excellent point! That was my intention of comparing class matches with a list of class names instead of just one.

      However it might make more sense to define the number of columns at the form level by assigning a custom class to the form itself and adding that class to the list of valid form classes:

      $form_class_matches = array_intersect($form_class, array('two-column', 'three-column'));
  2. Thank you for this tutorial! I have been trying to figure this out.

    In that vain, I can’t get the code as presented to work. I’m sure it’s because I didn’t put the proper info into my form settings of my form. In my section breaks, I have the css classname of “gform_column” – is that incorrect? Do I need to set a style name for the form itself too?

  3. Sorry for jumping the gun; I figured it out. Was missing “two-column” as my form class.

  4. Thanks for the post, this was very helpful. I had struggled by trying to do floats on individual fields–this is much better.

  5. Thanks for the great post. I have tried it but it doesn’t really work for me. First of all the structure of my Gform looks a bit different, because I want the first form fields to appear in just one column and then add the section break to format all the fields after the break as two columns with float. However, if I split my form, only the fields before the split are being submitted.

    Secondly, I was wondering if this function does also work with the honeypot anti-spam field that adds the gform validation wrapper at the end?

    1. Hey Tim, are you sure you’re injecting the correct opening/closing HTML tags with the gform_field_content filter. That’s the only thing I can think of that would cause an entire column to not show up.

      I haven’t tested the honeypot anti-spam Gravity Forms addition myself but I don’t see how this would affect it at all.

  6. Thanks for the information/tutorial. Much appreciated and very helpful.

  7. Any way to give the second column it’s own div name? For example, both columns are called “gform_column” i’d like the left one to be “gform_column1” and the right one to be “gform_column2” so that I can style each of them separately. is this possible?

  8. Hi there excelent tutorial, but im having trouble getting it to work. Im adding the function in the functions.php of my child theme but it doesn´t seem to work. is that the only thing i have to do or do i have to set an especific class to the form itself and/or to the section break field? heres is a link of where im testing it:

    thanx in advance for the help!

    1. nevermind, i think i got it to work. but one question about what greg ad it, do i have to add that line of code to the function or replace it for the one in this tutorial? thanx again

      1. That line Greg added would replace the one included from the tutorial.

  9. Hi there!

    Great post 🙂 , but I found something easier I think.
    GF comes with a set of CSS classes for doing what you’re explaining
    Try to fill in the class blanket of every field with this class “gf_left_half” or “gf_right_half” depending on what field you want to float left or right.

    Read this:

    Hope it helps somebody!

    1. I mentioned the CSS ready classes in the opening paragraphs but their capability is limited. With those, all you can do is float individual fields left and right, not entire groups of fields.

  10. This did not work, after fixing three of the errors it posted in the log I gave up on it, hopefully Gravity Forms releases CSS for this in the future.

  11. This looks great to me, but for some reason the php just turns my form into a blank page. From a cut n’ paste attempt, I found that the &amp’s in the php needed to be replaced with &&, if that’s any help to anyone. And I found that my problem seems to be with the opening/closing HTML tags as Cameron already pointed out. My form doesn’t go blank if if I just use return’ ‘; instead of trying to return the the desired HTML. I also noticed that if I include /li and /ul tags in the return’ ‘ statement that the form page doesn’t go blank. But then the HTML markup is not showing any of the desired changes either. Sorry that this site I’m working on is not live. Any ideas?? Thanks

    1. The formatting of that code snippet got screwed up, it should be correct now though. Have you tried enabling debug mode on your site?

  12. Thanks Cameron, I always just use the CSS styling to target the individual fields in the form or groups of fields to make things float where I want them too. Like in these videos:

    But I can see how this method of splitting into different lists can be very useful and cut down on the amount of CSS styling necessary.

    Cheers, Neil

  13. Great tutorial! Customizations like this is exactly why we build things in such a way that 3rd party developers can customize Gravity Forms behavior.

    The ability to create multi-column forms directly within the Form Editor is a feature that we do plan on tackling in the future.

    We have already laid the groundwork that we needed to put in place within Gravity Forms v1.9 which was just released as a beta last weekend:

    With the changes we’ve made under the hood we’ll be able to tackle this functionality as a WYSIWYG feature of the Form Editor in a future feature version release.

  14. Depending on the situation something like this can work very nicely:

    #gform_fields_1 .gfield:nth-child(odd) {
    width:47.5%; margin-right:5%; display:inline-block;
    #gform_fields_1 .gfield:nth-child(even) {
    width:47.5%; display:inline-block;

    You will also probably have to target the different types of inputs to get their widths just right:
    #gform_wrapper_1 select { width:102%; }

    And you can target particular pieces for exceptions like, say you want the textarea to be 100% and not columnized.

  15. Hi,
    I’m trying to get the submit button appearing within the second column rather than outside the two columns.
    Any hints appreciated 🙂


    1. There’s no way to easily move the submit button to within the second column of fields, but you should be able to give the .gform_footer a left margin of the same percentage as the width of your field columns. That way, the submit button should line up that second column in your form.

      1. Thanks Cameron, the nature of this responsive form is the height of the columns change which can put the submit in some strange places for different devices as it has to clear both the columns.

        What I have worked as the best solution is keeping the right column slightly shorter than the left so the submit button sits up against the left column until the form breaks into the single column media query.

        Definitely not eloquent, but seems consistent.

  16. Hi there, the rendering you’re using for the code blocks is fantastic – what plugin/library are you using for that?

    Great post by the way!

  17. Hello,
    Nice plugin, however I think it may have broken my form where there is a list of checkboxes?

    1. It shouldn’t have, what does the HTML around your checkboxes look like? Are there any missing tags?

        1. That shouldn’t make a difference as long as your tags are properly closing and the additional CSS isn’t targeting those lists.

  18. Hi there, great tutorial. I was wondering if there´s a way to do something like this but as a container in which i could wrap all columns into one or multiple wrappers. Like if i have 5 columns with 4 fields each and i would like to wrap two columns in one div and other three in another div. Do you get what i mean?

  19. This was a great approach. I’m glad they have taken notice to add this in the future. I just upgraded to 1.9 and now this code is throwing me notices. Any thoughts on how to adjust the code? In any case, maybe they will add support soon. This is the notice I now receive with 1.9, I have debug on:

    Notice: GFFormsModel::add_default_properties is deprecated since version 1.9 with no alternative available.

  20. Great snippet! This code suddenly stopped working on my site. Not sure if the reason was updating to Gravity Forms 1.8.22 or installing a Gravity Form Add-Ons, but changing the filter priority solved it.

    add_filter('gform_field_content', 'gform_column_splits', 10, 5);

    add_filter('gform_field_content', 'gform_column_splits', 100, 5);

  21. First Off, Thanks for the great tutorial. I think this tutorial would be more helpful if we could see the form back end. Took me a while to figure out what was wrong.

  22. Cannot get it to work. First section break is hidden, but second appears and yet html and css look right. ????

    1. the problem was Elegant Themes (not) Divi theme gives a default padding style to on pages you don’t use their drag and drop “Page Builder” with. was driving me crazy.

      also, gravity forms adds a border to section breaks, so you need to add:

      .two-column_wrapper li.gsection { border: 0; }

      to get rid of it.

  23. so how would this work if i want some to be in two columns and other parts of the form to be in one column? thanks!

  24. well, i managed to get one, two and three columns in one form with pretty small changes.

    in gform_column_splits:
    ` $form_class_matches = array_intersect($form_class, array(‘multi-column’));

    // check for the presence of section break column classes
    $field_class = explode(‘ ‘, $field[‘cssClass’]);
    //$field_class_matches = array_intersect($field_class, array(‘gform_column’));
    $field_class_matches = array_intersect($field_class, array(‘gform_one-column’, ‘gform_two-column’, ‘gform_three-column’));

    multi column capability of gravity forms
    .gform_wrapper.multi-column_wrapper ul.gform_fields.gform_one-column {
    display: block;
    float: left;
    width: 100%;
    .gform_wrapper.multi-column_wrapper ul.gform_fields.gform_two-column {
    display: block;
    float: left;
    width: 50%;
    .gform_wrapper.multi-column_wrapper ul.gform_fields.gform_three-column {
    display: block;
    float: left;
    width: 33%;
    .gform_wrapper.multi-column_wrapper ul.gform_one-column li.gsection:first-child,
    .gform_wrapper.multi-column_wrapper ul.gform_two-column li.gsection:first-child,
    .gform_wrapper.multi-column_wrapper ul.gform_three-column li.gsection:first-child
    .gform_wrapper.multi-column_wrapper ul.gform_fields li.empty,
    .gform_wrapper.multi-column_wrapper ul.gform_fields li.gform_one-column,
    .gform_wrapper.multi-column_wrapper ul.gform_fields li.gform_two-column,
    .gform_wrapper.multi-column_wrapper ul.gform_fields li.gform_three-column
    display: none;
    .multi-column_wrapper li.gsection { border: 0; }
    .gform_wrapper textarea { width: 97.5%; } /* make it fit a column */

  25. Hi,

    Great work, but from some reason when applying this fix, it makes my all form disapear, I understand its because of the display : none, but I wonder why its there, and how do I make my form to work ?

  26. Can anyone confirm this is working with latest 1.9.5 GF ? cant get it working.. it dont split Columns not even Sections into ul`s…

  27. This is so useful – and just what I was looking for. Thank you so much for sharing this advice.

  28. I get the following error:

    Warning: array_key_exists() expects parameter 2 to be array, null given in /home2/hifivpub/public_html/premierdev/wp-content/plugins/gf-break/gf-break.php on line 12

    1. Line 12 in my code (I put it into a plugin rather than my functions.php):

      $form_class = array_key_exists('cssClass', $form) ? $form['cssClass'] : '';

    2. Sorry about that, I had a mis-named variable in my code snippet ($form_id). It should be fixed now!

  29. I’ve tried and failed with this – I was not able to create multiple

    I’ve given my form the class “two-column” and created divs of class “gform_column” but no joy.

    My divs just appearing in-line within the single UL as if the function is not having any effect?

    Am I missing something basis ?


  30. Thank you so much for this. It was the only tutorial I found that actually worked. I needed two true columns so I could wrap one in special formatting (in addition to the contextual issue you mentioned). The CSS Ready Classes weren’t cutting it.

  31. Thanks for this smart solution, it works on latest version as of today. Wish this was in gravity forms to begin with! The css ready classes are really clunky and wouldn’t work in this scenario anyways, as you pointed out.

  32. How do you break the last column if you need another single column below the two-column or three-column? because when you add another section after the last column it goes inside the last column and not in the new line.

    1. You should be able to split up the form into as many column groups as you’d like, you’ll just need to style the final group to clear the columns above and span the full width of the container.

  33. Awesome – received a mockup with this layout and was about to work out how to do this. You have saved me a whole lot of work! Thank you for making it available.

  34. This tutorial is excellent, thank you so much.

    If I can offer one suggestion: I’d love to see a few screenshots of your WP-admin views.

    The first few times I read this, I skimmed too quickly and missed the “add .two-columns to your your form classes.”

    Definitely my fault for not reading closely enough.

    But in case anyone else makes the same mistake, a few screenshots like this would be a huge help:

    Thanks again for writing this up. A total lifesaver.


Get a Quote

  • Contact Information

  • Project Details

  • Accepted file types: doc, pdf, Max. file size: 50 MB.