I started looking into Bootstrap to make my forms responsive. I want to generate them from a data source and place each control on the page, using all the space. I got something that resemble what I want, with a responsive design, but I am using class="row", which gives me some white spaces when the divs have different heights on the same row. Is it possible to use something else that would remove those, while, if possible, staying with aligned controls that removes most of the white space?
This is the full code I am using for my tests:
<html>
<head>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<br/>
<div class="row">
<div class="form-group col-sm-6 col-lg-4 col-xl-3">
<label for="name" class="col-sm-2 control-label">Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="name" name="name" placeholder="First & Last Name" value="">
</div>
</div>
<div class="form-group col-sm-6 col-lg-4 col-xl-3">
<label for="email" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="email" name="email" placeholder="example#domain.com" value="">
</div>
</div>
<div class="form-group col-sm-6 col-lg-4 col-xl-3">
<label for="message" class="col-sm-2 control-label">Message</label>
<div class="col-sm-10">
<textarea class="form-control" rows="4" name="message"></textarea>
</div>
</div>
<div class="form-group col-sm-6 col-lg-4 col-xl-3">
<label for="human" class="col-sm-2 control-label">2 + 3 = ?</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="human" name="human" placeholder="Your Answer">
</div>
</div>
<div class="form-group col-sm-6 col-lg-4 col-xl-3">
<label for="name" class="col-sm-2 control-label">Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="name" name="name" placeholder="First & Last Name" value="">
</div>
</div>
<div class="form-group col-sm-6 col-lg-4 col-xl-3">
<label for="email" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="email" name="email" placeholder="example#domain.com" value="">
</div>
</div>
<div class="form-group col-sm-6 col-lg-4 col-xl-3">
<label for="message" class="col-sm-2 control-label">Message</label>
<div class="col-sm-10">
<textarea class="form-control" rows="4" name="message"></textarea>
</div>
</div>
<div class="form-group col-sm-6 col-lg-4 col-xl-3">
<label for="human" class="col-sm-2 control-label">2 + 3 = ?</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="human" name="human" placeholder="Your Answer">
</div>
</div>
<div class="form-group col-sm-6 col-lg-4 col-xl-3">
<label for="name" class="col-sm-2 control-label">Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="name" name="name" placeholder="First & Last Name" value="">
</div>
</div>
<div class="form-group col-sm-6 col-lg-4 col-xl-3">
<label for="email" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="email" name="email" placeholder="example#domain.com" value="">
</div>
</div>
<div class="form-group col-sm-6 col-lg-4 col-xl-3">
<label for="message" class="col-sm-2 control-label">Message</label>
<div class="col-sm-10">
<textarea class="form-control" rows="4" name="message"></textarea>
</div>
</div>
<div class="form-group col-sm-6 col-lg-4 col-xl-3">
<label for="human" class="col-sm-2 control-label">2 + 3 = ?</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="human" name="human" placeholder="Your Answer">
</div>
</div>
</div>
</div>
</body>
</html>
You can see some whitespace here on the 1st row (left of Message label), as the Message Div has a different height.
You can also see this strange whitespace on the 3rd row, where a complete column is empty. It seems to happen when the label on top of it has a second line (2+3=? where the ? appear on a second line). If I drag the window large enough so the label is on one line, the problem is gone. Still, that will happen and I don't want it to create problems.
This one is not related to the whitespace (an extra problem). I need to be able to resize my text area, and the resize operation should move the other divs out of the way, instead of letting them on top of the current text area... This already works when I drag the area to the bottom (down), but not to the right.
Would you have an idea on how I could resolve the problems listed above (bullet points) ?
UPDATE
For the screen above, the way I would like it to be shown (the order of the items could differ) is indicated in the following screen. As you can see, I would like things to stay aligned in rows while reducing the white space. The smaller items are combined in the same column of the same row to fit the empty space, just like a row could have nested rows for a specific column. Still, if two smaller items cannot fit inside the space, it should not be placed there, as I want to keep lines of content. As an example, if "name" and "email" cannot fit in the height of "message", then I should have the same layout as before ("name, email, message" only, in the 1st row). The number and types of items are variables (depending on the form). Also, it is important that the form stays responsive to screen size changes and vertical resizes (it is right now), so if I lower the size or enlarge a text area, the number of columns still need to change and the same kind of layout should be seen with less columns.
I would also add that my items (whatever the type) need to be shown like this:
["centered label" "input field"]
They can then be stacked, still keeping the same absolute order (most of it at least). The important part is that I need groups for those items, that include a responsive label and input.
UPDATE2
This is another picture that represent the same problem. I used the same code as before but with some other controllers. I marked the spots where the whitespace should not be present with red arrows. This time the form items's html was generated from a data source (which represent my goal).
For your first problem you could use <div class="clearfix"> in between each three form-groups. clearfix will clear the spacing and reset on the next row. This solution will also help your second problem. If you also want this to work on sm and xl make use of different .clearfix divs which will hide on the specific browser like so: <div class="clearfix hidden-sm"></div>.
http://www.bootply.com/KxONBlaNXJ
You can see some whitespace here on the 1st row (left of Message label), as the Message Div has a different height.
The main cause of the spacing issues have to do with the differing heights of your div.form-groups.
Example: In your screenshot, the height of the "first row" is pretty much defined by the height of the message div.
Masonry.js is one way about this - refer to this previous question for a nice visual made by the original poster on what Masonry can do (as well as link to Masonry).
You can also see this strange whitespace on the 3rd row, where a complete column is empty. It seems to happen when the label on top of it has a second line (2+3=? where the ? appear on a second line). If I drag the window large enough so the label is on one line, the problem is gone. Still, that will happen and I don't want it to create problems.
That nitpicky 2+3=? is indeed "claiming" that space as you have it now, thus pushing the next div over an entire column. So another height issue and as mentioned above, Masonry is another way about this.
This one is not related to the whitespace (an extra problem). I need to be able to resize my text area, and the resize operation should move the other divs out of the way, instead of letting them on top of the current text area... This already works when I drag the area to the bottom (down), but not to the right.
I can point you to this bootply example which shows how you can disable resize.
To your points, when you drag "down", the height adjusts and the following divs react accordingly (similar theme as above). You can drag right because you've applied col-sm-6 col-lg-4 col-xl-3... i.e. the widths are controlled via Bootstrap and you can't change that by simply dragging a textarea.
Edit - I just noticed #CBroe's comment and I like that CSS only solution. The only word of caution is I probably wouldn't directly modify the bootstrap -col- classes. I would simply apply a new class name and play from there :)
You have col-*-* in both the outline <div> and the label - is the nesting intentional? If so, then the child nest needs it's own .row... see http://getbootstrap.com/css/#grid-nesting
Use col-*-* in the <input> & <textarea> to assign widths... see http://getbootstrap.com/css/#form-control-column-sizing, scroll down to Column sizing
Related
Using bootstrap 3.3 and angular here.
I am trying to create a search filter above my grid but having some alignment issues. In full page I can see them aligned correctly, but when I try to resize the page all my form controls get jumbled up and down. I believe these is some css class which is missing but cant seem to figure out what is that. Could anyone point me in right direction.
I also created a stackblitz demo here at:
https://angular-datrange-enhq8w.stackblitz.io/
If you resize the window you would see what I am talking about.
Here is the stackblitz editor for this:
https://stackblitz.com/edit/angular-datrange-enhq8w
Below is some relevant code:
<div id="filters">
<form [formGroup]="filtersForm" >
<div class="row padding-top-10">
<div class="col-xs-12 col-sm-12 col-md-1 col-lg-1 form-group" style="margin-right:65px">
<label for="name">Name</label>
<input formControlName="name" name="name" type="text" style="height:33px" autocomplete="off" class="hidden-xs hidden-sm" />
</div>
</div>
</form>
</div>
Also on side note if you see the demo somehow I feel my dropdown does has the right style, is there some extra bootstrap 3 style I can add for this.
Thanks for looking into.
Anyone for inputs?
The grid system for bootstrap states that every row must be wrapped by a container class.
<div id="filters">
<form [formGroup]="filtersForm">
<div class="container-fluid">
<div class="row padding-top-10">
<div class="col-xs-12 col-sm-12 col-md-1 col-lg-1 form-group" style="margin-right:65px">
<label for="name">Name</label>
<input formControlName="name" name="name" type="text" style="height:33px" autocomplete="off"
class="hidden-xs hidden-sm" />
</div>
</div>
</div>
</form>
</div>
This does not solve the issue of changing the size. The bootstrap grid system is setup like this: For every row, there are 12 columns. What you are saying is that for the div with the class col-xs-12, make the element in that class have a width of 100% when the screen size is extra small. You are also saying that when it hits the col-md-1 (medium screen size breakpoint), it should have a width of 8.3333%. You have 6 divs in that page you provided. Since you have 6 divs, 12 columns / 6 divs = 2 columns per div. Therefore your code should be refactored to something like this:
<div id="filters">
<form [formGroup]="filtersForm">
<div class="container-fluid">
<div class="row padding-top-10">
<div class="col-xs-12 col-md-2 form-group" style="margin-right:65px">
<label for="name">Name</label>
<input formControlName="name" name="name" type="text" style="height:33px" autocomplete="off"
class="hidden-xs hidden-sm" />
</div>
</div>
</div>
</form>
</div>
Notice how I removed col-sm-12.. this is because col-xs-12 will set the width for every screen size up to the next given class. In this case you have col-xs-12, therefore when the screen size is xs and sm, it'll have a width of 100%. When it hits the md breakpoint, it'll change the width to 2/12 and have the same width for lg and xl screen sizes.
Check out bootstrap grid system.
The base syntax is:
container | container-fluid
row
columns (the total of col must be 12)
Also, there is no need of aditional margins on your col divs.
<div id="filters">
<form class="container-fluid">
<div class="row padding-top-10">
<div class="col-xs-12 col-md-2">
<div class="form-group">
<label for="name">Name</label>
<input formControlName="name" name="name" type="text" autocomplete="off" class="form-control" />
</div>
</div>
<div class="col-xs-12 col-md-2">
<div class="form-group">
<label for="age">Age Range</label>
<select class="form-control" formControlName="age">
<option [selected] value="">All</option>
<option *ngFor="let age of ages" value='{{age}}'>
{{age}}
</option>
</select>
</div>
</div>
</div>
</form>
</div>
If you want to persist all columns in a single row even on small screens, remove col-xs-12 and change col-md-2 to col-xs-2.
I'm trying to figure out how I can get labels in my form to be maintained all on one line. That is if a label for a specific input happens to be longer than the rest, I would like the other labels to have additional white space underneath such that my input fields are in alignment. See picture for alignment issue.
<div class="row">
<div class="form-group col-xs-12 col-sm-3 col-md-3 col-lg-3">
<label>Window Utilization Total:<span class="input-required" ng-show="logbook.util.$error.required">*</span></label>
<input name="util" ng-model="sortie.total_window_time" empty-to-null required type="text" title="Time: e.g. 01:00, 12:30, 23:59, etc" maxlength="5"
placeholder="00:00" pattern="^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$"/>
<p class="input-error" ng-show="logbook.util.$invalid && logbook.util.$touched">
Invalid time (e.g. 12:00, 23:59, 1:30, etc).
</p>
</div>
<div class="form-group col-xs-12 col-sm-3 col-md-3 col-lg-3">
<label>Flight Plan:</label>
<input ng-model="sortie.flight_plans" empty-to-null type="text" placeholder="e.g. NMZSAN_FP509"/>
</div>
<div class="form-group col-xs-12 col-sm-3 col-md-3 col-lg-3">
<label>Partial Flight Plans (Lines Completed):</label>
<input ng-model="sortie.partial_flight_plan" empty-to-null type="text" placeholder="e.g. NMZSAN_FP509, Lines 1-5"/>
</div>
<div class="form-group col-xs-12 col-sm-3 col-md-3 col-lg-3">
<label>Date of Last Control:</label>
<input ng-model="sortie.last_control_date" empty-to-null type="text" placeholder="YYYY-MM-DD"/>
</div>
</div>
If you want an all-css approach, it's going to be tricky. Someday, grid layout will make this sort of thing easy, but it has terrible support right now.
However, you could use flex-box to help you.
I think it will work if you have two rows, one for labels and one for the inputs.
<style>
div { display: flex }
label, input { flex: 1 }
</style>
<div>
<label for="1">Short</label>
<label for="2">Also Short</label>
<label for="3">So long ohmygoodness so much to say</label>
</div>
<div>
<input id="1"/>
<input id="2"/>
<input id="3"/>
</div>
Here's a jsfiddle to demonstrate it.
Note that flexbox support is not yet perfect, and you should add some browser-specific prefixes and be aware of its limitations. Read more at caniuse.com. If you need support for older versions of IE, it looks like you'll have to use a javascript fallback as indicated in the other answer here.
Just add this js code in your file, what this will do, it will equalize all the label height based on the height of biggest label as per its content/text.
Add class label_big to all the label elements
This works for me very well, hope it will resolve your issue.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(document).ready(function(){
var highestBox = 0;
$('.form_group .label_big').each(function(){
if($(this).height() > highestBox){
highestBox = $(this).height();
}
});
$('.form_group .label_big').height(highestBox);
});
</script>
I have 3 columns in my form for inputting the user's phone:
<div class="col-md-5">
<label class="control-label">Phone</label>
<div class="row">
<div class="col-md-4">
<label for="phone_code" class="sr-only"><fmt:message key="phoneCode"/></label>
<select class="form-control" name="phoneCode" id="phone_code">
<option value="1">1</option>
<option value="2">2</option>
</select>
</div>
<span class="col-md-2 text-center">-</span>
<div class="col-md-6">
<label for="phone_number" class="sr-only">phone number</label>
<input type="tel" class="form-control" name="phoneNumber" id="phone_number" dir="LTR" value="${phoneNumber}">
</div>
</div>
</div>
http://www.bootply.com/jgFqaA4r6o
When I include the bootstrap css for rtl:
https://github.com/morteza/bootstrap-rtl
this flips the order of the columns, which in most cases is the desired result. However, I would like the phone input columns to remain in the same order (unaltered).
Including the pull-left class to the first two columns fixes the problem but causes errors when resizing (specifically, shrinking) the screen.
I have tried using/learning the col--pull-/col--push- classes but I couldn't figure out how to make them work here.
Does anybody have any suggestions?
I am also open to changing the general layout if there are improvements on that as well.
Thank you.
I changed the html and used a small "hack" to solve this.
There is still probably a better solution out there. This is my html:
<div class="col-md-5">
<div class="col-sm-4 col-xs-12 pull-left">
<label for="phone_code" class="control-label">phone code</label>
<input type="text" class="form-control">
</div>
<div class="col-sm-8 col-xs-12">
<label for="phone_number" class="control-label">phone number</label>
<input type="tel" class="form-control">
</div>
</div>
http://www.bootply.com/tIW6xBHVGB
The "hack" is the "col-xs-12" class added to the <div> elements. If not added, the divs don't expand to take up the entire row as they should due to the "pull-left" class.
I'm open to hearing other suggestions.
i'm trying to build a 2 column form layout in bootstrap with an fixed height textarea on the right. I got it working well on desktop screen with an .pull-right-md (own class) on the textarea box. But in "responsive" mode (on smaller screens) I have the problem with the order of the boxes. I want the textarea to be on the last position when displayed on small screens.. I already tried to solve this problem by ordering the col's with .col-*-pull and .col-*-push classes but it was not working.
Here you can see what I have done so far: http://www.bootply.com/BBFB4Tt97j
Do you have any ideas how I could solve this problem?
Plz don't ever do duplication of html elements for sake of styling, it's not worth it! You breaking semantics, and produce illogical code that is tricky to maintain.
You can easily achieve desired effect without duplicating anything:
http://output.jsbin.com/debenudiqi/2/
You can grab code here
http://jsbin.com/debenudiqi/2/edit
This is what I suggest, tried to work my way around with pull and push but i haven't found a solution with that. You can use the hidden-xs, visible-xs to create two different text-area, one visible only on small screen and the other on large screens only. But you make sure when you handle the form, you handle the two different text areas.
<form class="">
<div class="col-md-6 col-sm-12 form-group pull-right-md hidden-sm hidden-xs">
<textarea class="form-control textarea-fixed-height" id="textarea" name="textarea">default text</textarea>
</div>
<div class="col-md-6 col-sm-12 form-group">
<input class="form-control" id="inputEmail3" placeholder="Name" type="text">
</div>
<div class="col-md-6 col-sm-12 form-group">
<input class="form-control" id="inputPassword3" placeholder="Email" type="email">
</div>
<div class="col-md-6 col-sm-12 form-group">
<input class="form-control" id="inputPassword3" placeholder="Telefon" type="text">
</div>
<div class="col-md-6 col-sm-12 form-group">
<input class="form-control" id="inputPassword3" placeholder="Betreff" type="text">
</div>
<div class="col-md-6 col-sm-12 form-group pull-right-md hidden-lg hidden-md">
<textarea class="form-control textarea-fixed-height" id="textarea1" name="textarea1">default text</textarea>
</div>
</form>
Bootply link
So for everyone with the same kind of problem thats the solution of my problem: http://www.bootply.com/BBFB4Tt97j#
I have put two textareas in the form-tag. One as first box and the second on the last position but before the submit button. With .hidden-xs and .hidden-sm on the first textarea it's not visible for smaller devices and with .hidden-md and .hidden-lg I prevent the textarea-tag for showing up on big screens.
this is working fine now.. thx
With Bootstrap 3.0, I am have a couple of questions/issues:
1) For learning, how is possible to have the div with class col-sm-5 small than the child div elements that are specified longer with class="col-sm-4" + class="col-sm-4" which equals 8?
2) I want "Pick A Date" text to come before the 2 input elements. However, it's coming after them which makes no sense to me.
<form name="dateFrom">
<div class="form-group well col-sm-5">
<div class="form-group">
Pick A Date
<div class="col-sm-4">
<input type="text" class="form-control datepicker" placeholder="From date" name="search" class="form-control">
</div>
<div class="col-sm-4">
<input type="text" class="form-control datepicker" placeholder="To date" name="search1" class="form-control">
</div>
</div><!-- /input-group -->
</div><!-- /.col-lg- -->
</form>
1) the widths of the columns are defined in percent, col-sm-5 has is 5/12 of the width of its parent and the col-sm-4 is 4/12 of the width of its parent which is in your case the form-group.
2) the elements with the class col-sm- have float: left, as your text Pick A Date does not have any floating attribute, the two div with col-sm- float to the left thats why your text appears on the right. If you want it in the correct order surround it with a div and add e.g. col-sm-4 to it.