Escaping Bootstrap Columns - html

I have two Bootstrap columns in my row, one is wide and tall and the others are short and narrow
However, on mobile devices (which I am targeting as anything below lg) I want to change the order of these columns, effectively splitting into three
Photo Consent
Organisation Details
Images
However, as the Photo Consent and Images are in the same column, I can't get this layout right - I either end up with both Photo Consent and Images above the Organisation, or I can get the right mobile layout but then Images ends up on a new row below on desktop.
Is there a way to achieve the desired layout in Bootstrap?
Here's the relevant markup for these columns:
<div class="row">
<!-- first column - Organisation Details -->
<div class="col-12 col-lg-7">
<div class="card card-body mb-3">
<h3 class="text-center">Organisation Details</h3>
<div class="row">
<div class="col-12 col-lg-6">
<div class="form-group mb-3">
<label class="form-label" for="name">Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Name" maxlength="255" required />
</div>
</div>
<div class="col-12 col-lg-6">
<div class="form-group mb-3">
<label class="form-label" for="slug">URL Slug</label>
<input type="text" class="form-control" id="slug" name="slug" placeholder="URL Slug" maxlength="300" />
</div>
</div>
<div class="col-12 col-lg-6">
<colour-picker title="Primary Colour" name="primary" value="#000000">
</colour-picker>
</div>
<div class="col-12 col-lg-6">
<colour-picker title="Secondary Colour" name="secondary" value="#FFFFFF"></colour-picker>
</div>
</div>
<div class="form-group mb-3">
<label class="form-label" for="description">Description</label>
<textarea rows="7" id="description" class="form-control" name="description" placeholder="Description" ></textarea>
</div>
</div>
</div>
<!-- second column - photo consent and images -->
<!-- on mobile, would prefer to split this column in two and have Photo Consent show above Org Details -->
<div class="col-12 col-lg-5">
<div class="card card-body mb-3">
<h3 class="text-center">Photo Consent</h3>
<div class="form-group mb-3">
<label for="consent">Can we take photos and videos of this organisation?</label>
<select class="form-control style-by-value" name="consent" id="consent" required>
<option value="">-- Please Select --</option>
<option value="1">No</option>
<option value="2">Yes, but...</option>
<option value="3">Yes</option>
</select>
</div>
<small>Consent type updated from web order</small>
</div>
<div class="card card-body mb-3">
<h3 class="text-center">Images</h3>
<div class="alert alert-danger text-center">File uploads are currently unavailable</div>
</div>
</div>
</div>
The only other thing I could think was to duplicate the columns and use a combination of d-none / d-none-lg to show/hide the relevant layout depending on the screen - but this is all wrapped in a form and I have concerns it could get a bit messy (besides the messiness of duplicated columns!!)

