Flex element inside another flex element collapses on Safari - html

I got this code working on Chrome where the content of first flex-item needs to be aligned to the bottom and stretches if necessary:
body {
height:100vh;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
}
.flex-container {
padding: 0;
margin: 0;
height: 100%;
display: flex;
flex-direction: column;
}
.flex-item {
background: tomato;
padding: 10px;
border: 5px solid red;
flex: 0 1 auto;
}
.flex-stretch {
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-end;
flex: 1 1 auto;
}
<div class="flex-container">
<div class="flex-item flex-stretch">1</div>
<div class="flex-item">2<br>2<br>2<br>2<br>2<br>2<br>2<br>2</div>
<div class="flex-item">3</div>
</div>
but on Safari it doesn't respect the content of the first flex-item and collapses if the viewport is smaller than the flex-container and scrolling is necessary.
Is there any work around this issue?
Thanks, this is my first question here :)
Here is the codePen: https://codepen.io/felphos/pen/GRZVKwY

Since you use flexbox you shouldn't define the height explicitly. I think that removing height: "100%" and also setting .flex-stretch{flex: 1 0 auto;} (0 flex-shrink) will get you what you want.

Related

In container with flex-grow: 1 the content is overflowing when it should be scrollable

I have a container that is flex-grow sized to fill up the remaining space within a fixed size container.
Within the flex-grow container, I have another div that is a lot bigger than the flex sized container. How do I make it so that the content-wrapper element is scrollable instead of the child element overflowing.
Thank you!
.main-content-container {
padding: 0 20px;
display: flex;
flex-flow: column nowrap;
grid-gap: 10px;
height: 550px;
background: green;
}
.sub-content-container {
width: 300px;
background: grey;
flex-grow: 1;
display: flex;
flex-flow: column nowrap;
}
.content-wrapper {
flex-grow: 1;
display: flex;
flex-flow: column nowrap;
overflow: auto;
}
.content-container {
height: 10000px;
background: #555;
}
body {
background: black;
color: white;
padding-bottom: 30px;
}
<div class='main-content-container'>
<p>stuff</p>
<div class='sub-content-container'>
<p>header</p>
<div class='content-wrapper'>
<div class="content-container">I WANT THIS TO STAY WITHIN THE CONTENT-WRAPPER</div>
</div>
</div>
</div>
Generally speaking, for the overflow property to work, the container needs to be overflowed. That requires a fixed length on the container. Without a fixed length (height or width), there's nothing to trigger an overflow. The flex-grow property doesn't establish a fixed length, so it doesn't work.
Of course, setting a fixed height on your container is not an option if you want a dynamic layout.
So, to solve both problems, set the container to height: 1px.
this establishes the fixed length;
it doesn't interfere with the dynamic lengths; and,
the flex-grow property expands the container to full height
But there's one more problem. The nested flex container in column direction seems to be ignoring the overflow property. This is possibly because of the nesting in a flex formatting context. Hence, if possible, switch that container back to a block formatting context.
Make these adjustments to your code:
.content-wrapper {
height: 1px; /* new */
flex-grow: 1;
/* display: flex; */
flex-flow: column nowrap;
overflow: auto;
}
.main-content-container {
padding: 0 20px;
display: flex;
flex-flow: column nowrap;
grid-gap: 10px;
height: 550px;
background: green;
}
.sub-content-container {
width: 300px;
background: grey;
flex-grow: 1;
display: flex;
flex-flow: column nowrap;
}
.content-wrapper {
height: 1px; /* new */
flex-grow: 1;
/* display: flex; */
flex-flow: column nowrap;
overflow: auto;
}
.content-container {
height: 10000px;
background: #555;
}
body {
background: black;
color: white;
padding-bottom: 30px;
}
<div class='main-content-container'>
<p>stuff</p>
<div class='sub-content-container'>
<p>header</p>
<div class='content-wrapper'>
<div class="content-container">I WANT THIS TO STAY WITHIN THE CONTENT-WRAPPER</div>
</div>
</div>
</div>
jsFiddle demo

