Push footer to bottom of flexbox - html

I want my ReactModal to sit at the bottom of the viewport, but it's sitting right underneath the Results, and all I've tried so far has failed to correct the problem. I know this is a common issue and there are many solutions online, but there is something about how I've got my CSS set up that is not allowing the flex-grow property to work the way I expect it to. Any ideas?
JSX:
<div className='App'>
<div className='main-content'>
<Header/>
<Results results={testData}/>
</div>
<ReactModal/>
</div>
CSS:
* {
margin: 0;
padding: 0;
}
body, html {
height: 100%;
}
.App {
text-align: center;
display: flex;
flex-direction: column;
margin: 0 auto;
padding: 1.5rem;
align-content: center;
min-height: 100vh;
}
.main-content {
flex-grow: 1;
}

flex-grow specifies how much of the remaining space in the flex container should be assigned to the item. If your trying to place the ReactModal to the bottom of the viewport you would probably want to use the example below.
Edited
Codepen Example
If you look at the css file, you would add this:
position: fixed;
bottom: 0;
To your ReactModal component and it would place it to the bottom of the page. You would not use flex-grow because it is totally useless in this situation.
Hope this helps.

Related

Elements Being Pushed Above Page even with Overflow set to scroll

I am having a problem in one of my projects. I set the container to be 100vh and 100vw and overflow to be "auto." However, even with these height and width properties, and the overflow, it seems that elements are being pushed out of the div still, and I am not sure why. For example, in this div I have an h1, and an image. I have the h1 displaying above the image; when I have a screen height that is too small, I want the user to be able to scroll. However, even with the overflow set, the h1 gets pushed above the page completely, so it cannot be seen, and cannot be scrolled up to, only the image and everything below it can be scrolled.
My JSX:
<div id="SingleProjectContainer">
<h1>{name}</h1>
{images.map((image, idx) => (
<div key={idx}>
<img src={image} alt="Project Picture" />
</div>
))}
</div>
and my CSS:
#SingleProjectContainer {
top: 0;
padding: 10px;
margin: 0;
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
flex-direction: column;
overflow: auto;
flex: auto;
}
#SingleProjectContainer h1 {
font-size: 3em;
margin: 10px;
color: white;
}
I have tried many combinations of position and margin settings and nothing seems to work. I am not sure if there is another css property I am missing. Any help will be appreciated!
Comment to answer:
It is a flexbox issue. Remove justify-content and align items and use margin: auto on the children instead.

Vertically Aligning Flexbox Items Correctly

I am working on creating a footer for my app where there are 3 main components. The current footer container is:
.footer-container {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: $bar-color;
Each child element has
display: inline-block
And it produces the vertical alignment that I am looking for:
However, I am looking to center the 3 components equally across the footer. The flexbox space-between option looked like it would fit best, therefore I tried it. In terms of horizontal alignment, it is perfect, however when I add
display: flex;
align-items: center;
to the footer-container class it moves the first item down. Like this:
I'm not sure why this is occurring. How would I fix it?
A flexbox has two main axes. You are aligning items along one axis of the flex container with align-items, but you also need to include the justify-content property for aligning along the other main axis of the flex container. That is why you see the uneven row.
When you specify both axes of the container with CSS properties justify-content and align-items, using space-between works as expected. Flexbox docs
html, body {
margin: 0;
padding: 0;
background: #111;
}
:root {
--footer-color: #000;
}
.footer-container {
display: flex;
align-items: center;
justify-content: space-between;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: var(--footer-color);
}
.footer-container p {
display: inline-block;
color: #FFF;
}
<html>
<body>
<div class="footer-container">
<p>Connected</p>
<p>12:00:59 AM</p>
<p>Version 0.0.1 (Latest Version)</p>
</div>
</body>
</html>

Using flexbox to center dynamical objects

When the game starts, flexbox centering works great (on static objects).
During the game progress both (title and remain divs) change their values/sizes, so that causes to constantly adjusting center positioning by flexbox (all divs in header are moving).
I want each div inside header to stay "fixed" during the game.
Is that possible just by using flexbox or should i use another approach?
Should I position each element individually?
You can watch header behaviour on the remote server:
https://stacho163.000webhostapp.com/firstLevel.html
body {
margin: 0;
width: 100%;
height: 100%;
}
header {
display: flex;
justify-content: space-around;
align-items: center;
background-color: white;
}
#game-window {
position: absolute;
width: 90vw;
height: 90vw * 16/9;
top: 50%;
left: 50%;
transform: translate(-50%, -46%);
background-color: gray;
}
<body>
<header>
<div id="lifes">
Life1 Life2 Life3
</div>
<div id="title">
Title (changes when you win)
</div>
<div id="remain">
Remaining: (from 100 to 0)
</div>
</header>
<canvas id="game-window"></canvas>
</body>
https://jsfiddle.net/nfzj183t/14/
I am asking, as I don't have much experience in web stuff and i want to use the correct approach to solve this simple problem.
Thank you in advance for your tips :)
One approach could be to use grid for the main layout and inside every element of grid, use flexbox components.
header would be something like:
header {
display: grid;
grid-template-columns: repeat(3,1fr);
grid-template-rows: 10vh;
}
And you will need to make every column a "display: flex;" container. This would be an example with the "lifes":
#lifes{
display: flex;
align-items: center;
justify-content: center;
}
I can show you more complex examples if needed.
Reference: https://gridbyexample.com/examples/