Hi Luke Reafactored your code.
added comments near each section please go through.
adding clearfix d-flex flex-wrap on the row
we are making the child elements inside the row to float, so adding clearfix will solve the issue of float elements.
d-flex flex-wrap setting the display to flex, and flex-wrap makes child elements wrap to next line when there is no enough space.
adding float-start order-2 on organisation block
float-start makes the block to float:left, order-2 - because we made the parent row to display as flex using d-flex , order class controls the position of the block when it is displayed as flex
rest of the blocks are floated to right using float-end, and following the same order concept, we are ordering the blocks.
i suggest you refer order concept in flex-box which helps to solve these issues.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/css/bootstrap.min.css" integrity="sha512-SbiR/eusphKoMVVXysTKG/7VseWii+Y3FdHrt0EpKgpToZeemhqHeZeLWLhJutz/2ut2Vw1uQEj2MbRF+TVBUA==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<div class="container-fluid">
<!-- added clearfix and display classes -->
<div class="row clearfix d-flex flex-wrap d-lg-block">
<!-- first column - Organisation Details -->
<!-- added order classes and float classes -->
<div class="col-12 col-lg-7 float-start order-2">
<div class="card card-body mb-3">
<h3 class="text-center">Organisation Details</h3>
<div class="row">
<div class="col-12 col-lg-6">
<div class="form-group mb-3">
<label class="form-label" for="name">Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Name" maxlength="255" required />
</div>
</div>
<div class="col-12 col-lg-6">
<div class="form-group mb-3">
<label class="form-label" for="slug">URL Slug</label>
<input type="text" class="form-control" id="slug" name="slug" placeholder="URL Slug" maxlength="300" />
</div>
</div>
<div class="col-12 col-lg-6">
<colour-picker title="Primary Colour" name="primary" value="#000000">
</colour-picker>
</div>
<div class="col-12 col-lg-6">
<colour-picker title="Secondary Colour" name="secondary" value="#FFFFFF"></colour-picker>
</div>
</div>
<div class="form-group mb-3">
<label class="form-label" for="description">Description</label>
<textarea rows="7" id="description" class="form-control" name="description" placeholder="Description"></textarea>
</div>
</div>
</div>
<!-- second column - photo consent -->
<!-- added order classes and float classes -->
<div class="col-12 col-lg-5 float-end order-1">
<div class="card card-body mb-3">
<h3 class="text-center">Photo Consent</h3>
<div class="form-group mb-3">
<label for="consent">Can we take photos and videos of this organisation?</label
>
<select
class="form-control style-by-value"
name="consent"
id="consent"
required
>
<option value="">-- Please Select --</option>
<option value="1">No</option>
<option value="2">Yes, but...</option>
<option value="3">Yes</option>
</select>
</div>
<small>Consent type updated from web order</small>
</div>
</div>
<!-- moved images out of the above div and made it seperate -->
<!-- images -->
<!-- added order classes and float classes -->
<div class="col-12 col-lg-5 float-end order-3">
<div class="card card-body mb-3">
<h3 class="text-center">Images</h3>
<div class="alert alert-danger text-center">
File uploads are currently unavailable
</div>
</div>
</div>
</div>
</div>

Related

How to ignore "order" class on mobile in Bootstrap

Is there a way to ignore the order class on larger screens?
I have two inputs with a label that goes like this;
<div class="row">
<div class="col-12 col-md-5 order-first order-md-5"><label class="form-label">Label for 1st input <small>(Explanation for first input)</small></label></div>
<div class="col-12 col-md-5 offset-md-2 order-last order-md-10"><label class="form-label">Label for 2n input<small>( Explanation for second input )</small></label></div>
<div class="col-12 col-md-5 order-first order-md-5">
<div class="form-group mt-2">
<input autocomplete="off" type="text" class="form-control" placeholder="">
</div>
</div>
<div class="col-12 col-md-2 align-self-center">
<p class="form-group text-center mt-3">and/or</p>
</div>
<div class="col-12 col-md-5 order-last order-md-10">
<div class="form-group mt-2">
<input autocomplete="off" type="text" class="form-control" placeholder="">
</div>
</div>
</div>
They work just as I want them to on mobile, however, I need them to look like they were as before I have added the order classes which look like
<div class="row">
<div class="col-12 col-md-5"><label class="form-label">Label for 1st input <small>(Explanation for first input)</small></label></div>
<div class="col-12 col-md-5 offset-md-2"><label class="form-label">Label for 2n input<small>( Explanation for second input )</small></label></div>
<div class="col-12 col-md-5">
<div class="form-group mt-2">
<input autocomplete="off" type="text" class="form-control" placeholder="">
</div>
</div>
<div class="col-12 col-md-2 align-self-center">
<p class="form-group text-center mt-3">and/or</p>
</div>
<div class="col-12 col-md-5">
<div class="form-group mt-2">
<input autocomplete="off" type="text" class="form-control" placeholder="">
</div>
</div>
</div>
Ordering is correct on mobile and just as I want, but it breaks the desktop order. Ordering without the order classes is perfect on the desktop for me, but it breaks the mobile order. Is there a way to activate the order classes on mobile only?
Try to add class like .order-1 insted of order-first and all related classes hope that work for you.

Bootstrap - vertical align form group label on top, input at bottom

