[forms] Multi column forms with fieldsets

Sorry for the vague title, I wasn't sure how to describe it better. I'm currently upgrading a website to bootstrap 3 and got a little problem with multiple inputs in one form row.

In bootstrap 2, I would have simply created two .controls.controls-row with .spanX elements inside to create the necessary columns. However, as these are removed in bootstrap 3, I replaced them with .form-group and the new column classes.

If I have two rows inside the form (resp. fieldset in this case), the first one becomes non-editable if the second one is a one-column row (see code and attached screenshot below).

I inspected the elements with firebug and saw that the .col-sm-12 from the second fieldset lays over the .form-group and does not let the user click the elements inside. In the first fieldset with the .col-sm-12 first, everything works fine.

I also tried placing a .row around each .form-group which solves the issue, but increases the width of the form line, so it does no longer has a left margin inside the fieldset.

Is there a way to solve this without increasing the form-row width?

Thanks in advance!

EDIT: I added the generated code as a jsFiddle

%fieldset
  %legend= t('.login_information')
  .form-group
    .col-sm-12
      = f.label :login
      = f.text_field :login, :class => 'form-control', :required => true

  .form-group
    .col-sm-6
      = f.label :password
      = f.password_field :password, :class => 'form-control'
    .col-sm-6
      = f.label :password_confirmation
      = f.password_field :password_confirmation, :class => 'form-control'

%fieldset
  %legend= t('.personal_details')
  .form-group
    .col-sm-4
      = f.label :title
      = f.text_field :title, :class => 'form-control'
    .col-sm-4
      = f.label :firstname
      = f.text_field :firstname, :class => 'form-control', :required => true
    .col-sm-4
      = f.label :lastname
      = f.text_field :lastname,  :class => 'form-control', :required => true

  .form-group
    .col-sm-12
      = f.label :email
      = f.text_field :email, :class => 'form-control email', :required => true

Non-editable form elements

This question is related to forms twitter-bootstrap-3

The answer is


There are a couple of things that need to be adjusted in your layout:

  1. You are nesting col elements within form-group elements. This should be the other way around (the form-group should be within the col-sm-xx element).

  2. You should always use a row div for each new "row" in your design. In your case, you would need at least 5 rows (Username, Password and co, Title/First/Last name, email, Language). Otherwise, your problematic .col-sm-12 is still on the same row with the above 3 .col-sm-4 resulting in a total of columns greater than 12, and causing the overlap problem.

Here is a fixed demo.

And an excerpt of what the problematic section HTML should become:

<fieldset>
    <legend>Personal Information</legend>
    <div class='row'>
        <div class='col-sm-4'>    
            <div class='form-group'>
                <label for="user_title">Title</label>
                <input class="form-control" id="user_title" name="user[title]" size="30" type="text" />
            </div>
        </div>
        <div class='col-sm-4'>
            <div class='form-group'>
                <label for="user_firstname">First name</label>
                <input class="form-control" id="user_firstname" name="user[firstname]" required="true" size="30" type="text" />
            </div>
        </div>
        <div class='col-sm-4'>
            <div class='form-group'>
                <label for="user_lastname">Last name</label>
                <input class="form-control" id="user_lastname" name="user[lastname]" required="true" size="30" type="text" />
            </div>
        </div>
    </div>
    <div class='row'>
        <div class='col-sm-12'>
            <div class='form-group'>

                <label for="user_email">Email</label>
                <input class="form-control required email" id="user_email" name="user[email]" required="true" size="30" type="text" />
            </div>
        </div>
    </div>
</fieldset>

I disagree that .form-group should be within .col-*-n elements. In my experience, all the appropriate padding happens automatically when you use .form-group like .row within a form.

<div class="form-group">
    <div class="col-sm-12">
        <label for="user_login">Username</label>
        <input class="form-control" id="user_login" name="user[login]" required="true" size="30" type="text" />
    </div>
</div>

Check out this demo.

Altering the demo slightly by adding .form-horizontal to the form tag changes some of that padding.

<form action="#" method="post" class="form-horizontal">

Check out this demo.

When in doubt, inspect in Chrome or use Firebug in Firefox to figure out things like padding and margins. Using .row within the form fails in edsioufi's fiddle because .row uses negative left and right margins thereby drawing the horizontal bounds of the divs classed .row beyond the bounds of the containing fieldsets.