IE11 - Flex child takes full height [duplicate] - css

This question already has answers here:
How to make a sticky footer using flexbox in IE11?
(5 answers)
flex container min-height ignored in IE
(3 answers)
Closed 5 years ago.
I have a problem with Flexbox on IE11.
What I'm trying to do is to have one parent with 3 children. One header with a fixed size, a footer with a fixed size and in between a content area which should take the remaining space.
Here's the code - it works with Chrome but not with IE11:
.parent {
display: flex;
flex-direction: column;
max-height: 500px;
}
.header {
flex: 0 0 auto;
background: red;
height: 50px;
}
.content {
background: yellow;
flex: 1 1 auto;
position: relative;
overflow-y: scroll;
}
.footer {
flex: 0 0 auto;
background: blue;
height: 50px;
}
.long-item {
height: 2000px;
}
<div class="parent">
<div class="header">Header</div>
<div class="content">
<div class="long-item">Content</div>
</div>
<div class="footer">Footer</div>
</div>
I already went throught the open issues but couldn't really find a solution.

That is one of IE's flex bugs, the min-height when using flex direction column "bug".
In your case, add display: flex to the body and flex-grow: 1; to the parent (flex-basis: 100% or width: 100% will work as well).
body {
display: flex;
}
.parent {
flex-grow: 1; /* fill horizontal space */
display: flex;
flex-direction: column;
max-height: 500px;
}
.header {
flex: 0 0 auto;
background: red;
height: 50px;
}
.content {
background: yellow;
flex: 1 1 auto;
position: relative;
overflow-y: scroll;
}
.footer {
flex: 0 0 auto;
background: blue;
height: 50px;
}
.long-item {
height: 2000px;
}
<div class="parent">
<div class="header">Header</div>
<div class="content">
<div class="long-item">Content</div>
</div>
<div class="footer">Footer</div>
</div>

Related

How to fit 2 elements to page height?

I'm developing an app with the interface that is supposed to fit the page (only some internal elements may have scrolling). The basic layout consists of a header and the main section:
<div class="page">
<Navigation/> <!-- a Vue component -->
<main class="page__main">
...
</main>
</div>
currently, CSS has hardcoded height of the header (Navigation):
.page {
height: 100vh;
}
.page__main {
height: calc(100vh - 80px); /* 80px is the height of the header */
}
I'd like to get rid of this hardcoded bit but make sure .page__main's height gets no larger than 100vh - height of Navigation. Is there a way to do this without JS? I suspect that there are some options that can be used with
.page {
height: 100vh;
display: flex;
flex-direction: column;
}
but just using that with
.page__main {
flex-shrink: 1;
}
doesn't work: .page__main has children which use height in percents and once I set flex-shrink: 1; instead of height: calc(100vh - 80px); those grow and the interface is broken.
To illustrate the problem better, here's the current state:
body { padding: 0; margin: 0; }
.page {
height: 100vh;
background: blue;
}
.page__navigation {
height: 80px;
background: gray;
}
.page__main {
height: calc(100vh - 80px);
}
.part1 {
height: 50%;
background: #eeeeee;
overflow-y: scroll;
}
.part2 {
height: 50%;
background: #cccccc;
}
<div class="page">
<div class="page__navigation">nav stuff</div>
<main class="page__main">
<div class="part1">
this one usually has more elements than it could contain and those are shown with scrolling
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line
</div>
<div class="part2">
some
</div>
</main>
</div>
and here's what happen when I try to "set height" via flex:
body { padding: 0; margin: 0; }
.page {
height: 100vh;
display: flex;
flex-direction: column;
background: blue;
}
.page__navigation {
height: 80px;
background: gray;
}
.page__main {
flex-shrink: 1;
}
.part1 {
height: 50%;
background: #eeeeee;
overflow-y: scroll;
}
.part2 {
height: 50%;
background: #cccccc;
}
<div class="page">
<div class="page__navigation">nav stuff</div>
<main class="page__main">
<div class="part1">
this one usually has more elements than it could contain and those are shown with scrolling
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line
</div>
<div class="part2">
some
</div>
</main>
</div>
You can consider a nested flexbox container and don't forget the use of min-height:0; to allow the elements to shrink.
body { padding: 0; margin: 0; }
.page {
height: 100vh;
display: flex;
flex-direction: column;
background: blue;
}
.page__navigation {
height: 80px;
background: gray;
}
.page__main {
flex-grow: 1; /* Fill the remaining space*/
display:flex; /* Nested Container*/
flex-direction:column;
min-height:0; /* Allow the element to shrink */
}
.part1 {
flex-basis: 50%;
background: #eeeeee;
overflow-y: scroll; /* Allow the element to shrink */
}
.part2 {
flex-basis: 50%;
min-height:0; /* Allow the element to shrink */
background: #cccccc;
}
<div class="page">
<div class="page__navigation">nav stuff</div>
<main class="page__main">
<div class="part1">
this one usually has more elements than it could contain and those are shown with scrolling
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line
</div>
<div class="part2">
some
</div>
</main>
</div>
Use flex-grow. Keep everything as the second one (flex one) and change:
Edit
.page {
height: 100vh;
display: flex;
flex-direction: column;
background: blue;
}
.page__main {
height: 100%;
min-height: 0;
flex: 1 1 auto;
}
Three value flex means flex: flex-grow | flex-shrink | flex-basis.
Flex-grow tells our element whether or not it can take up additional space.
Flex-shrink works very similarly to flex-grow, only instead of dealing with extra space, it deals with space not needed by an elements content.
Flex basis is best used when in conjunction with either flex-shrink or flex-grow.
You can check this article to understand better.
I would suggest css-grid approach : -
.page {
background: gray;
display: grid;
grid-template-rows: 100px auto;
height: 100vh;
color: white;
}
.nav {
grid-row: 1/2;
background: brown;
}
.main {
grid-row: 2/3;
background: green;
display: grid;
grid-template-rows: 30% 70%;
}
.part1 {
overflow: auto
}
.part2 {
background: blue
}
<div class="page">
<div class="nav">Nav</div>
<div class="main">
<div class="part1">
this one usually has more elements than it could contain and those are shown with scrolling
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line
</div>
<div class="part2">
some
</div>
</div>
</div>
</div>

