Flexbox - align : center / justify : center with unknown height - html

I am trying to split the page into 4 equal squares with centered content. The issue I am having is centering the content due to the .flex-item divs having a viewport height, I am looking for a full flexbox solution, Thank you.
I have tried the following from resources:
justify-content center
align-items center
.flex-container {
display: -webkit-flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
}
.color_1 {
background: tomato;
}
.color_2 {
background: LightGreen;
}
.color_3 {
background: PowderBlue;
}
.color_4 {
background: SteelBlue;
}
.flex-item {
-webkit-flex: 1 0 auto;
flex: 1 0 auto;
width: 50%;
height: 50vh;
}
<div class="flex-container">
<div class="flex-item color_1"><div class="inner"><p>inner</p></div></div>
<div class="flex-item color_2"><div class="inner"><p>inner</p></div></div>
<div class="flex-item color_3"><div class="inner"><p>inner</p></div></div>
<div class="flex-item color_4"><div class="inner"><p>inner</p></div></div>
</div>

Make the .flex-item be flex containers, and use justify-content and align-items to center their content:
.flex-item {
display: flex;
justify-content: center;
align-items: center;
}
body {
margin: 0;
}
.flex-container {
display: flex;
flex-wrap: wrap;
}
.color_1 {
background: tomato;
}
.color_2 {
background: LightGreen;
}
.color_3 {
background: PowderBlue;
}
.color_4 {
background: SteelBlue;
}
.flex-item {
flex: 1 0 auto;
width: 50%;
height: 50vh;
display: flex;
justify-content: center;
align-items: center;
}
<div class="flex-container">
<div class="flex-item color_1"><div class="inner">inner</div></div>
<div class="flex-item color_2"><div class="inner">inner</div></div>
<div class="flex-item color_3"><div class="inner">inner</div></div>
<div class="flex-item color_4"><div class="inner">inner</div></div>
</div>

Related

Make it so parent element not grow when child expands

I have a flex-box layout where I'm using flex-grow: 1 on multiple elements in order to distribute the layout evenly. However, when I add contents to one of the elements, it immediately expands out and ruins the even layout.
How can I make it so that the parents stay evenly distributed? Or would it be easier to just change it to width: 50% in order to fix that problem? Below is the code.
.app-container {
display: flex;
background: orange;
min-height: 100vh;
min-width: 100vw;
}
.sideBar-container {
display: flex;
background: pink;
width: 10%;
}
.info-container {
display: flex;
flex-direction: column;
flex-grow: 1;
height: 100vh;
}
.top-container {
display: flex;
background: green;
flex-grow: 1;
}
.bottom-container {
flex-grow: 1;
display: flex;
background: wheat;
}
.top-left {
display: flex;
flex-direction: column;
background: blue;
flex-grow: 1;
}
.top-right {
display: flex;
background: red;
flex-grow: 1;
}
.top-two {
display: flex;
justify-content: space-around;
align-items: center;
flex-grow: 1;
background: gold;
}
.bottom-two {
display: flex;
justify-content: space-around;
align-items: center;
flex-grow: 1;
background: cornflowerblue;
}
.number-appts {
background: aqua;
flex-basis: 35%;
height: 45%;
}
.projected-revenue {
background: aquamarine;
flex-basis: 45%;
}
.projected-costs {
background: burlywood;
}
.projected-profit {
background: darkgray;
}
.appointment-consult {
background: seagreen;
}
<div className="app-container">
<div className="sideBar-container">
</div>
<div className="info-container">
<div className="top-container">
<div className="top-left">
<div className="top-two">
<div className="number-appts">test</div>
<div className="projected-revenue">this</div>
</div>
<div className="bottom-two">
<div className="projected-costs">here</div>
<div className="projected-profit">testing</div>
</div>
</div>
<div className="top-right">
<div className="appointment-consult"></div>
</div>
</div>
<div className="bottom-container"></div>
</div>
</div>
I figured it out. Changed my flex-grow: 1 to flex:1 as creating a rule where flex-basis is now 0px rather than auto stops the css from looking inward at the content

CSS Flexbox: How to arrange three Items in a Row, but two of them below each other?

