I'm trying to set up wide flex elements that contain two children (see image at bottom).
The green child element should fill the remaining width of the parent element.
The blue child element should maintain a certain aspect ratio (1 to 0.75, for instance), but ultimately it should fill the height of the parent element.
Here's how I've tried setting this up:
.parent-outer {
display: flex;
flex-direction: row;
height: 250px;
}
.parent-inner {
display: flex;
flex-direction: column;
height: 100%;
}
.blue-child {
height: 100%;
width: 75vh;
background: blue;
}
.green-child {
height: 100%;
flex-grow: 1;
background: green;
}
<div class="parent-outer">
<div class="parent-inner">
<div class="blue-child"></div>
<div class="green-child"></div>
</div>
</div>
This does not seem to be working.
edit: refactor based on Temani Afif's comment -- remove .parent-inner. Looks like that inner parent div wasn't necessary, but can't seem to get the blue child to fill it's container's height and allow its width to adjust accordingly:
.parent {
display: flex;
flex-direction: row;
height: 250px;
}
.blue-child {
height: 100%;
width: 75vh;
background: blue;
}
.green-child {
height: 100%;
flex-grow: 1;
background: green;
}
<div class="parent">
<div class="blue-child"></div>
<div class="green-child"></div>
</div>
In the below I have 2 div containers.
Container 1 which contains a google map div that looks like the below :
HTML
<div class="container">
<div class="mapCanvas2" #mapCanvas2></div>
</div>
CSS
.container{
height: 64%;
width: 100%;
}
.mapCanvas2{
position:relative;
height: 100%;
width: 100%;
}
Container 2
.container2{
height: 36%;
width: 100%;
}
The problem:
On some screens (depending on its height) a blank space shows up below container 2 to hide it I must set the height value of .container to 67% or above which is of course not a solution.
You can use flex, by specifing flex:1 you make the second container fill the remaining space :
body {
height: 100vh;
display: flex;
flex-direction: column;
margin: 0;
}
.container {
height: 30%;
background: red;
}
.container-2 {
flex: 1;
background: blue;
}
<div class="container">
<div class="mapCanvas2" #mapCanvas2> map </div>
</div>
<div class="container-2"></div>
There are so many questions people have asked and answered about getting a flexbox div to fill the remaining height, but they are all slightly disappointing.
I want to get a div to fill the screen height responsively, and to make the background green. I don't want to have to tell the css the height of anything, I just want it to fill up the available space.
Every solution I've seen reverts to specifying a height at some stage, and I don't want to do that because it means either scroll-bars or white spaces some of the time.
Just colouring the body background seems even more complicated in Angular and I don't want to mess with my theme if I can help it, but this would also be a way to achieve what I want. It just feels like there should be a way to just tell a div to fill the rest of the browser window and it's really bugging me.
HTML:
<div flex layout="column" class="outer">
<div class="top">
<span class="left-spacer"></span>
<span class="page-header">
HOME
</span>
</div>
<div class="middle">
<div class="middle-constrained">
<img src="{{image}}">
</div>
</div>
<div class="bottom">
3
</div>
</div>
CSS:
#import url('https://fonts.googleapis.com/css?family=Bungee|Bungee+Shade');
.outer {
display: flex;
flex-direction: column;
background-color: #009999;
min-height: 100%;
}
.top {
flex: 1;
order: 1;
display: flex;
flex-basis: 33%;
}
.middle {
flex: 8;
order: 2;
display: flex;
flex-basis: 33%;
}
.bottom {
order: 3;
flex: 1;
flex-basis: 33%;
background-color: #009999;
}
.left-spacer {
flex: 7;
background-color: #009999;
}
.page-header {
padding: 0px;
background-color: #009999;
flex: 1;
height: 50px;
font-family: 'Bungee', cursive;
font-size: 2em;
vertical-align: middle;
color: #E1E3F3;
}
.middle {
display: flex;
overflow: auto;
}
.middle-constrained {
flex: 1;
}
img {
width:100%;
height: 100%;
}
I also have an Angular Material Toolbar component at the top of my webpage.
I have a requirement where I need to align content vertically within some divs. Flex-box would provide exactly what I need in an elegant way.
But I can't fully figure out whats the best way of setting the width of the flex-items is. If i use flex: 50%, the items grow with their content (which is not what I want). Also, I am not able to use overflow: hidden (because of the content within the divs).
Is it viable to set the width by using the good old width-property (this would work)? In other words: display: flex without flex: xx?
.wrapper {
display: flex;
width: 200px;
}
.left {
display: flex;
flex: 50%;
background-color: green;
/* overflow: hidden; *//* can't use that */
}
.right {
display: flex;
flex: 50%;
background-color: red;
/* overflow: hidden; *//* can't use that */
}
<div class="wrapper">
<div class="left">BigBigBigBigBig</div>
<div class="right">Small</div>
</div>
You can use flex: 0 0 50% so flex-grow will be set to 0 and it won't grow over 50%.
.wrapper {
display: flex;
width: 200px;
align-items: center;
}
.left {
flex: 0 0 50%;
background-color: green;
word-break: break-all;
}
.right {
flex: 0 0 50%;
background-color: red;
}
<div class="wrapper">
<div class="left">BigBigBsdfsdfigBigBigsdfsdf</div>
<div class="right">Small</div>
</div>
Does the fiddle supplied answer your question, just not too sure this is what you are after.
This question already has answers here:
Chrome / Safari not filling 100% height of flex parent
(5 answers)
Closed 6 years ago.
I've got a delicate problem for any CSS guru out there.
My green div has a flexible height, taking up the remaining.
And now I want to put a div inside that div which should be the half of the green div. But it seems like if Chrome treats it like half of the whole page rather than the flex item.
http://jsfiddle.net/unh5rw9t/1/
HTML
<body>
<div id="wrapper">
<div id="menu">
1
</div>
<div id="content">2
<div id="half_of_content">2.1</div>
</div>
<div id="footer" style="">
3
</div>
</div>
</body>
CSS
html,body {
height: 100%;
margin: 0;
}
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#menu {
height: 70px;
background-color: purple
}
#content {
flex: 1;
height: 100%;
background-color: green;
}
#half_of_content {
height: 50%;
background-color: yellow;
}
#footer {
height: 100px;
background-color: cyan
}
#Michael_B explained why Chrome behaves like this:
You gave the body a height: 100%. Then gave its child (.wrapper)
a height: 100%. Then gave its child (.content) a height: 100%.
So they're all equal height. Giving the next child (#half_of_content) a height: 50% would naturally be a 50% height
of body.
However, Firefox disagrees because, in fact, that height: 100% of .content is ignored and its height is calculated according to flex: 1.
That is, Chrome resolves the percentage with respect to the value of parent's height property. Firefox does it with respect to the resolved flexible height of the parent.
The right behavior is the Firefox's one. According to Definite and Indefinite Sizes,
If a percentage is going to be resolved against a flex item’s
main size, and the flex item has a definite flex
basis, and the flex container has a definite main
size, the flex item’s main size must be treated as
definite for the purpose of resolving the percentage, and the
percentage must resolve against the flexed main size of the
flex item (that is, after the layout algorithm below has been
completed for the flex item’s flex container, and the flex
item has acquired its final size).
Here is a workaround for Chrome:
#content {
display: flex;
flex-direction: column;
}
#content::after {
content: '';
flex: 1;
}
#half_of_content {
flex: 1;
height: auto;
}
This way the available space in #content will be distributed equally among #half_of_content and the ::after pseudo-element.
Assuming #content doesn't have other content, #half_of_content will be 50%. In your example you have a 2 in there, so it will be a bit less that 50%.
html,
body {
height: 100%;
margin: 0;
}
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#menu {
height: 70px;
background-color: purple
}
#content {
flex: 1;
height: 100%;
background-color: green;
display: flex;
flex-direction: column;
}
#content::after {
content: '';
flex: 1;
}
#half_of_content {
flex: 1;
background-color: yellow;
}
#footer {
height: 100px;
background-color: cyan
}
<div id="wrapper">
<div id="menu">
1
</div>
<div id="content">2
<div id="half_of_content">2.1</div>
</div>
<div id="footer" style="">
3
</div>
</div>
You could absolutely position div id="half_of_content".
#content {
flex: 1;
height: 100%;
background-color: green;
position: relative; /* new */
}
#half_of_content {
height: 50%;
background-color: yellow;
position: absolute; /* new */
width: 100%; /* new */
}
DEMO
With regard to your statement:
But it seems like if Chrome treats it like half of the whole page
rather than the flex item.
You gave the body a height: 100%. Then gave its child (.wrapper) a height: 100%. Then gave its child (.content) a height: 100%. So they're all equal height. Giving the next child (#half_of_content) a height: 50% would naturally be 50% height of body.
With absolute positioning, however, you don't need to specify parent heights.
Nesting flexboxes is a little buggy. I reworked your markup a little by adding an inner wrapper with display: flex; which seems to do the job. Here is the fiddle (also using class names instead of ids).
<div class="content">
<div class="wrapper-inner">
2
<div class="half">
2.1
</div>
</div>
</div>
.wrapper-inner {
position: absolute;
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
Fix:
on #content set
display: flex;
flex-flow: column nowrap;
justify-content: flex-end
on #half_of_content set flex: 0 0 50%;
Caveat: you need to add an extra div as a child of #content.
Here's the full example:
html,body {
height: 100%;
margin: 0;
}
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#menu {
height: 70px;
background-color: purple
}
#content {
flex: 1;
height: 100%;
display:flex;
flex-flow: column nowrap;
justify-content: flex-end;
background-color: green;
}
#half_of_content {
flex: 0 0 50%;
background-color: yellow;
}
#footer {
height: 100px;
background-color: cyan
}
<body>
<div id="wrapper">
<div id="menu">
1
</div>
<div id="content">2
<div id="half_of_content">2.1</div>
</div>
<div id="footer" style="">
3
</div>
</div>
</body>