How can I set a height of left column(block) to 100% using flex? I have dom like this:
<LeftPanel>
<Logo />
<Profile />
<Chat />
<SocialButtons />
</LeftPanel>
LeftPanel to have a height 100%. Chat should grow or shrink by free space, but it isn't. How I should use css(scss) flex for that?
I don't know if I got what you wanted to do, but if you want <LeftPanel> to be 100% of the screen and <Chat> to be vertically expansive, you should set its CSS with the following properties:
.LeftPanel {
display: flex;
flex-direction: column;
height: 100vh;
}
<Logo>,<Profile> and <SocialButtons> should have a defined height. Like the following example:
.Logo {
height: 60px;
width: 100%;
}
.Profile {
height: 160px;
width: 100%;
}
.SocialButtons {
height: 50px;
width: 100%;
}`
An then, here's two possible tricks:
.Chat {
flex-grow: 1;
}`
With flex-grow you can set the expansive factor of an flex item over the others, read the docs here.
.Chat {
height: 100vh;
}`
If .Chat's parent doesn't wrap its content with flex-wrap, the .Chat will occupy the remaining space, of the parent's space.
Related
I have a column flex container, with one flex child containing an image
<div class="flex">
<p> Test </p>
<div class="flex-item">
<img class="img" src="https://i.imgur.com/E4Os1Fh.png">
</div>
</div>
All elements are given width 100% height 100% along the chain.
html, body {
height: 100%;
}
.flex {
display: flex;
width: 100%;
height: 100%;
flex-direction: column;
}
.flex-item {
flex: 1;
}
.img {
width: 100%;
height: 100%;
}
How come the image is not respecting the height properties and is taking up more space than the height of its parent element?
JSFiddle: https://jsfiddle.net/ohewn35k/4/
(You need to resize the window to be smaller than the natural image size to see the problem in action)
EDIT: The example in this question seems to be working fine, but it doesn't not work in my actual code. I have stripped my code down in developer tools and uploaded a zip file
https://www.mediafire.com/file/v32z4xrxnstyd3d/reproduce.7z/file
If you extract the file and open reproduce.html you'll see that the image element has a scrollbar as it's expanding passed its available space for some reason.
Once I fix this problem, I intend to add object-fit: contain to the image so it contains nicely within its available space.
Since you're using flexbox.
Your .flex-item becomes this:
.flex-item {
flex: 1;
}
Essentially you're are telling the flex item to use the maximum space available.
You can read about the flex property on MDN
Your CSS '.img' selector should just be 'img'
Try this
<div class="flex">
<div class="flex-item">
<img src="https://i.imgur.com/E4Os1Fh.png">
</div>
</div>
html, body {
height: 100%;
}
.flex {
display: flex;
width: 100%;
height: 100%;
flex-direction: column;
}
.flex-item {
width: 100%;
height: 100%;
}
img {
width: 100%;
height: 100%;
}
Trying to get cdk-virtual-scroll-viewport height to be equal to page height.
<div class="plServiceItemsList-list">
<cdk-virtual-scroll-viewport class="plServiceItemsList-listViewPort" itemSize="20">
When trying to use height 100%, I see no list
.plServiceItemsList-listViewPort {
height: 100%;
min-height: 100%;
}
The only way it will be displayed is specifying a height:
.plServiceItemsList-listViewPort {
height: 100px;
}
But this is not dynamic.
After #Chellappan suggested using vh, I thought my issue was solved, but actually, when the page size what bigger than the screen, it failed.
This is what I used:
.plServiceItemsList-listContainer {
display: flex;
flex-direction: column;
min-height: 100%;
}
.plServiceItemsList-listViewPort {
flex-grow: 1;
}
So I'm using flexbox to create the grid unfortunately, I'm a little stuck as to how to make the divs stack on top of each other. This is what it looks like when I hide overflow:auto and add position relative to the carddiv. I believe the divs are stacking on top but they don't look the right way.
this is what it looks like:
Image Link
https://imgur.com/a/1KsJDh7
What I want it to look like is this:
Except positon:absolute makes everything disappear.
I'm new to css/html so I'm not exactly sure what I'm doing wrong.
https://imgur.com/a/mrLsTdX
App.css
* {
/*overflow:auto*/
}
.App {
/*display: flex;*/
/*flex-wrap: wrap;*/
}
Card.css
.container{
background-color: yellow;
display: flex;
flex-flow: column;
text-align: center;
position: relative;
margin: 10% 10% 10%;
}
.cardDiv {
height: 100vh;
position: absolute;
}
.cardPicture {
background-color: blue;
height: 50vh;
}
.cardDescription {
background-color: green;
height: 50vh;
}
However, without position:absolute it looks like this which is what I want it to look like except it doesn't stack. I assume the first version is stacked which is why it only shows one div?
The code below is for the second image link:
https://imgur.com/a/mrLsTdX
App.css
* {
overflow:auto
}
.App {
/*display: flex;*/
/*flex-wrap: wrap;*/
}
Card.css
.container{
background-color: yellow;
display: flex;
flex-flow: column;
text-align: center;
position: relative;
margin: 10% 10% 10%;
}
.cardDiv {
height: 100vh;
}
.cardPicture {
background-color: blue;
height: 50vh;
}
.cardDescription {
background-color: green;
height: 50vh;
}
The cardDivs are being generated through a map function that is inserting the divs.
The html looks like this:
<div className='container'>
<div className="cardDiv">
<div className="cardPicture"></div>
<div className="cardDescription"></div>
</div>
</div>
Does anyone have any idea on what I could do make the divs stack up without disappearing?
I think the issue is the combination of a flex container and flex items that have been set to absolute positioning. When you set position: absolute on .cardDiv it takes all the cardDiv elements out of the flex flow, and without any width or content, the cardDiv's disappear. As an experiment, take your first CSS block and add a width (say, 50px) to .cardDiv. You should see the cards reappear, stacked and taking up 50 pixels horizontally.
When you set a element to display: flex or display: inline-flex, all the direct children of that element become flex items. You can see all the things that does to the children by default here, and the purpose of the various flex properties are there to manipulate how the children will be displayed along the axis you specify. If you set one of these flex-items to absolute positioning, however, it takes that element out of that flex configuration.
If I understand what you want correctly, I'm not sure you need the container to be flex at all. Try taking the flex properties out of the container, setting the cardDivs to position:absolute and setting width and height to conform to how much of the screen you want filled.
.container {
position: relative;
margin: 1rem;
}
.cardDiv {
position: absolute;
width: 100%;
height: 100vh;
}
.cardPicture {
background-color: blue;
height: 50%;
}
.cardDescription {
background-color: green;
height: 50%;
}
Let me know if this is not what you were looking for-- I figure you can adjust it to how you want the cards to appear. But that's them stacked and split 50-50 between picture and description.
I have a simple wrapper with 2 div elements in it.
I want the first one to gain 85% of the height and the second one to gain only 15% of the height.
It works when I set a fixed height to the wrapper. Though sadly my wrapper has a dynamic height.
Do you know how I can accomplish this?
I have also provided a plunker: http://plnkr.co/edit/HQpahfmRasij8Zougjkn?p=preview
Code:
.outer{
flex: 1;
display: flex;
flex-direction: column;
flex-basis: 0;
/* if i set the fixed height everthing works
though i do want a dynamic height
height: 800px; */
}
.main {
background-color: blue;
display: flex;
flex: 0 0 85%;
max-height: 85%;
flex-direction: row;
height: 400px;
}
.navigator {
background-color: red;
display: flex;
flex: 0 0 15%;
max-height: 15%;
flex-direction: row;
height: 400px;
}
<div class="outer">
<div class="main" >
<!-- this container should have 85% of the outer containers height -->
</div>
<div class="navigator" >
<!-- this container should have 15% of the outer containers height -->
</div>
</div>
You can do the initial (outer) layout without flex, as I can't see the point when it's not needed.
The requirement is the same though, that the .outer's parent need a height, either inherited or set.
html, body {
height: 100%;
margin: 0;
}
.outer {
height: 100%;
}
.main {
background-color: blue;
height: 85%;
display: flex; /* this is for main's children */
flex-direction: row; /* this is for main's children */
}
.navigator {
background-color: red;
height: 15%;
display: flex; /* this is for nav's children */
flex-direction: row; /* this is for nav's children */
}
<div class="outer">
<div class="main" >
<!-- this container should have 85% of the outer containers height -->
</div>
<div class="navigator" >
<!-- this container should have 15% of the outer containers height -->
</div>
</div>
You can try sizing the flex items with flex-grow instead of flex-basis or height.
In the following example, one flex item will occupy 85% of the available space in the container. The other flex item will take the remaining 15%.
HTML (no changes)
CSS
.outer {
display: flex;
flex-direction: column;
}
.main { flex-grow: 85; }
.navigator { flex-grow: 15; } /* flex-grow: 1 would work as well */
Revised Plunkr
Learn more about flex heights here: Heights rendering differently in Chrome and Firefox
if they are direct childs of body, then you first need to set height on patrents : html & body in order to have an inheritable value.
then outer is no longer needed, body is there already.
Set height to the smallest (and eventually a min-height) and request the other to grow via just : flex:1;.
html,
body {
height: 100%;
margin: 0;
}
body {
display: flex;
flex-direction: column;
}
.main {
flex: 1;
background: tomato;
}
.navigator {
height: 15%;
min-height: 2em;
background: lime;
}
<div class="main">
<!-- this container should have 85% of the outer containers height -->
main
</div>
<div class="navigator">
navigator
<!-- this container should have 15% of the outer containers height -->
</div>
http://plnkr.co/edit/R502OvyV2RR8GZ96UJvt?p=preview
comment pulled up here :
#JuHwon then, does the parent has a known size that it can be
inherited.
could you set up an example that shows your trouble.
% values need a reference to calculate a ratio from it, within flex imbrication height should be usable or something like
flex:85; & flex:15; http://codepen.io/gc-nomade/pen/pgOjXB
If I have a flexbox container containing multiple containers, how do I make the containers' contained items wrap before the containers themselves?
For example (codepen):
HTML
<div>
<row>
<column id="first">
<widget width=1 height=8></widget>
<widget width=1 height=8></widget>
</column>
<row id="second">
<widget></widget>
<widget></widget>
<widget></widget>
</row>
</row>
</div>
CSS
column, row, widget {
background: RGBA(0,0,0,.2);
margin: 1em;
display: flex;
flex-wrap: wrap;
align-items: top;
align-content: flex-start;
}
row {
flex-direction: row;
}
column {
flex-direction: column;
}
widget {
min-height: 100px;
flex-grow: 2;
flex-shrink: 1;
width: calc(25% - 3em);
min-width: 300px;
height: 100px;
flex-basis: 0;
padding: .5em;
display: block;
}
widget[width=1] {
flex-grow: 1;
min-width: 150px;
}
widget[width=4] {
flex-grow: 4;
min-width: 600px;
}
widget[width=8] {
flex-grow: 8;
min-width: 1200px;
}
widget[height=1] {
min-height: 150px;
}
widget[height=4] {
min-height: 600px;
}
widget[height=8] {
min-height: 1200px;
}
widget {
background: RGBA(200,0,20,.5);
}
I want the items in #second to wrap before #second itself wraps below #first. In other words, I always want to try wrapping the innermost items before trying to wrap the outermost ones, which seems to be the opposite of what happens by default. Is there any way to do this?
EDIT: There were requests for visual clarification.
2 containers with several items each:
Desired behavior, slightly smaller. Innermost items wrap before their containers.
Desired behavior, smaller still.
Desired behavior, smallest. After the innermost items can't wrap any more, the containers finally wrap.
What actually happens: the containers wrap before their contents.
I don't believe there are any flex properties that make this process simple and easy. However, the flexbox specification does allow for absolutely-positioned flex children. So with a combination of media queries and absolute positioning, the flex items within the container can be made to wrap before the container itself wraps.
Try this:
HTML (no changes)
CSS (add media queries and absolute positioning)
#second { position: relative; }
/* establishes nearest positioned ancestor for absolute positioning */
#media screen and (max-width: 1000px) {
#second widget:nth-child(3) {
position: absolute;
left: 0;
bottom: 0;
width: 90%; }
}
#media screen and (max-width: 800px) {
#second { height: 375px; }
#second widget:nth-child(2) {
position: absolute;
left: 0;
bottom: 127px;
width: 75%; }
#second widget:nth-child(3) {
position: absolute;
left: 0;
bottom: 0;
width: 75%; }
}
/* final media query removes absolute positioning and restores flex properties */
#media screen and (max-width: 600px) {
column, row, widget { flex-wrap: wrap; }
#second widget {
position: static;
width: calc(25% - 3em);
min-width: 300px;
}
Revised Codepen
Note that although this code does what the question asks – it wraps flex items in their container before the container itself wraps – it's only meant to convey the basic concept of the solution. Issues like margin and width for flex items, which I considered beyond the scope of this question, may still need to be addressed.