Assumed we have this simple CSS flexbox layout:
.flex-container {
display: flex;
justify-content: space-between;
align-items: center;
height: 100vh;
}
.flex-item:nth-child(1) {
order: 0;
}
.flex-item:nth-child(2) {
order: 1;
align-self: flex-start;
}
.flex-item:nth-child(3) {
order: 1;
align-self: flex-end;
}
.flex-item {
width: 50px;
height: 50px;
background:red;
}
<div class="flex-container">
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
</div>
Description of the issue:
Unfortunately flex-item 2 and 3 are not located at the right edge below each other, although they are both set to order: 1.
Question:
How can I arrange flex-item 2 to be at the upper right edge, while flex-item 3 is located at the lower right edge (item 1 should remain vertically centered at left edge)?
I did not yet figure out on how to arrange all three items in a row, but the latter two items below each other within this row.
I guess you are trying to do that.
* {
padding: 0;
margin: 0;
}
.flex-container {
display: flex;
justify-content: space-between;
align-items: center;
height: 100vh;
}
.flex-container-col {
display: flex;
flex-direction:column;
justify-content: space-between;
align-items: center;
height: 100vh;
}
.flex-item:nth-child(1) {
order: 0;
align-self: flex-center;
}
.box {
width: 50px;
height: 50px;
background:red;
}
<div class="flex-container">
<div class="flex-item box"></div>
<div class="flex-item flex-container-col">
<div class="box"></div>
<div class="box"></div>
</div>
</div>
If you want to both item 2 and 3 top of the right edge together, you can delete justify-content in flex-container-col so they will unite at the top. Hope works.
If you want a block to be at up right, one at the center and other at the bottom right, then you can use this snippet. The flex item 1 should be at flex-start, the flex item 3 should be at the flex end and the flex item 2 should be where it is.
* {
padding: 0;
margin: 0;
}
.flex-container {
display: flex;
justify-content: space-between;
align-items: center;
height: 100vh;
}
.flex-item:nth-child(1) {
order: 0;
align-self: flex-start;
}
.flex-item:nth-child(2) {
order: 1;
}
.flex-item:nth-child(3) {
order: 1;
align-self: flex-end;
}
.flex-item {
width: 50px;
height: 50px;
background:red;
}
<div class="flex-container">
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
</div>

Flex Box Behavior

I cannot understand WHY I am not getting this:
.container {
width: 600px;
height: 400px;
border: 3px solid green;
}
.cg-panel {
display: flex;
flex-flow: column;
align-items: stretch;
justify-content: center;
}
.cg-panel .content {
flex: 1;
background-color: tomato;
}
<div class="container">
<div class="cg-panel">
<div class="content"></div>
</div>
</div>
I, for the life of me, cannot understand why the content panel does not vertically stretch the entire container. What is the purpose of "flex:1" if it isn't going to work? Am I not reading the documentation correctly?
There's nothing in your CSS that is expanding the height of .cg-panel to fit its parent .container.
Adding height: 100%; to .cg-panel fixes this:
.container {
width: 600px;
height: 400px;
border: 3px solid green;
}
.cg-panel {
display: flex;
flex-flow: column;
align-items: stretch;
justify-content: center;
height: 100%; /* add this */
}
.cg-panel .content {
flex: 1;
background-color: tomato;
}
<div class="container">
<div class="cg-panel">
<div class="content"></div>
</div>
</div>

CSS flex grow does not work with added div on top

Consider the following fiddle: https://jsfiddle.net/7naxprzd/1/
Requirements are:
two columns with header and contents
tops of columns should align
bottom of columns should align
on top of each column there should be a horizontally centered arrow
The code is working properly if the arrows are eliminated by deleting the div with class .arrow-wrapper, but I need the arrows.
A solution could be to absolute position the arrow, but is there a way to solve this layout issue with flex without absolute positioning the arrow?
Should work for modern browsers and IE11.
.row-wrapper {
display: flex;
}
.col-wrapper-outer {
display: flex;
flex-wrap: wrap;
}
.arrow-wrapper {
width: 100%;
text-align: center;
font-size: 30px;
}
.col-wrapper {
width: 100%;
display: flex;
flex-direction: column;
border: 2px solid red;
color: white;
}
.col-wrapper .header {
background: blue;
}
.col-wrapper .contents {
flex: 1 0 auto;
background: green;
}
<div class="row-wrapper">
<div class="col-wrapper-outer">
<div class="arrow-wrapper">
↓
</div>
<div class="col-wrapper">
<div class="header">Please align tops.</div>
<div class="contents">Let me grow.</div>
</div>
</div>
<div class="col-wrapper-outer">
<div class="arrow-wrapper">
↓
</div>
<div class="col-wrapper">
<div class="header">please align tops.</div>
<div class="contents">Let me grow.<br>Please<br>align<br>bottoms.</div>
</div>
</div>
</div>
In your div with class col-wrapper-outer, instead of this:
.col-wrapper-outer {
display: flex;
flex-wrap: wrap;
}
Use this:
.col-wrapper-outer {
display: flex;
flex-direction: column;
}
Then add flex: 1 to .col-wrapper so it takes the full height of the container.
revised fiddle
.row-wrapper {
display: flex;
}
.col-wrapper-outer {
display: flex;
/* flex-wrap: wrap; */
flex-direction: column; /* NEW */
}
.arrow-wrapper {
width: 100%;
text-align: center;
font-size: 30px;
}
.col-wrapper {
flex: 1; /* NEW */
width: 100%;
display: flex;
flex-direction: column;
border: 2px solid red;
color: white;
}
.col-wrapper .header {
background: blue;
}
.col-wrapper .contents {
flex: 1 0 auto;
background: green;
}
<div class="row-wrapper">
<div class="col-wrapper-outer">
<div class="arrow-wrapper">
↓
</div>
<div class="col-wrapper">
<div class="header">Please align tops.</div>
<div class="contents">Let me grow.</div>
</div>
</div>
<div class="col-wrapper-outer">
<div class="arrow-wrapper">
↓
</div>
<div class="col-wrapper">
<div class="header">please align tops.</div>
<div class="contents">Let me grow.
<br>Please
<br>align
<br>bottoms.</div>
</div>
</div>
</div>