I have a form that uses Bootstrap 4.4. The form groups contain a label and an input and sometimes also a select and when the select is present it breaks the alignment of the labels and inputs on the same row.
How to keep the labels always on top and the input at the bottom? I want to do this without custom Css and additional html elements if possible.
<div class="row col-sm-12 col-md-12 col-lg-12">
<div class="col-sm-12 col-md-3 col-lg-3 form-group">
<label for="value">Value:</label>
<select>
<option>something</option>
</select>
<div class="input-group">
<input type="text" class="form-control">
</div>
</div>
<div class="col-sm-12 col-md-3 col-lg-3 form-group">
<label for="name">Name:</label>
<div class="input-group">
<input type="text" class="form-control">
</div>
</div>
</div>
Using justify on one of the containers I got all the inputs to allign at the bottom but I want to keep the labels at the top.
Edit: I need to keep the layout like this, with the two (or more) form groups on one row:
If you add label -> class="w-100" it will take width:100% so it won't take any element to the same row with itself. To keep inputs always at the end of the form group you can add something on top of them. Also if you give the same design for selects and other form elements it will look better.
<div class="row col-sm-12 col-md-12 col-lg-12">
<div class="col-sm-12 col-md-3 col-lg-3 form-group">
<label class="w-100" for="value">Value:</label>
<select>
<option>something</option>
</select>
<div class="input-group">
<input type="text" class="form-control">
</div>
</div>
<div class="col-sm-12 col-md-3 col-lg-3 form-group">
<label class="w-100" for="name">Name:</label>
<div class="input-group">
<input type="text" class="form-control">
</div>
</div>
</div>

How to align two inputs side by side inside a Bootsrap row?

The two inputs get misaligned due to the difference in length of the label text. Below is the part of my code:
<div class="row">
<div class="col-auto col-md-6 form-group">
<label for="category">Which of the following best describes you?</label>
<select class="form-control" id="category" name="category">
<option>Furniture Designer</option>
<option>Architect</option>
</select>
</div>
<div class="col-auto col-md-6 form-group">
<label for="training">Education level/type </label>
<input type="text" name="training" class="form-control" id="training" placeholder="Training">
</div>
</div>
How can I easily fix the misalignment and keeping the form resposive?
You could make the form-group's d-flex flex-column and then use mt-auto on the form input to force bottom alignment...
<div class="row">
<div class="col-auto col-md-6 form-group d-flex flex-column">
<label for="category">Which of the following best describes you?</label>
<select class="form-control mt-auto" id="category" name="category">
<option>Furniture Designer</option>
<option>Architect</option>
</select>
</div>
<div class="col-auto col-md-6 form-group d-flex flex-column">
<label for="training">Education level/type </label>
<input type="text" name="training" class="form-control mt-auto" id="training" placeholder="Training">
</div>
</div>
https://codeply.com/p/S9wKwrKLch
OR, use the text-truncate class on the labels to prevent text wrapping:
<label for="category" class="text-truncate">
Which of the following best describes you?
</label>
https://codeply.com/p/S9wKwrKLch
try with this way
<div class="col-auto d-md-flex flex-md-column col-md-6 form-group">
<label class="flex-md-fill" for="training">Education level/type </label>
<input type="text" name="training" class="form-control" id="training" placeholder="Training">
</div>
https://jsfiddle.net/lalji1051/t41Lnuxh/5/
The default behavior in bootstrap 4 is that the label will appear above the input. (Certainly with the code you have above).
If you want the label to be next to the input then try this straight from teh bs4 documentation:
<form>
<div class="form-group row">
<label for="inputPassword" class="col-sm-2 col-form-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword">
</div>
</div>
</form>
Bootstrap 4 docs
If you would like to handle it with a little piece of code, I hope this one wirks for you :
You can use equal margin-bottoms for both your inputs and if you like to use bootstrap, for example you can add mb-2 class to your inputs.
Or even you can use mt-auto to your inputs.

How to set the height of textarea to fill the whole column?

