Flexbox breaks bootstrap responsiveness - html

I have a row where one column can vary in height so I don't know how high it will be. In order to properly space the adjacent column I have used nested flex boxes.
This works fine on main break point but as soon as I add the flex box then this breaks the responsiveness as the columns don't stack on mobile anymore.
What should I do here? Should I drop flexbox? How else can I achieve this spacing?
.container{
margin-top: 60px;
}
.container{
border: 1px solid #000;
}
.row{
display: flex;
}
.row-center{
display: flex;
flex: 1;
}
.outer{
display: flex;
flex-direction: column;
justify-content: space-around;
border: 1px solid #000;
width: 100%;
}
.one, .two, .three{
flex: 0 0 40px;
border: 1px solid #000;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-6"><img src="http://placehold.it/350x500"></div>
<div class="col-xs-12 col-sm-6 row-center">
<div class="outer">
<div class="one">some text</div>
<div class="two">some text</div>
<div class="three">some text</div>
</div>
</div>
</div>
</div>
jsfiddle mirror: https://jsfiddle.net/y68dnzwy/

May be this help you:
.container{
margin-top: 60px;
}
.container{
border: 1px solid #000;
}
.row{
display: flex;
}
.row-center{
display: flex;
flex: 1;
}
.outer{
display: flex;
flex-direction: column;
justify-content: space-around;
border: 1px solid #000;
width: 100%;
}
.one, .two, .three{
flex: 0 0 40px;
border: 1px solid #000;
}
/* Added: */
#media screen and (min-width:100px) and (max-width: 980px) {
.row-center {
flex: auto;
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-6"><img src="http://placehold.it/350x500"></div>
<div class="col-xs-12 col-sm-6 row-center">
<div class="outer">
<div class="one">some text</div>
<div class="two">some text</div>
<div class="three">some text</div>
</div>
</div>
</div>
</div>
Demo

Used this with bootstrap 3, 4-text boxes in row with same height depending on the dynamic text, where on tablet and mobile are only 2 in row. And with tetx centered in middle
Somehow this flex magic makes on mobile, that only text boxes that are in same row have same height, so if last item is super tall, only last 2 items are super tall, not affecting first 2.
<div class="row row-flex-box">
<div class="col-xs-6 col-sm-6 col-md-3">
<div class="thumbnail flex-col-vertical-center">
<div class="caption"><span>text text text text</span></div>
</div>
</div>
<div class="col-xs-6 col-sm-6 col-md-3">
<div class="thumbnail flex-col-vertical-center">
<div class="caption"><span>text text text text text text text text</span></div>
</div>
</div>
<div class="col-xs-6 col-sm-6 col-md-3">
<div class="thumbnail flex-col-vertical-center">
<div class="caption"><span>text text text text</span></div>
</div>
</div>
<div class="col-xs-6 col-sm-6 col-md-3">
<div class="thumbnail homepage-slider-bottom-block-single flex-col-vertical-center">
<div class="caption"><span>text text text texttext text text texttext text text text</span></div>
</div>
</div>
</div>
Css:
.row-flex-box {
display: flex; /* make cols same heigh */
flex-wrap: wrap; /* alows responsive behavior of cols (otherwise cols will never break on mobile)*/
}
.flex-col-vertical-center {
display: flex; /* specifing display/flex-direction/justifi-content only because i want to have text aligned in the middle of boxes much cleaner than display:table-cell way*/
flex-direction: column;
justify-content: center;
text-align:center;
height: 100%; /* since cols have bigger height this has effect, also can be ussefull - height: calc(100% - 15px); with 15px bottom margin */
}

Related

How to right align text inside a div for mutiline content using flexbox

I'm using flexbox model to align div items to the right. It works when the items has only one line, but when I have more than one line, only the first line is aligned right. If the div fills two or more lines the next lines get aligned to the left.
Notice the last div from first column, in bold.
Is that a way to get the multiline text right aligned for all the lines using flexbox?
/* CSS */
.wrapper {
display: flex;
flex-wrap: wrap;
width: 100%;
}
.col-md-3 {
flex: 0 0 25%;
max-width: 25%;
}
.col-md-9 {
flex: 0 0 65%;
max-width: 65%;
margin-left: 20px;
}
.item-first-col {
justify-content: flex-end;
border: 1px solid blue;
}
.item-second-col {
border: 1px solid blue;
}
.d-flex {
display: flex;
}
.align-items-center {
align-items: center;
}
<!-- HTML -->
<div class="wrapper">
<div class="item-first-col col-md-3 d-flex">
One line text
</div>
<div class="item-second-col col-md-9 d-flex align-items-center">
Second column text
</div>
<div class="item-first-col col-md-3 d-flex">
One line text
</div>
<div class="item-second-col col-md-9 d-flex align-items-center">
Second column text
</div>
<div class="item-first-col col-md-3 d-flex" style="font-weight: bold;">
Here goes the text that fills two lines
</div>
<div class="item-second-col col-md-9 d-flex align-items-center">
Second column text
</div>
</div>
Simply use text-align: right;
.wrapper {
display: flex;
flex-wrap: wrap;
width: 100%;
}
.col-md-3 {
flex: 0 0 25%;
max-width: 25%;
}
.col-md-9 {
flex: 0 0 65%;
max-width: 65%;
margin-left: 20px;
}
.item-first-col {
justify-content: flex-end;
border: 1px solid blue;
text-align: right;
}
.item-second-col {
border: 1px solid blue;
}
.d-flex {
display: flex;
}
.align-items-center {
align-items: center;
}
<div class="wrapper">
<div class="item-first-col col-md-3 d-flex">
One line text
</div>
<div class="item-second-col col-md-9 d-flex align-items-center">
Second column text
</div>
<div class="item-first-col col-md-3 d-flex">
One line text
</div>
<div class="item-second-col col-md-9 d-flex align-items-center">
Second column text
</div>
<div class="item-first-col col-md-3 d-flex" style="font-weight: bold;">
Here goes the text that fills two lines
</div>
<div class="item-second-col col-md-9 d-flex align-items-center">
Second column text
</div>
</div>
Thanks and best regards!
You can use text-align css property
/* CSS */
.wrapper {
display: flex;
flex-wrap: wrap;
width: 100%;
text-align: right;
}
.text {
text-align: right;
width: 100%;
}
.col-md-3 {
flex: 0 0 25%;
max-width: 25%;
}
.col-md-9 {
flex: 0 0 65%;
max-width: 65%;
margin-left: 20px;
}
.item-first-col {
justify-content: flex-end;
border: 1px solid blue;
}
.item-second-col {
border: 1px solid blue;
}
.d-flex {
display: flex;
}
.align-items-center {
align-items: center;
}
<!-- HTML -->
<div class="wrapper">
<div class="item-first-col col-md-3 text">
One line text
</div>
<div class="item-second-col col-md-9 align-items-center text">
Second column text
</div>
<div class="item-first-col col-md-3 text">
One line text
</div>
<div class="item-second-col col-md-9 align-items-center text">
Second column text
</div>
<div class="item-first-col col-md-3 text" style="font-weight: bold;">
Here goes the text that fills two lines
</div>
<div class="item-second-col col-md-9 align-items-center text">
Second column text
</div>
</div>
It is not possible to align text the way you want it using only Flexbox properties.
The reason for that appears in the Flexbox specification:
Each in-flow child of a flex container becomes a flex item, and each contiguous sequence of child text runs is wrapped in an anonymous block container flex item.
In your example, you are able to align a single line of text, but it is not the text that is aligned, it is the anonymous block which contains it. That's why it works.
It won't work for multiple lines of text because writing more text simply increases the size of the anonymous block and stretches to fill the whole parent div. At that point, it doesn't matter what value you set justify-content to.
The only way to do what you want is using text-align:right on the parent div which the anonymous block will inherit, making the text it contains align to the right.

How do I correctly nest a flexbox to achieve a form layout?

I am looking to achieve the following layout:
Here is how I'm picturing it (with grids):
Black bar is the nav (we can ignore this)
A title and subtitle (purple) - these should be aligned and take up approx 70% of width - I think I've done this
A form which has 3 columns (should take up 70ish percent of the 70%, I don't want inputs to be too wide)
Column 1: Heading + text pairs
Column 2: it will have some icon/character - these must be perfectly aligned
Column 3: Heading + input boxes - these must be the same width
Here is my starting HTML:
.title-container {
display: flex;
justify-content: center;
background: red;
}
.title-item {
flex-basis: 75%;
}
.data-container {
display: flex;
justify-content: center;
background: blue;
}
.column-items {
flex-basis: 70%;
display: flex;
flex-direction: row;
}
.column-1-item {
background: green;
flex-grow: 0.5;
}
.column-2-item {
background: yellow;
flex-grow: 0.1;
align-self: center;
}
.column-3-item {
background: orange;
flex-grow: 1;
}
<div class="title-container">
<div class="title-item">
<h2>Title</h2>
<p>This is some text</p>
</div>
</div>
<div class="data-container">
<div class="column-items">
<div class="column-1-item">
<p>Heading1</p>
<p>SomeText</p>
</div>
<div class="column-2-item">
<p>--></p>
</div>
<div class="column-3-item">
<p>Heading1</p>
<input type="text" name="lname">
</div>
</div>
</div>
I have tried to expand on this, but no matter what I try, I end up further away from my design making me think there is something wrong with my initial design (and flex understanding). If I add additional 'row', it breaks my layout. I also think my data-container is wrongly setup, since this will take up far more space than I want it to
Here is a code pen.
Could someone help get me closer to my design?
I would wrap your entire html in a wrapper class so that you can get the general layout of the page like so:
<div class="wrapper">
<div class="title-container">
<h2>Title</h2>
<p>
Subtitle should be aligned with title
</p>
</div>
<div class="form-container">
<div class="item">
<div class="column">
<p>Heading1</p>
<p>Some Text</p>
</div>
<div class="column">
<p>-></p>
</div>
<div class="column">
<p>Heading1</p>
<p>[ input textfield ]</p>
</div>
</div>
<div class="item">
<div class="column">
<p>Heading3</p>
<p>Some Text</p>
</div>
<div class="column">
<p>-></p>
</div>
<div class="column">
<p>Heading2</p>
<p>[ input textfield ]</p>
</div>
</div>
<div class="item">
<div class="column">
<p>Heading3</p>
<p>Some Text</p>
</div>
<div class="column">
<p>-></p>
</div>
<div class="column">
<p>Heading3</p>
<p>[ input textfield ]</p>
</div>
</div>
<div class="item">
<div class="column"></div>
<div class="column"></div>
<div class="column submit-button">
<p>[ Button ]</p>
</div>
</div>
</div>
</div>
Then you can specify the width for the title-container and form-container with the width property. Making each of the item classes in the form container have a display: flex property lets you format the children column classes to have flex-grow: 1 so they can fill up the available space. The css then looks like:
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
outline: 1px solid red;
}
.title-container {
width: 70%;
outline: 1px solid red;
}
.form-container {
width: 50%;
outline: 1px solid red;
}
.item {
display: flex;
outline: 1px solid red;
}
.column {
/* flex-grow: 1; */
flex: 1 1 0px;
outline: 1px solid red;
}
.submit-button {
display: flex;
align-items: flex-end;
justify-content: flex-end;
}
Alternately you can remove the flex-grow: 1 property from the column class and add justify-content: space-between to the item class to get a result similar to your example.
Here is the codepen.
Your .data-container just needs a flex-direction: column; because you want the .column-items to stack.

Re-order items when I hit a custom breakpoint [duplicate]

This question already has answers here:
Order columns through Bootstrap4
(6 answers)
Closed 3 years ago.
I have four items with different sizes in a row.
On extra-large screens everything looks fine. But when I hit large screens (1199.98px / bootstrap 'lg'), I need to re-order my div items.
The third div need to be the last.
I also made a code pen for this
<!-- https://codepen.io/ibrahim-kunushefci/pen/OKJWzq -->
.hotelPr,
.hotelPr2,
.hotelPr3 {
height: 100px;
display: flex;
justify-content: center;
align-items: center;
color: white;
background: #3161a3;
border: 2px solid black;
}
.custom {
height: 100px;
display: flex;
justify-content: center;
align-items: center;
color: white;
background: #bbbbbb;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="row">
<div class="col-xl-2 col-lg-4">
<div class="hotelPr">
<p>Hotel</p>
</div>
</div>
<div class="col-xl-2 col-lg-4">
<div class="hotelPr2">
<p>Hotel</p>
</div>
</div>
<div class="col-xl-5 col-lg-10">
<div class="custom">
<p>This needs to be the last on small, medium and large screens. But not in extra large</p>
</div>
</div>
<div class="col-xl-3 col-lg-4">
<div class="hotelPr3">
<p>Hotel</p>
</div>
</div>
</div>
Add d-flex to your row container:
Add order-1 order-xl-0 to your the col you need to re-order
You can specify the order of the displayed siblings on a parent flexbox element.
I changed the display of your .row div in a flexbox, and I added an order property to your col-xl-5 div.
.row{
display: flex;
}
.hotelPr,
.hotelPr2,
.hotelPr3 {
height: 100px;
display: flex;
justify-content: center;
align-items: center;
color: white;
background: #3161a3;
border: 2px solid black;
}
.custom {
height: 100px;
display: flex;
justify-content: center;
align-items: center;
color: white;
background: #bbbbbb;
}
.col-xl-5{
order: 1; /* here */
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="row">
<div class="col-xl-2 col-lg-4">
<div class="hotelPr">
<p>Hotel</p>
</div>
</div>
<div class="col-xl-2 col-lg-4">
<div class="hotelPr2">
<p>Hotel</p>
</div>
</div>
<div class="col-xl-5 col-lg-10">
<div class="custom">
<p>This needs to be the last on small, medium and large screens. But not in extra large</p>
</div>
</div>
<div class="col-xl-3 col-lg-4">
<div class="hotelPr3">
<p>Hotel</p>
</div>
</div>
</div>

How to use `flex: grow` on floating content?

I have a header with 2 rows of 2 Foundation columns of content, as below:
<div class="wrapper">
<div class="header row">
<div class="large-6 columns">
HEADER
</div>
<div class="large-6 columns">
menu
</div>
</div>
<div class="row">
<div class="large-5 none show-for-medium columns info">
Some information to the left
</div>
<div class="large-7 columns">
<div class="image-container">
<div class="image">
image to the right
</div>
</div>
</div>
</div>
</div>
The .header height is dynamic and not set. I want the .image element to take up 100% of the remaining vertical space.
eg:
To that affect I have tried using flex and flex-grow, eg:
.wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
width: 100%;
}
.image-container {
flex-grow: 1;
}
but had no luck, see fiddle: https://jsfiddle.net/9kkb2bxu/46/
Would anyone know how I could negate the dynamic height of the header from the 100vh of the image container?
.wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
width: 100%;
border: 1px solid black;
background-color: #ccc;
}
.row {
width: 100%;
}
.header {
background-color: green;
}
.info {
background-color: yellow;
border: 1px solid #ccc;
}
.image-container {
border: 1px solid black;
display: flex;
}
.image {
background-color: red;
flex-grow: 1;
width: 100%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.1/css/foundation.min.css" rel="stylesheet"/>
<div class="wrapper">
<div class="header row">
<div class="large-6 columns">
<h1>
HEADER
</h1>
</div>
<div class="large-6 columns">
<h1>
menu
</h1>
</div>
</div>
<div class="row">
<div class="large-5 none show-for-medium columns info">
Some information to the left
</div>
<div class="large-7 columns">
<div class="image-container">
<div class="image">
image to the right
</div>
</div>
</div>
</div>
</div>
Set the second row to take up the rest of the remaining height with flex: 1 and make sure you nest that flex with display: flex:
.row.target-row {
flex: 1;
display: flex;
}
Set the .image-container to 100% height of its column parent.
.image-container {
height: 100%;
}
By default both columns will expand. Stop the left column from expanding with:
.large-5 {
align-self: flex-start;
}
(flex-start reference: https://stackoverflow.com/a/40156422/2930477)
Complete Example
.wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
width: 100%;
border: 1px solid black;
background-color: #ccc;
}
.row {
width: 100%;
}
.header {
background-color: green;
}
.info {
background-color: yellow;
border: 1px solid #ccc;
}
.image-container {
height: 100%;
background-color: red;
}
.large-5 {
align-self: flex-start;
}
.row.target-row {
flex: 1;
display: flex;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.1/css/foundation.min.css" rel="stylesheet" />
<div class="wrapper">
<div class="header row">
<div class="large-6 columns">
<h1>
HEADER
</h1>
</div>
<div class="large-6 columns">
<h1>
menu
</h1>
</div>
</div>
<div class="row target-row">
<div class="large-5 none show-for-medium columns info">
Some information to the left
</div>
<div class="large-7 columns">
<div class="image-container">
<div class="image">
image to the right
</div>
</div>
</div>
</div>
</div>
flex-grow only applies to flex children.
.image-container isn't a direct child of a display: flex element, so that property has no effect.
Plus, it affects the flex axis, which is not what you want.
Instead, you need to put those two elements in their own flex row, and use align-items (on the parent) and align-self (on either child) so that the first one aligns (on the cross axis) to flex-start (stick to top) and the second one to stretch.
You'll also want that flex row (parent) to have flex-grow: 1 so that it stretches along the vertical flex axis of its parent (.wrapper) to fill the rest of the page (otherwise, the grandchild will have nothing to stretch to).
For more information, read a good flex tutorial.
div.wrapper > div:not(.header).row {
flex: 1; /* 1 */
display: flex; /* 1 */
}
div.large-7.columns {
display: flex; /* 2 */
}
div.image-container { /* 3 */
flex: 1;
}
div.large-5.show-for-medium { /* 4 */
align-self: flex-start;
}
jsFiddle
Notes:
flex container and items consume all remaining height of respective parents
give children full height (via align-items: stretch initial setting)
flex item consumes all available width
yellow box does not need to expand to full height; now set to content height

Flexbox grid: two equal length rows, top row split into two columns

I'm trying to make a layout like the following image using css flexbox.
But I'm not much familiar with flexbox anyone can help me to make this?
Here is what I'm trying:
.row.flex {
display: flex;
}
.row [class=^"col-"] {
width: 200px;
height: 100%;
}
<div class="row flex">
<div class="col-xs-12 col-sm-6">
</div>
<div class="col-xs-12 col-sm-6">
</div>
<div class="col-xs-12 col-sm-12">
</div>
</div>
thanks :)
Option 1
Set the flex container to wrap.
Make each flex item take 50% of the space. Adjust for margins with calc.
The third item, which is forced to wrap, gets flex-grow: 1, so it consumes remaining space.
.row.flex {
display: flex;
flex-wrap: wrap;
}
.row [class^="col-"] {
flex: 0 0 calc(50% - 10px);
height: 100px;
margin: 5px;
background-color: lightgreen;
}
.row [class^="col-"]:last-child {
flex-grow: 1;
}
<div class="row flex">
<div class="col-xs-12 col-sm-6"></div>
<div class="col-xs-12 col-sm-6"></div>
<div class="col-xs-12 col-sm-12"></div>
</div>
Option 2
Set the flex container to wrap.
Give each flex item just enough width to allow only two per row.
Give each item the ability to consume remaining space.
.row.flex {
display: flex;
flex-wrap: wrap;
}
.row [class^="col-"] {
flex: 1 0 35%;
height: 100px;
margin: 5px;
background-color: lightgreen;
}
<div class="row flex">
<div class="col-xs-12 col-sm-6"></div>
<div class="col-xs-12 col-sm-6"></div>
<div class="col-xs-12 col-sm-12"></div>
</div>