Anchor controls using flexbox

I'm trying to create a visual layout using Flexbox.
In this layout, controls are arranged in rows. Some of the rows will have a predefined height, and some of the rows will be anchored to both the top and bottom of the screen, which means they'll stretch their height to occupy all available space.
I've got a working layout that will achieve this, but there seems to be an issue when the rows with predefined height need stretch because their contents no longer fit. They seem to not actually be stretching, which causes them to overlap with one another.
Anyone know how to get the rows to resize in height, properly?
You can have a look at the current status here:
https://jsfiddle.net/cgledezma1101/o9zwa7na/
I'm using the following CSS for my containers:
.main-container {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
height: 100vh;
}
.row {
flex: 1 1 auto;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
width: 100%;
}
.row2 {
height: 200px;
min-height: 200px;
}
.row1 {
height: 100px;
min-height: 100px;
}
.not-anchored {
height: 100px;
}
.anchored {
height: 100%;
}
A fixed height on the container means it cannot expand to accommodate a taller layout. Hence, flex items are forced to overlap on smaller screens.
Instead of height: 100vh, use min-height: 100vh.
Also, remove fixed heights on flex items. They override align-items: stretch.
revised fiddle
.main-container {
display: flex;
flex-flow: column nowrap;
min-height: 100vh;
}
.row {
display: flex;
flex-flow: row wrap;
}
.row.anchored { flex: 1; }
body { margin: 0; }
.item12 {
flex: 1 1 100px;
height: 200px;
min-width: 100px;
background: tomato;
}
.item21 {
flex: 1 1 200px;
height: 100px;
min-width: 100px;
background: deepskyblue;
}
.item {
text-align: center;
color: white;
font-weight: bold;
font-size: 3em;
border: 1px dashed black;
line-height: 100px;
margin-left: auto;
margin-right: auto;
}
.item.anchored {
flex: 1;
/* height: 100%; */
min-height: 150px;
background: hotpink;
}
<body>
<div class="main-container">
<div class="row row2 not-anchored">
<div class="item item12">
1.1
</div>
<div class="item item12">
1.2
</div>
<div class="item item12">
1.3
</div>
</div>
<div class="row anchored">
<div class="item anchored">
A.1
</div>
</div>
<div class="row row1 not-anchored">
<div class="item item21">
2.1
</div>
<div class="item item21">
2.2
</div>
</div>
<div class="row anchored">
<div class="item anchored">
A.2
</div>
</div>
</div>
</body>
It seems the issue arises from giving the .main-container element a height: 100vh;. Changing that to height: 100%; seems to fix it.
.main-container {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
height: 100%;
}
.main-container {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
height: 100%;
}
.row {
flex: 1 1 auto;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
width: 100%;
}
.row2 {
height: 200px;
min-height: 200px;
}
.row1 {
height: 100px;
min-height: 100px;
}
.not-anchored {
height: 100px;
}
.anchored {
height: 100%;
}
.item12 {
flex: 1 1 100px;
height: 200px;
min-width: 100px;
background: tomato;
}
.item21 {
flex: 1 1 200px;
height: 100px;
min-width: 100px;
background: deepskyblue;
}
.item {
text-align: center;
color: white;
font-weight: bold;
font-size: 3em;
border: 1px dashed black;
line-height: 100px;
margin-left: auto;
margin-right: auto;
}
.item.anchored {
flex: 1 1 100%;
height: 100%;
min-height: 150px;
background: hotpink;
}
<body>
<div class="main-container">
<div class="row row2 not-anchored">
<div class="item item12">
1.1
</div>
<div class="item item12">
1.2
</div>
<div class="item item12">
1.3
</div>
</div>
<div class="row anchored">
<div class="item anchored">
A.1
</div>
</div>
<div class="row row1 not-anchored">
<div class="item item21">
2.1
</div>
<div class="item item21">
2.2
</div>
</div>
<div class="row anchored">
<div class="item anchored">
A.2
</div>
</div>
</div>
</body>
The following produces: