How can I make the shrink element "shrink" when the flex container below grows as a result of flex-wrapping. What is happening now is that new space created below the container instead of shrinking the one above. For some reason flex-grow and flex-shrink are not working expectedly whenever wrap happens. I want everything to fit within the viewport so that the user does not need to scroll.
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
.main-container {
display: flex;
width: 100vw;
height: 100vh;
flex-direction: column;
}
.main-container>* {
text-align: center;
}
.shrink {
background-color: #c0caad;
padding-top: 30%;
height: 80vh;
width: 100vw;
flex-shrink: 0;
}
.grow {
height: 20vh;
width: 30vw;
background-color: #9da9a0;
display: flex;
flex-wrap: wrap;
flex-grow: 1;
}
.grow>* {
border: 5px solid #654c4f;
height: 100%;
background-color: #b26e63;
width: 50%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="main-container">
<div class="shrink">Shrink</div>
<div class="grow">
<div class="growItems">Wrap</div>
<div class="growItems">Wrap</div>
<div class="growItems">Wrap</div>
</div>
</div>
</body>
</html>
There are a few concerns in your CSS. See the working snippet below.
1. flex-shrink: 0; prevents it from shrinking.
For flex-children to be flexibly growing and shrinking, you'd probably want flex: 1; or some other shrink/grow values than 0.
2. explicit height of 80vh and 20vh make them of static height.
That is, they will remain of those specific height rather than flexibly changing their relational heights as you indicated in your drawing. You'd want to remove those values.
3. padding-top: 30% pushes the content down, forcing the height
I wonder if you included it just to push the placeholder text down. But in any case, it's one of the factors that stops the shrink from shrinking.
4. width: 50% + border: 5px - border-box > 50% of available space
Again, this might be just a placeholder style. But in any case, unless you set it to box-sizing: border-box; the width will become 50% + 5px and will unexpectedly wrap.
Below are cleaned up suggestion, based on your drawing in the question.
html, body {
padding: 0;
margin: 0;
}
.main-container {
display: flex;
border: 1px solid red;
width: 100vw;
height: 100vh;
flex-direction: column;
}
.main-container>* {
text-align: center;
}
.shrink {
background-color: #c0caad;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
flex: 3;
}
.grow {
background-color: #9da9a0;
display: flex;
flex-wrap: wrap;
flex: 1;
align-items: flex-start;
}
.grow>* {
box-sizing: border-box;
border: 5px solid #654c4f;
height: 50px;
background-color: #b26e63;
flex-basis: 50%;
}
<div class="main-container">
<div class="shrink">Shrink</div>
<div class="grow">
<div class="growItems">Wrap</div>
<div class="growItems">Wrap</div>
<div class="growItems">Wrap</div>
<div class="growItems">Wrap</div>
<div class="growItems">Wrap</div>
<div class="growItems">Wrap</div>
</div>
</div>
Related
I am trying to build this dynamic navigation bar with two zones, and only set sizes on the menu items. The yellow zone items shall wrap freely while the red zone items shall be presented at the bottom with no wrapping. Can i have some guidance on how to solve this..am totally lost :/
Navigation container
width: Full page
height: Depends on content height
Yellow Zone
width: Full page - red zone
height: Depends on content height
items wraps to x new rows
Red Zone:
width: Depends on content width
height: Same as yellow zone
items does not wrap and are presented on the same row as the last row on the yellow zone
This should do what you are looking for. To do most of the styling I used flex-box, so if you don't know it yet, I suggest you learn it, it's very useful.
What I basically do is use two separate containers to which I'm going to apply a different flex-flow. flex-flow takes the direction (row/column) as the first "parameter" and the wrap (wrap/nowrap) as the second. I add a little gap between the elements and you can style the rest as you prefer.
I'll also link you to the codepen, so you can test it easier.
*, *::before, ::after {
box-sizing: border-box;
padding: 0;
margin: 0;
}
nav {
display: flex;
flex-flow: row nowrap;
background: gray;
}
.wrap {
display: flex;
flex-flow: row wrap;
flex-grow: 2;
gap: .5rem;
background: yellow;
padding: .4rem;
}
.nowrap {
display: flex;
flex-flow: row nowrap;
flex-grow: 1;
align-items: flex-end;
gap: .5rem;
background: red;
padding: .4rem;
}
.element {
width: 500px;
height: 50px;
background: blue;
}
.element-2 {
width: 300px;
height: 50px;
background: blue;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<nav>
<div class="wrap">
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
</div>
<div class="nowrap">
<div class="element-2"></div>
<div class="element-2"></div>
<div class="element-2"></div>
</div>
</nav>
</body>
</html>
<body>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
nav,
.yellow,
.red {
display: flex;
}
.yellow {
flex-wrap: wrap;
background: yellow;
gap: 1rem;
}
.red {
background: red;
gap: 1rem;
}
.red a {
align-self: flex-end;
}
.yellow,
.red {
padding: 1rem 2rem;
}
a {
padding: 1rem 2rem;
border: 1px solid teal;
}
</style>
<nav>
<div class="yellow">
A1
A2
A3
A4
A5
A6
A7
</div>
<div class="red">
B1
B2
B3
</div>
</nav>
</body>
I want to create a box which has on left and right side a blue "div" and in the middle a larger purple "div". My Problem is that when i write "align-items : center" all "div" vanishes but i dont know why. Can you help me?
This is my HTML Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flexbox Playground</title>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght#300&display=swap" rel="stylesheet">
<link rel="stylesheet" href="app.css">
</head>
<body>
<h1>Let's Play With Flexbox</h1>
<section id="anotherExample">
<div class="sidebar"></div>
<div class="mainContent"></div>
<div class="sidebar"></div>
</section>
</body>
</html>
This is my CSS Code
#anotherExample{
width: 90%;
height: 500px;
margin: 0 auto;
border: 5px solid #003049;
display: flex;
justify-content: center;
/*align-items: center;*/
}
section .sidebar{
background-color: blue;
flex-grow:1 ;
flex-basis: 200px;
}
section .mainContent{
background-color: blueviolet;
flex-grow:2 ;
flex-basis: 200px;
}
It looks like when you apply align-items: center, the height of div elements are set to 0. You can try to add the height property to divs to see them again as #anotherExample is parent of those div elements.
#anotherExample{
width: 90%;
height: 500px;
margin: 0 auto;
border: 5px solid #003049;
display: flex;
justify-content: center;
align-items: center;
}
section .sidebar{
height: 100%;
background-color: blue;
flex-grow:1;
flex-basis: 200px;
}
section .mainContent{
height: 100%;
background-color: blueviolet;
flex-grow:2 ;
flex-basis: 200px;
}
<h1>Let's Play With Flexbox</h1>
<section id="anotherExample">
<div class="sidebar"></div>
<div class="mainContent"></div>
<div class="sidebar"></div>
</section>
All div vanish because they have no height when align-items: center.
For flex items, the default align-items behave as stretch. The three div are stretched to their container height.
When you set align-items: center, the three div are centered on the cross-axis, but they are not visible due to no height (since they do not have content or a set height).
If you give them a height such as height: 100%, you can see the three div again.
More about align-items
Example:
#anotherExample {
width: 90%;
height: 500px;
margin: 0 auto;
border: 5px solid #003049;
display: flex;
justify-content: center;
/* 👇 With this turn on the div will no height will vanish */
align-items: center;
}
section .sidebar {
background-color: blue;
flex-grow: 1;
flex-basis: 200px;
/* 👇 Give div a height to see it when align-items is center */
height: 100%;
}
section .mainContent {
background-color: blueviolet;
flex-grow: 2;
flex-basis: 200px;
/* 👇 Give div a height to see it when align-items is center */
height: 100%;
}
<h1>Let's Play With Flexbox</h1>
<section id="anotherExample">
<div class="sidebar"></div>
<div class="mainContent"></div>
<div class="sidebar"></div>
</section>
Here's how my child divs look and I'm trying to make them have less space in between when they wrap
I think the problem is in the media query
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 10px;
width: 100%;
}
html,
body {
margin: 0;
height: 100%;
width: 100%;
/* added the line above remove if erros */
}
.container-2 {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
background-color: red;
align-items: center;
}
.item {
margin: 2% 1%;
width: 95%;
height: 12%;
background-color: yellow;
border: solid black;
border-radius: 1% 1%;
}
/* Extra large devices (large laptops and desktops, 1200px and up) */
#media only screen and (min-width: 1200px) {
.container-1 img {
width: 50%;
height: 100%;
}
.container-2 {
flex-direction: row;
justify-content: center;
align-items: flex-start;
flex-wrap: wrap;
}
.item {
margin: 2% 1%;
width: 25%;
height: 12%;
background-color: yellow;
border: solid black;
border-radius: 1% 1%;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./css/menu.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Menu | Andy's House</title>
</head>
<body>
<div class="container-2">
<div class="item">
</div>
<div class="item">
</div>
<div class="item">
</div>
<div class="item">
</div>
<div class="item">
</div>
<div class="item">
</div>
<div class="item">
</div>
</div>
</div>
</body>
</html>
I want to make them have less space between them. If anyone knows how to, it would be greatly appreciated!
P.S: If you couldn't tell, I am a noob. So, I am sorry :(
The problem wasn’t the media query. I would change the container height to auto. Like this:
.container-2 {
display: flex;
flex-direction: column;
width: 100%;
height: auto;
background-color: red;
align-items: center;
}
I want to make 3 column layout with flex box. The goal is to make first and last div widths dynamic. But the 2nd div max-width is static.
Code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html, body{
min-height: 100% !important;
height: 100%;
}
body{
margin: 0;
background-color: #ddd;
display: flex;
justify-content: space-between;
}
.left , .center, .right{
height: 100%;
}
.left{
width: auto;
background-color: antiquewhite;
}
.center{
display: flex;
min-height: 100vh;
flex-direction: column;
width: 100%;
max-width: 1200px;
background-color: green;
}
.right{
width: auto;
background-color: blue;
}
</style>
</head>
<body>
<div class="left">
</div>
<div class="center">
</div>
<div class="right">
</div>
</body>
</html>
Now I am getting the center max width is constant that I expected. But left & right div's not appear always. I want to make right & left div appear with dynamic width that based on browser window size.
Update - current layout:
Expected layout:
How can I make it work?
Here you go.
Just apply flex:1 to all of the divs but flex: 1 0 100%; to the center div so it defaults to as wide as it can before hitting the max-width you wanted.
html,
body {
min-height: 100% !important;
height: 100%;
}
body {
margin: 0;
background-color: #ddd;
display: flex;
}
.left,
.center,
.right {
flex: 1;
height: 100%;
}
.left {
width: auto;
background-color: red
}
.center {
display: flex;
min-height: 100vh;
flex-direction: column;
flex: 1 0 100%;
width: 100%;
max-width: 1200px;
background-color: green;
}
.right {
width: auto;
background-color: blue;
}
<div class="left">
</div>
<div class="center">
</div>
<div class="right">
</div>
does this help?
.flex-container {
display: flex;
justify-content: space-between;
background-color: DodgerBlue;
}
.flex-container > .side {
background-color: green;
width: 100%;
}
.flex-container > .center {
background-color: #f1f1f1;
color: green;
max-width: : 100%;
height: 100px;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="flex-container">
<div class="side"></div>
<div class="center">
this will expand as your content grows
</div>
<div class="side"></div>
</div>
</body>
</html>
This question already has an answer here:
flex-grow not working in column layout
(1 answer)
Closed 4 years ago.
I'm trying to have space between each .box element, however space-between is not acting to create spaces between the boxes. The boxes appear with no space in between them.
* {
box-sizing: border-box;
}
.grid {
border: black dashed 1px;
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: center;
}
.grid * {
border: 1px red solid;
}
.box {
height: 100px;
width: 100px;
background-color: blue;
}
<div class="grid">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
See codesandbox: https://codesandbox.io/s/8j7k4xjzl
The code is actually working. The problem is the ".grid" div is taking the minimum height required according to it's content.
If you give ".grid" div height equal to 100vh you can see the result.
height: 100vh;
Here's a fiddle showing the result:
https://jsfiddle.net/ayushgupta15/w30h5kep/
Please tell if this is the solution you're looking for.
Space-between is used for horizontal "box spacing". What you're looking for is margin.
.box {
height: 100px;
width: 100px;
background-color: blue;
margin: 5px;
}
like so.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<style>
* {
box-sizing: border-box;
}
.grid {
border: black dashed 1px;
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: center;
}
.grid * {
}
.box {
height: 100px;
width: 100px;
background-color: blue;
margin: 5px;
}
</style>
<div class="grid">
<div class="box">1
</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
</body>
</html>
You can edit the top, right, left, bottom margin if you want to do so:
margin: (top) (right) (bottom) (left);