Flex item not going to next row (not wrapping) [duplicate] - html

This question already has answers here:
Why are flex items not wrapping?
(2 answers)
Closed 3 years ago.
Why isn't the flex item going to the next row?
The flex item just pushes to side.
.section-header {
border-top: 1px solid #eee;
//padding-bottom: 20px;
background: blue;
}
.section {
margin-top: 20px;
background: orange;
padding: 20px;
}
.desc-label {
padding-top: 10px;
flex: 1 0 100%;
height: 100px;
background: green;
}
.row {
width: 50%;
max-width: 700px;
margin: 0 auto;
display: flex;
//flex-direction: column;
//align-items: flex-start;
padding-top: 20px;
background: lightblue;
height: 400px;
}
.section-title {
flex: 1 0 100%;
height: 100px;
background: purple;
}
<div class="section">
<div class="row section-header">
<div class="section-title">Engine</div>
<div class="desc-label">Template Element: Recipe Ingredient</div>
</div>
</div>
https://codepen.io/anon/pen/rQVbMr

An initial setting of a flex container is flex-wrap: nowrap. This means that flex items, by default, are forced to remain on a single line.
You can override the default by adding flex-wrap: wrap to the container (revised demo).
https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap

Related

Css flexbox column overflow [duplicate]

This question already has answers here:
How to make an element width: 100% minus padding?
(15 answers)
Closed 4 years ago.
How to avoid a horizontal overflow inside flex column? For instance I have the following markup:
.container {
display: flex;
}
.left, .right {
height: 300px;
}
.left {
flex: 0 0 300px;
background-color: pink;
}
.right {
flex: 1 0;
background-color: lightblue;
}
.inner-container{
padding-left: 16px;
padding-right: 16px;
width: 100%;
/*for testing purpose*/
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
<div class="container">
<div class="left"></div>
<div class="right">
<div class="inner-container">
Inner container
</div>
</div>
</div>
As you can see there are two items inside flex container: a left one is 300px width and a right one that takes all remaining space inside container. And if I'm going to add another fullwidth container inside right flex column it causes horizontal overflow. How to prevent this behavior? Thank you.
Add box-sizing: border-box to .inner-container.
.container {
display: flex;
}
.left,
.right {
height: 300px;
}
.left {
flex: 0 0 300px;
background-color: pink;
}
.right {
flex: 1 0;
background-color: lightblue;
}
.inner-container {
padding-left: 16px;
padding-right: 16px;
width: 100%;
/*for testing purpose*/
display: flex;
justify-content: center;
align-items: center;
height: 100%;
box-sizing: border-box; /* NEW */
}
<div class="container">
<div class="left"></div>
<div class="right">
<div class="inner-container">
Inner container
</div>
</div>
</div>

Flex last row to take available vertical space [duplicate]

This question already has answers here:
Stretch columns in two columns layout with shared header using flexbox
(2 answers)
Closed 4 years ago.
I have this layout, where a row wrap flex container has a first child with 100% width and 2 more children on the second row. The container has a fixed height and the first child (Filters block below) is collapsible (i.e. has 2 possibles values for height).
I would like the blocks on the last line to take all available height in all cases (filters block collapsed or expanded), but I can't find a solution.
I've tried various combinations of height, align-items/align-self: stretch, to no avail. Setting the pdt/list blocks height to 100% makes them effectively 100% of parent container, so they overflow due to the filters.
I know I could achieve it by making the first container flex column and throw in a second one with flex row,but I'd like to keep the current markup if possible. Any idea?
JSfiddle: https://jsfiddle.net/Lp4j6cfw/34/
HTML
<div id="lp-tag">
<div id="header">HEADER</div>
<div id="lp-ctnr">
<div id="filters" onclick="toggle()">FILTERS</div>
<div id="pdt">PDT</div>
<div id="list">LIST</div>
</div>
CSS
#lp-tag{
display: flex;
flex-flow: column nowrap;
width: 350px;
margin: auto;
border: 1px solid red;
height: 250px;
}
#header{
background: lightblue;
height: 80px;
}
#lp-ctnr{
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-content: flex-start;
align-items: stretch;
border: 1px solid green;
flex: 1;
}
#filters{
width: 100%;
background: lightgreen;
height: 45px;
}
.close{
height: 20px !important;
}
#pdt, #list {
flex: 1;
border: 1px solid blue;
text-align: center;
align-self: stretch;
}
#pdt{
background: yellow;
}
#list{
background: pink;
}
If you are open to alternative layout methods, I'd recommend CSS-Grid
.lp-tag {
width: 250px;
margin: 1em auto;
border: 1px solid red;
height: 250px;
display: inline-grid;
grid-template-rows: auto 1fr;
}
.header {
background: lightblue;
height: 80px;
}
.header.small {
height: 40px;
}
.lp-ctnr {
display: grid;
grid-template-rows: auto 1fr;
grid-template-columns: repeat(2, 1fr);
border: 1px solid green;
flex: 1;
}
.filters {
grid-column: 1 / span 2;
background: lightgreen;
height: 45px;
}
.filters.large {
height: 80px;
}
.pdt,
.list {
border: 1px solid blue;
text-align: center;
}
.pdt {
background: yellow;
}
.list {
background: pink;
}
<div class="lp-tag">
<div class="header">HEADER</div>
<div class="lp-ctnr">
<div class="filters" onclick="toggle()">FILTERS</div>
<div class="pdt">PDT</div>
<div class="list">LIST</div>
</div>
</div>
<div class="lp-tag">
<div class="header small">HEADER</div>
<div class="lp-ctnr">
<div class="filters large" onclick="toggle()">FILTERS</div>
<div class="pdt">PDT</div>
<div class="list">LIST</div>
</div>
</div>
This is the only solution I can see without an intermediary container. https://jsfiddle.net/5j38ouvs/
However, I would probably do like Nandita and add a surrounding container like here: https://jsfiddle.net/8md4oyLx/
CSS
#lp-ctnr{
display: flex;
flex-direction: column;
border: 1px solid green;
height: 550px;
width: 350px;
margin: auto;
}
#filters{
width: 100%;
background: lightgreen;
}
.close{
height: 20px !important;
}
#pdt{
flex-grow: 1;
background: yellow;
}
#list{
flex-grow: 1;
background: pink;
}
.list-container {
flex-grow: 1;
border: 1px solid blue;
text-align: center;
display: flex;
flex-direction: row;
}
HTML
<div id="lp-ctnr">
<div id="filters" onclick="toggle()">FILTERS</div>
<div class="list-container">
<div id="pdt">PDT</div>
<div id="list">LIST</div>
</div>
</div>

