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
I have a container div that its content can grow vertically. I used overflow-y: auto for the container to make my page look good. But I need to place everything in the center when the content's height is smaller than the container's. So I used flexbox to do that. But the problem is that I can't scroll completely to see the top part of the contents.
Here is a simple example of the problematic code:
<html lang="en">
<head>
<style>
.container {
width: 20rem;
height: 20rem;
background-color: red;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
overflow-y: auto;
}
.child {
width: 10rem;
height: 40rem;
background-color: blue;
flex-shrink: 0;
}
.top {
width: 1rem;
height: 1rem;
background-color: green;
}
</style>
</head>
<body>
<div class="container">
<div class="child">
<div class="top"></div>
</div>
</div>
</body>
</html>
One of the solutions to this problem is to use the reverse order of the elements in the flex-container, i.e. in your case, using flex-direction: column-reverse instead of flex-direction: column.
Example #1 below:
.container {
width: 20rem;
height: 20rem;
background-color: red;
display: flex;
justify-content: center;
flex-direction: column-reverse;
align-items: center;
overflow-y: auto;
}
.child {
width: 10rem;
min-height: 0;
height: 40rem;
background-color: blue;
flex-shrink: 0;
max-height: 150%;
}
.top {
width: 1rem;
height: 1rem;
background-color: green;
}
<div class="container">
<div class="child">
<div class="top">test</div>
</div>
</div>
The second solution is to consider using for center alignment, you can also use justify-content: space-between and pseudo-elements ::after and ::before.
Example #2 below:
.container {
width: 20rem;
height: 20rem;
background-color: red;
display: flex;
justify-content: space-between;
flex-direction: column;
align-items: center;
overflow-y: auto;
}
.container::before,
.container::after {
content: '';
}
.child {
width: 10rem;
min-height: 0;
height: 40rem;
background-color: blue;
flex-shrink: 0;
max-height: 150%;
}
.top {
width: 1rem;
height: 1rem;
background-color: green;
}
<div class="container">
<div class="child">
<div class="top">test222</div>
</div>
</div>
I am trying to style a div that has two children, with flexbox and flex-wrap, without media-queries, that at a certain width is space-between, but once it is a single column is centered (as opposed to currently where once it wraps it's like flex-start). Hopefully that makes sense.
I think this is the relevant code, basically when it wraps, i would like space between to become center:
HTML and CSS
.content-container {
display: flex;
justify-content: center;
width: 100%;
}
.content {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
width: 82%;
}
.content h1 {
min-width: 20rem;
}
.content h6 {
min-width: 15.5rem;
}
<div class="content-container">
<div class="content">
<h1>'content1'</h1>
<h6>'content2'</h6>
</div>
</div>
I hope this fits your needs.
Since I don't believe that there is a way to solve your problem using only native CSS (i.e. no media queries, and I assume no JS), I let myself change the space-between to space-around (since you gave .content 82% there is not much of a difference).
if you do not want to use space-around, I find it hard for me to believe that there is a solution without media-queries \ JS.
.content-container {
display: flex;
justify-content: center;
width: 100%;
}
.content {
display: flex;
flex-wrap: wrap;
place-items: center;
justify-content: space-around;
width: 100%;
}
h1 {
width: min-content;
}
h6 {
width: min-content;
}
<div class="content-container">
<div class="content">
<h1 class="content__1">'content1'</h1>
<h6 class="content__2">'content2'</h6>
</div>
</div>
Do you want like this:
.content-container {
display: flex;
justify-content: center;
width: 100%;
}
.content {
display: flex;
flex-wrap: wrap;
justify-content: center;
text-align: center;
width: 82%;
}
.content h1 {
min-width: 20rem;
}
.content h6 {
min-width: 15.5rem;
}
<div class="content-container">
<div class="content">
<h1>'content1'</h1>
<h6>'content2'</h6>
</div>
</div>
I'm afraid it's impossible to achieve what you want the way you want (i.e., CSS without a #media query).
Solution 1: CSS without a #media query
If you don’t want to use a #media query, then look at Solution 1. But space-around is a different thing than space-between because space-between will push your two elements all the way to the left and right when they’re not stacked above each other, while space-around will not do so.
An example of space-between:
An example of space-around:
.content-container {
display: flex;
justify-content: center;
width: 100%;
}
.content {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
width: 82%;
text-align: center;
line-height: 50px;
border: 2px solid red;
}
.content h1 {
min-width: 20rem;
background-color: #DCDCDC;
}
.content h6 {
min-width: 15.5rem;
background-color: #DCDCDC;
}
<div class="content-container">
<div class="content">
<h1>Content 1</h1>
<h6>Content 2</h6>
</div>
</div>
If Solution 1 is good enough for you, then you don’t need to read further. But there are many better options on the table. If you’re not limited and can make changes to your code, then I think you should look at other possible solutions below. You can use different approaches to achieve what you want if you want your two elements to be pushed all the way to the left and right when they’re not stacked above each other.
The reason why this can’t be done without using a #media query, JavaScript or jQuery is that CSS on its own can’t “switch” from space-between to space-around when your two elements get stacked above each other. You need to define some rules using a #media query, JavaScript or jQuery so that CSS will change from space-between to space-around at a specific window width (i.e., exactly when your two elements get stacked above each other). See other possible solutions below.
Solution 2: CSS with a #media query
.content-container {
display: flex;
justify-content: center;
width: 100%;
}
.content {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
width: 82%;
text-align: center;
line-height: 50px;
border: 2px solid red;
}
.content h1 {
min-width: 20rem;
background-color: #DCDCDC;
}
.content h6 {
min-width: 15.5rem;
background-color: #DCDCDC;
}
#media only screen and (max-width: 708px) {
.content {
justify-content: space-around;
}
}
<div class="content-container">
<div class="content">
<h1>Content 1</h1>
<h6>Content 2</h6>
</div>
</div>
Solution 3: JavaScript
window.onload = function() {
if (window.innerWidth < 709) {
document.getElementById("content").style.justifyContent = "space-around";
} else {
document.getElementById("content").style.justifyContent = "space-between";
}
}
window.onresize = function() {
if (window.innerWidth < 709) {
document.getElementById("content").style.justifyContent = "space-around";
} else {
document.getElementById("content").style.justifyContent = "space-between";
}
}
.content-container {
display: flex;
justify-content: center;
width: 100%;
}
.content {
display: flex;
flex-wrap: wrap;
width: 82%;
text-align: center;
line-height: 50px;
border: 2px solid red;
}
.content h1 {
min-width: 20rem;
background-color: #DCDCDC;
}
.content h6 {
min-width: 15.5rem;
background-color: #DCDCDC;
}
<div class="content-container">
<div class="content" id="content">
<h1>Content 1</h1>
<h6>Content 2</h6>
</div>
</div>
Solution 4: jQuery
$(window).on('load', function() {
if ($(window).width() < 709) {
$(".content").css("justify-content", "space-around");
} else {
$(".content").css("justify-content", "space-between");
}
});
$(window).on('resize', function() {
if ($(window).width() < 709) {
$(".content").css("justify-content", "space-around");
} else {
$(".content").css("justify-content", "space-between");
}
});
.content-container {
display: flex;
justify-content: center;
width: 100%;
}
.content {
display: flex;
flex-wrap: wrap;
width: 82%;
text-align: center;
line-height: 50px;
border: 2px solid red;
}
.content h1 {
min-width: 20rem;
background-color: #DCDCDC;
}
.content h6 {
min-width: 15.5rem;
background-color: #DCDCDC;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div class="content-container">
<div class="content">
<h1>Content 1</h1>
<h6>Content 2</h6>
</div>
</div>
P.S. I added text-align: center; and line-height: 50px; to the .content class because if you really want to have your content centered then you also need to center text horizontally and vertically inside your containers. This is a quick fix, you can remove that if you want. Also, border: 2px solid red; is added to the .content class so you can better understand the difference between space-between and space-around.
Try this.
.content-container {
display: flex;
justify-content: center;
width: 100%;
text-align:center;
}
.content {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
width: 82%;
text-align:center;
}
.content h1 {
min-width: 20rem;
}
.content h6 {
min-width: 15.5rem;
}
<div class="content-container">
<div class="content">
<h1>'content1'</h1>
<h6>'content2'</h6>
</div>
</div>
Here is an idea using clamp() where I will toggle between a fixed width and full width based on a parameter (50rem in this case)
.content-container {
display: flex;
justify-content: center;
width: 100%;
}
.content {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
width: 82%;
text-align: center;
}
.content > * {
width: clamp(15rem, (50rem - 100vw)*9999, 100%);
outline: 1px solid red;
}
<div class="content-container">
<div class="content">
<h1>'content1'</h1>
<h6>'content2'</h6>
</div>
</div>
Related article if you want more detail: https://css-tricks.com/responsive-layouts-fewer-media-queries/
The following solution uses only flexbox, no media queries or JavaScript. Does this do what you want?
.content-container {
display: flex;
justify-content: center;
width: 100%;
}
.content {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
width: 82%;
text-align: center;
}
.content h1,
.content h6 {
flex: 1;
}
.horizontal-spacing {
flex: 1;
min-width: calc(20rem + 15.5rem);
height: 0;
}
<div class="content-container">
<div class="content">
<h1>'content1'</h1>
<span class="horizontal-spacing"></span>
<h6>'content2'</h6>
</div>
</div>
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>
#container {
display: flex;
flex-direction: column;
align-items: center;
height: 200px;
width: 100px;
background-color: red;
}
#stack{
display: flex;
flex-direction: column;
align-items: center;
max-height: 200px;
}
.item {
display: flex;
height: 30px;
width: 100px;
background-color: green;
flex-shrink: 0;
}
.spacer {
display: flex;
height: 200px;
flex-shrink: 1000;
}
<div id="container">
<div class="stack">
<div class="item">a</div>
<div class="spacer"></div>
<div class="item">b</div>
</div>
</div>
As the code shows above, parent had a max-height as the height of it is undefined.
I want the height of spacer was as large as possible. And what I expect is 160px in this situation.
I had tried flex-grow, but it doesn't work as the container has no height.
I had tried flex-shrink and a large height like the code in snippet either. But I found that sometime flex-shrink not work, or sometimes it looks scary with a very large height.
it does not work because you use a wrong selector for "stack" - it is a class, not id!
This should work: https://jsfiddle.net/bL5w81d4/1/
#container {
display: flex;
flex-direction: column;
align-items: center;
height: 200px;
width: 100px;
background-color: red;
}
.stack{
display: flex;
flex-direction: column;
align-items: center;
max-height: 200px;
}
.item {
display: flex;
height: 30px;
width: 100px;
background-color: green;
flex-shrink: 0;
}
.spacer {
display: flex;
height: 200px;
flex-shrink: 1000;
}