Flex element not filling up 100% height in flex container [duplicate]

This question already has answers here:
How to stretch flex child to fill height of the container?
(5 answers)
Closed 5 years ago.
I have the following markup:
.container {
display: flex;
width: 500px;
}
.col1 {
background: red;
height: 100%;
width: 50px;
}
.col2 {
background: blue;
flex: 1;
height: 200px;
}
<div class="container">
<div class="col1"></div>
<div class="col2"></div>
</div>
And I'm expecting it to look like this:
But instead when rendered in the browser and inspected, the height of .col1 is 0px. I'd expect it to be 200px since .col2 stretches the height of the container to that size. What am I doing wrong?
Remove height: 100% from .col1, like:
.col1 {
background: red;
width: 50px;
}
Have a look at the snippet below:
.container {
display: flex;
width: 500px;
}
.col1 {
background: red;
width: 50px;
}
.col2 {
background: blue;
flex: 1;
height: 200px;
}
body {
margin: 0;
}
<div class="container">
<div class="col1"></div>
<div class="col2"></div>
</div>
Hope this helps!

horizontally scrolling flex child

I have been scowering the web, but can not seem to get a solution to work.
Here is an example codepen:
http://codepen.io/anon/pen/Wxjjqp
.container {
display: flex;
}
.horizontally-scrolled-items {
display: flex;
background: lightblue;
overflow-x: scroll;
}
.item {
width: 1000px;
border: 1px solid blue;
}
html:
<div class="container">
<div class="horizontally-scrolled-items">
<div class="item">item1</div>
<div class="item">item2</div>
<div class="item">item3</div>
</div>
<div class="aside">
<button>keep me on screen</button>
</div>
</div>
The idea is for horizntally-scrolled-items to be flex:1. If the items are greater than the width of the container, for them to scroll, leaving aside in the view.
You can achieve this with min-width. Give your .item class a min-width with a flex-grow: 1;. Then set your .horizontally-scrolled-items div to width: 100%;.
CSS
.horizontally-scrolled-items {
width: 100%;
}
.item {
min-width: 400px;
flex-grow: 1;
}
CodePen
With Flex box
.horizontally-scrolled-items {
display: flex;
flex-wrap: nowrap;
overflow-x: auto;
}
.item {
flex: 0 0 auto;
}
Without Flex box
.horizontally-scrolled-items {
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
}
.item {
display: inline-block;
}
Another way is to set the items with and flex: 0 0 auto which is short hand for flex-grow: 0; flex-shrink: 0, so flexbox does not try to resize the items.

Make flex child element occupy 100% height of parent flex [duplicate]

This question already has answers here:
HTML5 flexible box model height calculation
(2 answers)
Closed 4 years ago.
I have a container flex with content flexes. How do i make content flex occupy full width and height of container flex.
<div id="main">
<div id="main-nav">
</div>
<div class="container">
<div class="content"></div>
<div class="content"></div>
</div>
</div>
#main{
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
}
#main-nav{
width: 100%
height: 50px;
}
.container{
display: flex;
flex-direction: row;
flex-wrap: wrap;
flex: 1;
}
.content{
display: flex;
width: 100%;
height: 100%;
}
The above code makes content to occupy 100% width of container but height is based on the text within the content. I tried the solutions mentioned from similar questions but had no luck and it was still the same.
Basically, I want each of the content to occupy the same height as occupied by the container in the viewport height. I also tried jQuery,
var rht = $("#container").height();
$(".content").height(rht);
It changes the height properly but adds a horizontal scroll bar with increase in width.
After several updates to the original question:
* {
box-sizing: borderbox;
margin: 0;
padding: 0;
}
#main {
display: flex;
flex-direction: column;
border: 1px solid red;
min-height: 100vh;
}
#main-nav {
flex: 0 0 50px;
}
.container {
display: flex;
flex-direction: column;
flex: 1;
border: 1px solid green;
}
.content {
flex: 1;
border: 1px solid orange;
}
<div id="main">
<div id="main-nav"></div>
<div class="container">
<div class="content"></div>
<div class="content"></div>
</div>
</div>
JSfiddle Demo
You cannot set width or height of flex's child is bigger (size of flex)/(number of flex's childs) but you can add position: absolute into .content and position: relative into .container then set width and height for .content. First .content is under second .content, you can use propety z-index or display: none to control.
* {
box-sizing: borderbox;
margin: 0;
padding: 0;
}
#main {
display: flex;
flex-direction: column;
background: red;
min-height: 100vh;
}
#main-nav {
flex: 0 0 50px;
}
.container {
position: relative;
display: flex;
flex: 1;
background: green;
}
.content {
position: absolute;
left: 0px;
top: 0px;
height: 100%;
width: 100%;
flex: 1;
background: orange;
}
<div id="main">
<div id="main-nav"></div>
<div class="container">
<div class="content">left</div>
<div class="content">right</div>
</div>
</div>

CSS Flex Layout: 2 columns out of non-hierarchal elements

I want to display the "right" and "left" elements in 2 columns. The right element should stretch vertically to the full height of the parent. Standard solutions use an extra container for each column. However, in my situation, the columns have no semantic meaning, they are just for display. Further, since my project will have many instances of this structure, adding container elements would introduce a lot of mess.
<div class='container'>
<div class='right'>
<div class='left'>
<div class='left'>
<div class='left'>
<div class='left'>
</div>
The under-appreciated "display:table-cell" almost works, but has some limitations, so that option is out. CSS "display:flex" is the only other potential solution that I can think of. I cannot find a working example, and my attempts have failed, so I hope that you can help me out. Thanks in advanced, -T
display:flex is awesome, but browser support could be an issue. Flex guide.
What's wrong with something like the below?
Fiddle Link!
HTML
<div class="left">
</div><!--
--><div class="right">
</div>
CSS
*, *:before, *:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
width: 100%;
max-width: 500px;
min-width: 200px;
margin: 0 auto;
}
div {
display: inline-block;
height: 100%;
}
.left {
background: #F00;
width: 50%;
}
.right {
background: #000;
width: 50%;
}
Within a flexible container, its children can be stacked vertically or horizontally (not both) via flex-direction. This is why if you want to use flexbox the .left divs should be wrapped in a containing parent. The .container children are stacked horizontally and the .left children are stacked vertically.
Here's fiddle: http://jsfiddle.net/7aK9f/1/.
Here's HTML:
<div class = "container">
<div class= "right">right</div>
<div class = "left">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
CSS:
* {
margin: 0;
padding: 0;
border: 0;
}
html, body {
height: 100%;
}
.container {
height: 100%;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
}
.container > .right {
order: 2;
background-color: #ccc;
-webkit-flex: 3 0 0;
flex: 3 0 0;
}
.container > .left {
order: 1;
background-color: #eee;
-webkit-flex: 7 0 0;
flex: 7 0 0;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
}
.container > .left > * {
-webkit-flex: 1 0 0;
flex: 1 0 0;
}
.container > .left > div + div {
box-shadow: inset 0 1px 0 0px #000;
}

Resources