Children of overflowing flex container exceed container [duplicate]

This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
Closed 4 years ago.
I've been on this for a while now and tried a lot of the solutions I've seen across different Stackoverflow questions / blogposts / ... But I honestly can't figure out what's going wrong.
I've got a flexed div with two divs in there. The top div A has a fixed height, the other div B fills the rest using flex: 1;. If the screen is resized and it's smaller than the height of A + B together, then B will start overflowing. I want it to scroll, but I also want the content to be fully visible when scrolling. For some reason which I can't figure out, the content renders out of the top of div B as you can see in this screenshot of my fiddle:
Some of the previously asked questions got me somewhere. For example setting the body to height: auto;, but then when my screen is bigger than A + B it can't be center aligned anymore. min-height: 0; also doesn't seem to help in this case.
How can I make sure my container overflows but will fully show the content of it?
You can solve the issue by giving .second:
flex-basis: auto;
flex-shrink: 0;
Or, with shorthand: flex: 1 0 auto;
Working example:
html, body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
body {
display: flex;
flex-direction: column;
}
.second {
flex: 1 0 auto;
background: blue;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
min-height: 0;
overflow: auto;
}
.container {
display: flex;
flex-direction: column;
width: 100%;
max-width: 500px;
min-height: 0;
/* added this to make it obvious. Obviously, not needed */
padding: 2rem 0;
}
.container-child {
height: 110px;
background: green;
width: 100%;
}
.container-child:not(:last-child) {
margin-bottom: 30px;
}
<div class="second">
<div class="container">
<div class="container-child"></div>
<div class="container-child"></div>
<div class="container-child"></div>
</div>
</div>
I added some top and bottom padding to .container to make it obvious that it's working - but it's not needed.
Now let's look at why this is happening. When you apply .second { flex:1; } it means:
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
... which allows it to have a smaller size than its contents.
Whenever you have a bigger child centered in a smaller parent, the browser won't provide a scrollbar to top (or to left, when horizontal), because then , if the top of the parent and the top of the child coincide and the child is bigger than the parent, the child is no longer centered, is it?
The same happens when using other centering techniques and you center a bigger child in a smaller parent.
To fix the problem, you need to prevent the child from outgrowing the parent.
In this case, it meant sizing .second based from its content (flex-basis: auto) and not allowing it to shrink: (flex-shrink: 0;).
To better visualize the issue, consider this example:
.left, .right {
position: relative;
border: 1px solid red;
padding: 1rem 5rem;
}
.left {
left: -5rem;
}
.right {
right: -5rem;
}
<div class="left">
I'm taken left
</div>
<div class="right">
I'm taken right
</div>
If the browser provided scrollbars to allow you to scroll to beginning of .left, it would mean that left: -5rem did not apply. I hope that makes sense, I can't explain it better.

Row flex container nested in column flex container with explicit height is rendered differently in Chrome and Firefox

This simple example is rendered differently in Chrome than in Firefox or Edge; in one case the main flex item shrinks to fit the flex container (set to viewport height), but in the other it doesn't. Is the rendering difference based on some bug, or is it something else?
html, body {
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
flex-direction: column;
}
main {
display: flex;
background: #f60;
}
<main>
<!-- any element longer than the viewport -->
<img src="https://i.redd.it/e7a2rxhf1yrx.jpg">
</main>
Edit: a more clear example.
It seems flexbox do not scale down replaced elements like images (that have an intrinsic aspect ratio) correctly in browsers at the moment, at least! And I believe this is what happens here.
(I read something similar here and met with an issue with image as a flex item here)
Solution:
One solution is using max-height: 100% on the flex item or even you can use flex-basis: 100% if it should always fill the parent height:
html, body {
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
flex-direction: column;
}
main {
display: flex;
background: #f60;
max-height: 100%;
}
<main>
<!-- any element longer than the viewport -->
<img src="https://i.redd.it/e7a2rxhf1yrx.jpg">
</main>
Seems to be an inconsistency across browsers regarding how they may interpret attributes of flex boxes within flex boxes, but I managed to get it to work consistently across browsers by setting the height of the inner box to 0 and then setting the flex box to grow 100% (or 1) within the outer flex box. Here's an example using your code.
html, body {
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
flex-direction: column;
}
main {
display: flex;
background: #f60;
height: 0;
flex-grow: 1;
}
<main>
<!-- any element longer than the viewport -->
<img src="https://i.redd.it/e7a2rxhf1yrx.jpg">
</main>