I am writing simple contact form using bootstrap-4. I have 1 row with 2 columns. Left column contains input text objects and selection object. Right column contains textarea. I try to make textarea the same hight as left col.
I aplied h-100 class into the textarea and parent div but it's higher than the left col.
link to the screenshot: https://i.imgur.com/Lrfwhtn.png
<div id="content" class="margin-from-nav">
<div class="container">
<form>
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-6 col-xl-6">
<div class="form-group">
<label for="inputName1">Imię</label>
<input type="text" class="form-control" id="inputName1" placeholder="Imie">
</div>
<div class="form-group">
<label for="inputName2">Nazwisko</label>
<input type="text" class="form-control" id="inputName2" placeholder="Nazwisko">
</div>
<div class="form-group">
<label for="inputEmail4">Adres e-mail</label>
<input type="email" class="form-control" id="inputEmail4" placeholder="Email">
</div>
<div class="form-group">
<label class="mr-sm-2" for="inlineFormCustomSelect">Temat zapytania</label>
<select class="custom-select mr-sm-2" id="inlineFormCustomSelect">
<option selected>Wybierz temat...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-6 col-xl-6">
<div class="form-group h-100">
<label for="exampleFormControlTextarea1">Treść wiadomości</label>
<textarea class="h-100 form-control" id="exampleFormControlTextarea1" rows="10"></textarea>
</div>
</div>
</div>
</form>
</div>
</div>
You can use the flexbox utility classes (d-flex flex-column) to make the textarea fill the remaining height (flex-grow-1):
<div class="col-12 col-sm-12 col-md-12 col-lg-6 col-xl-6 d-flex flex-column">
<div class="form-group flex-grow-1 d-flex flex-column">
<label for="exampleFormControlTextarea1">Treść wiadomości</label>
<textarea class="form-control flex-grow-1" id="exampleFormControlTextarea1"></textarea>
</div>
</div>
Demo: https://www.codeply.com/go/2z4ckbR2FU

How can I fix this Bootstrap layout issue?

I have a form that uses Bootstrap 3. My layout should follow the below:
On small screens, Display 1 input per row with the label stacked above the input
On medium devices, Display 2 input per row with the label to the left of each input
On large devices, Display 3 inputs per rom with the label to the left of each input
Rows that contain a textarea, should always be displayed with one input per row
I have this almost working with one small quirk. Everything works well with all of the elements lining up like the below on all bootstrap breakpoints up to md like this:
However, when I hit the lg breakpoint, the text area and it's label no longer line up with the other element like this:
Looking at the grid I've set up I can see why this happens but I cant seem to find a pattern that fits my needs without causing this issue. I know I can start hacking away with CSS like negative margins to force the layout but I feel like there is a better way.
How can I fix this?
Here is a jsFiddle showing the issue
And the relevant HTML:
<form class="form-horizontal" role="form">
<div class="row">
<div class="col-sm-12 input-row clone-icon text-right">
<div class="form-group">
<div class="col-md-2 col-lg-2 left-on-mobile">
<label for="" class="control-label ">Textarea</label>
</div>
<div class="col-md-10 col-lg-10">
<textarea class="form-control form-input"></textarea>
</div>
</div>
</div>
<div class="col-sm-6 col-lg-4 input-row clone-icon text-right">
<div class="form-group">
<div class="col-md-4 col-lg-5 left-on-mobile">
<label for="" class="control-label ">Input Field</label>
</div>
<div class="col-md-8 col-lg-7">
<input type="text" class="form-control">
</div>
</div>
</div>
<div class="col-sm-6 col-lg-4 input-row clone-icon text-right">
<div class="form-group">
<div class="col-md-4 col-lg-5 left-on-mobile">
<label for="" class="control-label ">Input Field</label>
</div>
<div class="col-md-8 col-lg-7">
<input type="text" class="form-control">
</div>
</div>
</div>
<div class="col-sm-6 col-lg-4 input-row clone-icon text-right">
<div class="form-group">
<div class="col-md-4 col-lg-5 left-on-mobile">
<label for="" class="control-label ">Input Field</label>
</div>
<div class="col-md-8 col-lg-7">
<input type="text" class="form-control">
</div>
</div>
</div>
</div>
</form>
For the first Input field change the col-lg-* classes from 5 and 7 to 6 and 6. That will make its <label> tag to align with the one in the previous row.
<div class="col-sm-6 col-lg-4 input-row clone-icon text-right">
<div class="form-group">
<div class="col-md-4 col-lg-6 left-on-mobile">
<label for="" class="control-label ">Input Field</label>
</div>
<div class="col-md-8 col-lg-6">
<input type="text" class="form-control">
</div>
</div>
</div>
Demo link here