Flexbox div not taking the entire vertical space

I'm having an issue with flexbox not filling spaces as I intend, I'm trying to see what I've been missing but couldn't wrap my head around it.
Below is a reproduction of my issue with a link to a codepen.
I need the div in the middle with class="artcl-description" to fill the remaining available space, taking into consideration the header and the footer and their content, I tried giving the parent (class="artcl-content-container") properties align-items: stretch; justify-content: stretch; but no bueno, I don't want to resort to hard coded height values and percentages if that's possible :/
html:
<div class="artcl-container">
<div class="artcl-content-container">
<div class="artcl-title-container">
<h1>Some Title</h1>
</div>
<div class="artcl-description">
<p>Why is this not taking the remaining height?</p>
</div>
<div class="artcl-footer">
<div>Some guy</div>
<div>
X/X/XXXX XX:XX:XX
</div>
</div>
</div>
<img class="artcl-thumbnail" src="https://picsum.photos/200" />
</div>
scss:
$article-height: 240px;
$pad: 16px;
body {
padding: 16px;
}
* {
direction: ltr;
margin: 0px;
}
.artcl-container {
height: $article-height;
background-color: black;
color: white;
font-family: sans-serif;
border-radius: 4px;
overflow: hidden;
display: flex;
flex-direction: row;
.artcl-thumbnail {
height: $article-height;
width: $article-height;
object-fit: cover;
}
.artcl-content-container {
flex: 1;
flex-direction: column;
align-items: stretch;
justify-content: stretch;
.artcl-title-container {
padding: $pad;
border: dashed 1px wheat;
}
.artcl-description {
flex: 1;
padding: $pad;
border: dashed 1px wheat;
}
.artcl-footer {
padding: $pad;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
border: dashed 1px wheat;
}
}
}
Link to Pen
You forgot to add display: flex; to your class .artcl-content-container. I added it to your pen and it just works fine.

How to place items in flexbox take equal width?

I want to place the items in the flexbox take the same width.
Within the flexbox I have a searchsvg, input field and div with some text. I want each of them to take equal width themselves based on the width of the flexbox. I don't want to provide the width of each item manually. I tried using justify-content: space-evenly. In doing so, the input field takes more width than rest of them.
How can I avoid it? Below is the code:
.wrapper {
display: flex;
flex-grow: 1;
}
.items_container {
position: relative;
width: 40px;
height: 40px;
top: 16px;
margin-left: 16px;
padding-left: 5px;
display: flex;
align-items: center;
justify-content: space-evenly;
}
#media (min-width: 300px) {
.items_container.expanded {
width: 50%;
}
}
.items_container.expanded .search_input_field {
display: flex;
align-items: center;
}
<div class="wrapper">
<div class="items_container expanded">
<div class="search_input_field">
<div>
<Svgsearch/>
</div>
<input type="text" placeholder="input" />
</div>
<div>dropdown to be added</div>
</div>
.child elements should grow equally and not shrink
.parent {
display: flex;
}
.child {
flex: 1 0 0;
}
/* ignore */
.child {
padding: 5px;
height: 50px;
background: lightcoral;
margin: 2px;
text-align: center;
}
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
</div>
I moved flex-grow: 1 from where you placed it, because it wasn't doing anything. This is a rule that affects flex children. Therefore, I moved it to affect all direct children of the flex parent, .wrapper.
.wrapper {
display: flex;
/* flex-grow: 1; <-- moved below */
& > * {
flex-grow: 1;
}
}
jsFiddle

How do you stretch and center item using Flexbox?