Remove gap between rows of flex items [duplicate]

This question already has answers here:
Remove space (gaps) between multiple lines of flex items when they wrap
(1 answer)
How does flex-wrap work with align-self, align-items and align-content?
(2 answers)
Closed 5 years ago.
Here's my example code:
#parent {
display: flex;
height: 350px;
background: yellow;
}
#wrapper {
flex: 1;
display: flex;
flex-flow: row wrap;
margin: 0 10%;
background: #999;
}
#top {
flex: 1 100%;
height: 50px;
margin-top: 10px;
background: red;
}
#left {
width: 30%;
height: 150px;
margin: 10px 10px 0 0;
background: blue;
}
#right {
flex: 1;
margin: 10px 0 0 0;
background: green;
}
<div id="parent">
<div id="wrapper">
<div id="top"></div>
<div id="left"></div>
<div id="right"></div>
</div>
</div>
As you can see, there's a gap (big gray area) between top (red) and left/right (blue/green). Flexbox seems to be spreading everything equally in parent element (gray).
However, I don't want the gap between my elements, I need everything to "rise" to top. There can be a gap after all elements (at the end).
I tried everything I could find/think of: auto margins, justify-content, align-items etc. No desired effect.
How to achieve this?
You need to add align-content: flex-start on flex-container or in your case #wrapper element.
#parent {
display: flex;
height: 350px;
background: yellow;
}
#wrapper {
flex: 1;
display: flex;
flex-flow: row wrap;
margin: 0 10% 50px 10%;
background: #999;
align-content: flex-start; /* Add this*/
}
#top {
flex: 1 100%;
height: 50px;
margin-top: 10px;
background: red;
}
#left {
width: 30%;
height: 150px;
margin: 10px 10px 0 0;
background: blue;
}
#right {
flex: 1;
margin: 10px 0 0 0;
background: green;
}
<div id="parent">
<div id="wrapper">
<div id="top"></div>
<div id="left"></div>
<div id="right"></div>
</div>
</div>
In a multi-line flex row layout, the align-content controls how the flex items aligns vertical when they wrap, and since its default is stretch, this is expected behavior.
Change it to align-content: center; and you'll see how their alignment change to vertical middle.
#parent {
display: flex;
height: 350px;
background: yellow;
}
#wrapper {
flex: 1;
display: flex;
flex-flow: row wrap;
margin: 0 10% 50px 10%;
background: #999;
align-content: center;
}
#top {
flex: 1 100%;
height: 50px;
background: red;
}
#left {
width: 30%;
height: 150px;
background: blue;
}
#right {
flex: 1;
background: green;
}
<div id="parent">
<div id="wrapper">
<div id="top"></div>
<div id="left"></div>
<div id="right"></div>
</div>
</div>

First flex item in a row disappearing outside left viewport edge without access via scroll [duplicate]

