Using flexbox to center dynamical objects - html

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/

Related

Problems with buttons / grid in HTML/CSS

i have problems with the setup of the buttons. I'm unsure if i need a grid system or not?
I want it to look like this example:
No code yet as i am unsure of where to start, and what to start with.
If somebody can help then hanks in advanced!
You can use with flex, justify-content, align-items like example below:
.wrapped {
display: flex;
flex-direction: column;
align-items: center;
width: 500px;
}
.avatar {
width: 50px;
height: auto;
}
button {
width: 200px;
}
.div1 {
display: flex;
justify-content: center;
padding: 10px;
}
.div2 {
display: flex;
flex-direction: column;
padding: 10px;
}
.div2 button{
width: 200px;
margin: 6px;
padding: 5px;
}
.div3 {
display: flex;
padding: 10px;
margin-left: 0px;
align-items: center;
}
.div3 button {
width: 40px;
height: 30px;
margin-left: 160px;
}
.bell {
width: 30px;
padding: 10px;
flex-basis: 1000px;
}
<section class="wrapped">
<div class="div1">
<button>At campus</button>
<img class="avatar" src="https://media.istockphoto.com/vectors/user-icon-flat-isolated-on-white-background-user-symbol-vector-vector-id1300845620?k=20&m=1300845620&s=612x612&w=0&h=f4XTZDAv7NPuZbG0habSpU0sNgECM0X7nbKzTUta3n8=" />
</div>
<div class="div2">
<button>Q & A</button>
<button>Klasser</button>
<button>Grupper</button>
<button>Chat</button>
</div>
<div class="div3">
<img class="bell" src="https://www.iconpacks.net/icons/1/free-bell-icon-860-thumb.png"/>
<button>Help</button>
</div>
</section>
for sure a grid would perfectly work for your design. However,you don't explicitly need a grid to obtain that result. Css flexbox display (display:flex) would also work and maybe fit your needs. Even display: block would work.
If you need a web layout that only consists of rows or columns, then Flexbox is the best model to use. However, if you have a complex, multi-row and multi-column layout, then you'll want to use CSS Grid.
Have a look for more details: https://www.webdesignerdepot.com/2018/09/grid-vs-flexbox-which-should-you-choose/
Here is a simple set-up for your design with flexbox in mind:
Suppose your first component (logo and user profile) are inside one div. You can use display:flex and flex-direction: row to display them in one line, and justify-content: space-between so the elements fill the entire row.
Then you have 4 buttons. You can use another div and set the flex-direction to column. Change the width of the div and of the buttons as you need.
Basically, the last div would be similar to the first one.
For each div you can specify different width or height.

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>

Push footer to bottom of flexbox

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.

How to stack divs on top of each other? Position absolute isn't working

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.

CSS Flex: Vertically centered items that are taller than the viewport [duplicate]

This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
Closed 5 years ago.
So i'm using CSS flex to create vertically centered Modal popups ( align-items: center; ). The issue is that when the Modal is taller than the viewport (and is scrollable), the Flex prioritizes the 'centered-ness' and thus makes the top of the modal inaccessible.
Has anyone found ways around this? I could use a media query to make all Modals flex-start aligned, however i still want smaller modals to be vertically centered.
I had thought of trying to make the modal flex-shrink; to always fit 100% of the viewport, but it needs to scroll (and allow content to fit in further down the page) so not sure!
.outer {
display: flex;
align-items: center;
}
Thanks to #Pete for answering this:
The solution was setting max-height: 100%; and overflow: auto; (i had previously had overflow: visible; which caused issue.
I also found another method:
by placing the following flex properties on the 'outer outer' container (in this case, we're using ReactModal, so there's ReactModalPortal).
So we do
```.ReactModalPortal {
display: flex;
align-items: flex-start;
.innerContainer {
display: flex;
align-items: center;
}
}
```
i suppose by putting flex-start on the parent, it always ensures the content 'begins' at the top of the window.
Here you go
.parent{
top:50px;
}
.parent,
.child {
position: relative;
width: 50px;
height: 50px;
margin: auto;
background: #CCC;
}
.child {
position: relative;
width: 25px;
height: 100px;
margin: auto;
background: #000;
top: 50%;
transform: translate(0, -50%);
}
<div class="parent">
<div class="child"></div>
</div>