Take a look at this https://codepen.io/techsin/pen/JWQgoM
//html
<div class="nav"> a \ b \ c</div>
<div class="box"> no text</div>
//css
body {
display: flex;
flex-direction: column;
align-items: center;
align-content: stretch;
}
.box {
max-width: 800px;
padding: 30px;
background-color: gray;
flex-grow:1;
}
.nav {
padding: 30px;
background-color: purple;
text-align: center;
color: #fff;
}
I want box to expand like a block element, but not expand beyond max width, and still be centered.
If I set align-items to stretch on body then box do expands but it gets aligned to left, if set margin auto Or align-items to center, then box stops trying to fill as much as possible width wise.
I simply want box to expand to 800 pixels, but when windows size changes its width also goes down, just like how any regular block element's width would act by default.
Whole reason to use flexbox is to have box also cover remaining height.
Give the box width: 100%;, margin: 0 auto; and box-sizing: border-box;, so the padding gets included in its width
Updated codepen
Stack snippet
* {
padding: 0;
margin: 0;
}
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
}
.box {
max-width: 800px;
width: 100%;
padding: 30px;
background-color: gray;
flex-grow:1;
margin: 0 auto;
box-sizing: border-box;
}
.nav {
padding: 30px;
background-color: purple;
text-align: center;
color: #fff;
}
<div class="nav"> a \ b \ c</div>
<div class="box"> no text</div>

flexbox: stretching the height of elements with flex-direction: row

I want to stretch two div elements (.sideline and .main-contents) to reach the bottom of the page and stay at a certain height from the footer.
The two divs are nested inside a div (.row-elements) with the flex-direction: row since I wanted them to be on the same row.
/* body {
display:flex;
flex-direction:column;
} */
.one-above-all {
display: flex;
flex-direction: column;
/* flex: 1 0 auto; */
/* min-height: 1100px; */
border: solid black 1px;
}
.top-block {
margin: 0 auto;
border: solid black 1px;
width: 300px;
height: 30px;
margin-top: -15px;
}
.headline {
border: solid black 1px;
width: 90%;
align-self: flex-end;
margin-top: 40px;
margin-right: 10px;
height: 160px;
display: flex;
box-sizing: border-box;
}
.row-elements {
display: flex;
flex-direction: row;
margin-top: 40px;
align-items: stretch;
/* min-height: 900px;
flex: 1 0 auto;
*/
}
.sideline {
width: 160px;
border: solid 1px;
margin-left: calc(10% - 10px);
box-sizing: border-box;
flex-shrink: 1
}
.main-contents {
border: solid 1px;
margin-left: 40px;
/* align-self: stretch; */
flex: 1 1 auto;
margin-right: 10px;
box-sizing: border-box;
}
.bottom-block {
align-self: flex-end;
margin-top: auto;
border: black solid 1px;
margin: auto;
width: 300px;
height: 30px;
margin-bottom: -10px;
/* margin-top: 880px; */
}
/* .stretch-test {
border:solid, 1px;
display: flex;
flex-direction: column;
flex: 1 0 auto;
} */
<div class="one-above-all">
<div class="top-block"></div>
<div class="headline"></div>
<!-- <div class="stretch-test"> -->
<div class="row-elements">
<div class="sideline"></div>
<div class="main-contents">jhjkdhfjksdhafjksdahfl</div>
<!--</div> -->
</div>
</div>
<div class="bottom-block">footer</div>
Codepen
The commented out code in the css is the things I have tried.
I tried to set the body as flex and give the row-elements class flex property of 1 0 auto which didn't work.
I tried nesting the row-elements class (which has the flex-direction of row) in another div with a flex-direction of column and setting .row-elements to flex:1 0 auto which also didn't work.
I tried totally removing the the row-elements class but the two divs won't come on the same row.
Any solution will be appreciated.
To stick the footer to the bottom, here are two methods:
Method #1: justify-content: space-between
Align the container vertically with flex-direction: column. Then pin the last element to the bottom with justify-content: space-between.
revised codepen
Method #2: auto margins
Also with the container in column-direction, apply margin-top: auto to the footer, which spaces it away from the other flex items. (Seems you're already familiar with this method.)
Here's a detailed explanation for both: Methods for Aligning Flex Items
Make sure to define a height for your container, unless you simply want content height. In my example I've used height: 100vh on body.