This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
Closed 6 years ago.
I have a flex container with three flex items in a row.
I'm trying to understand why when the screen isn't wide enough to accommodate all content, the 1st flex box gets truncated.
My expectation is that the horizontal scroll bar on .boxes_container allows all the content in #boxa to be visible provided we scroll.
Some quick notes:
Fixed widths are intentional.
In .boxes_container, justify-content:center is intentional. In the actual implementation the boxes are dynamic and I want the boxes to be centered if for example only one is visible.
.boxes_container {
display: flex;
flex-direction: row;
justify-content: center;
height: 77vh;
/* We need to set an explicit height here that translates into a real value
or scroll bars will not work because heights need a concrete value
*/
overflow-x: auto;
}
#boxa {
background-color: #994400;
display: flex;
flex-direction: column;
flex: 0 0 620px;
height: 100%;
/*
.boxa_content{
flex: 1 1 auto;
overflow-y: auto;
}
*/
}
#boxb {
background-color: #449900;
display: flex;
flex-direction: column;
flex: 0 0 620px;
height: 100%;
padding: 5px;
border: 2px solid #DDD;
border-radius: 8px;
}
#boxb .preview_content {
flex: 1 1 auto;
overflow-y: auto;
}
#boxc {
display: flex;
flex: 0 0 500px;
height: 100%;
flex-direction: column;
overflow-y: auto;
padding: 5px;
}
<div class="boxes_container">
<div id="boxa">
<h1>Stuff kajsdlkaj laksdjlka jslkdja sldjals jdlaksjd lkajs dlkajs dlkjas lkdjal ksdjalks jdlaj </h1>
</div>
<div id="boxb">
<h1>Stuff2 a;sldka;lskd a;lksd ;laks;dl kas;ldk a;lskd; laksd;la ksd;lak s;dlka s;ldlk a;lslkd ;alskd ;lask d;</h1>
</div>
<div id="boxc">
<h2>slkjdflksjd lfsjdklfs jdlkfjs ldkfjs ldkfj sl</h2>
</div>
</div>
codepen demo
The left box gets truncated because you are centering the content. When there isn't enough space, the content overflows the same amount on the left and right sides.
You can solve it by using margin: auto on the first and last elements as a way to center the content only when there is space left
.boxes_container {
display: flex;
flex-direction: row;
height: 77vh;
overflow-x: auto;
}
.boxes_container div:first-child {
margin-left: auto;
}
.boxes_container div:last-child {
margin-right: auto;
}
#boxa {
background-color: #994400;
display: flex;
flex-direction: column;
//width: 620px;
flex: 0 0 620px;
height: 100%;
}
#boxb {
background-color: #449900;
display: flex;
flex-direction: column;
//width: 620px;
flex: 0 0 620px;
height: 100%; // this is so important for the scrollbar behavior we want
//align-self:flex-start;
padding: 5px;
border: 2px solid #DDD;
border-radius: 8px;
.preview_content {
flex: 1 1 auto;
overflow-y: auto;
}
}
#boxc {
display: flex;
//width: 500px;
flex: 0 0 500px;
height: 100%;
flex-direction: column;
overflow-y: auto;
padding: 5px;
}
<div class="boxes_container">
<div id="boxa">
<h1>Stuff kajsdlkaj laksdjlka jslkdja sldjals jdlaksjd lkajs dlkajs dlkjas lkdjal ksdjalks jdlaj </h1>
</div>
<div id="boxb">
<h1>Stuff2 a;sldka;lskd a;lksd ;laks;dl kas;ldk a;lskd; laksd;la ksd;lak s;dlka s;ldlk a;lslkd ;alskd ;lask d;</h1>
</div>
<div id="boxc">
<h2>slkjdflksjd lfsjdklfs jdlkfjs ldkfjs ldkfj sl</h2>
</div>
</div>

Vertically aligning two flex items [duplicate]

This question already has answers here:
Prevent flex items from rendering side to side
(3 answers)
Closed 5 years ago.
I have a flex container .container and two flex items: item-one and item-two. I want to vertically center the first item and to stick the second to the bottom.
I don't know how to vertically align the first item in this context.
HTML:
<div class="container">
<div class="item-one">Item One</div>
<div class="item-two">Item Two</div>
</div>
CSS:
html, body {
height: 100%;
margin: 0;
}
.container {
width: 500px;
margin: 0 auto;
border: 5px solid orange;
height: 100%;
/* Flex properties */
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
.item-one {
border: 5px solid yellow;
flex-basis: 500px;
}
.item-two {
border: 5px solid red;
align-self: flex-end;
}
CodePen
You could use auto margins to align the elements like that. This will allow you to distribute any positive free space in the direction of the auto margin.
In this case, you would change flex-direction to column in order to make the flexbox items flow vertically. Then you could set margin-top: auto/margin-bottom: auto on the first flexbox item in order to center it vertically and ensure that the space above and below it is equal. In doing so, this will push the second item to the bottom:
Updated Example
html, body {
height: 100%;
margin: 0;
}
.container {
width: 500px;
margin: 0 auto;
border: 5px solid orange;
height: 100%;
display: flex;
flex-direction: column
}
.item-one {
border: 5px solid yellow;
margin: auto 0;
}
.item-two {
border: 5px solid red;
margin: 0 auto;
}
<div class="container">
<div class="item-one">Item One</div>
<div class="item-two">Item Two</div>
</div>