I'm currently doing some stuff with Flex Box and I'd like my flex box to stretch but I can't do it. Here is my codepen : https://codepen.io/chevalierv/pen/bGdBKyg
.FlexContainer {
height: 65vh;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: stretch;
align-content: stretch;
justify-content: center;
padding: 1em;
background-color: red;
}
.SecondChildContainer {
align-self: flex-end;
order: 2;
flex: 1;
flex-basis: 100%;
background-color: green;
}
.FirstChildContainer {
order: 1;
flex-grow: 5;
align-self: stretch;
background-color: blue;
}
<div class="FlexContainer">
<div class="FirstChildContainer">
a
</div>
<div class="SecondChildContainer">
a
</div>
</div>
I have cleaned your css a little bit and made it work. See the jsfiddle below:
https://jsfiddle.net/gqptemhu/
Basically, what your flex container needs is
.FlexContainer {
height: 65vh;
display: flex;
flex-direction: column;
}
so it knows to stack the items vertically.
And you use
flex: 0 1;
flex: 1 0;
On the items inside of the flex container, to tell which item will grow, and which one will shrink. The first number corresponds to flex-grow, and the second to flex-shrink. They are both relative numbers which tell which percentage of space the items will grow/shrink to.
You can read more about flexbox and how to use it on the link below:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Related
align-content and justify-content seem to do nothing when I run it on Chrome and Firefox.
I'm not sure what's wrong.
#container {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: center;
height: 90vh;
}
#header {
flex: 1 0 200px;
background-color: lightgreen;
height: 200px;
border-radius: 1rem;
}
#main {
flex: 1 0 200px;
background-color: coral;
height: 200px;
border-radius: 1rem;
}
#footer {
flex: 1 0 200px;
background-color: silver;
height: 200px;
border-radius: 1rem;
}
#media screen and (max-width: 915px) {
#container {
flex-flow: column wrap-reverse;
}
}
<div id="container">
<div id="header">Header</div>
<div id="main">Main</div>
<div id="footer">Footer</div>
</div>
They're doing exactly what you're asking them to do. What's wrong here is your flex definition.
If you want them to be 200px each, you shouldn't give it a flex-grow value of 1 which you're doing in your shorthand flex-grow: *1* 0 200px.
Instead, rewrite the flex properties as such:
#header {
flex: 0 0 200px;
...
}
Working JSFiddle
As for why align-content isn't working, you only have 1 line of items, so it has nothing to do.
align-content
This aligns a flex container's lines within when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis.
Note: this property has no effect when there is only one line of flex items.
From: CSS-Tricks
I'm guessing what you want is to center vertically and horizontally, in which case you don't want align-content, you want align-items.
Try replacing align-content: center with align-items: center to get the vertical centering.
JSFiddle example of align-items
I am trying to center a red box in the middle of the page.
I have set the flex container to 100% in height, and have also set the html,body to 100%, and it still does not align center.
Can anyone please help me understand why its not working? Thanks!
html, body {
height: 100%;
}
.flex-container {
display: flex;
flex-flow: column;
justify-content: center;
height: 100%;
}
.box {
flex: 0 0 100px;
background: red;
width: 100px;
}
<div class='flex-container'>
<div class='box'></div>
</div>
You use justify-content to align flex items on the main axis.
You use align-items to align flex items on the cross axis.
Since your flex container is flex-direction: column:
the main axis is vertical, and
the cross axis is horizontal.
justify-content: center is working fine.
You just need to add align-items: center.
html, body {
height: 100%;
}
.flex-container {
display: flex;
flex-flow: column;
justify-content: center; /* centers flex items vertically, in this case */
align-items: center; /* NEW */ /* centers flex items horizontally, in this case */
height: 100%
}
.box {
flex: 0 0 100px;
background: red;
width: 100px;
}
<div class='flex-container'>
<div class='box'></div>
</div>
Here's a more detailed explanation:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
You need to add align-items to .flex-container
align-items: center;
See here for an example https://jsfiddle.net/x9gyheo6/1/
I have a ul tag with display: flex.
I need it ordered by column with flex-direction: column;, but it does not work.
CSS for the container:
#nav li.four_columns ul.sub-menu {
width: 600px;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
flex-flow: wrap;
}
CSS for the child:
#nav li.four_columns ul.sub-menu li {
flex-basis: 25%;
/* white-space: nowrap; */
/* overflow: hidden; */
/* text-overflow: ellipsis; */
/* border-bottom: none; */
}
Here is the source of your problem: flex-flow: wrap
This is a shorthand property for flex-direction and/or flex-wrap.
The initial values of this property are row nowrap.
You have only declared the flex-wrap component: wrap.
This means that the flex-direction component remains the default value: row.
Hence, your flex items are aligning horizontally in a row that wraps.
As a solution, either specify both components:
flex-flow: column wrap
OR, since you already have flex-direction: column in the rule, remove flex-flow and use:
flex-wrap: wrap
Also important: If you want flex items to wrap in column-direction, you need to define a height on the container. Without a fixed height, the flex items don't know where to wrap and they'll stay in a single column, expanding the container as necessary.
Reference:
5.3. Flex Direction and Wrap: the flex-flow shorthand
If flex direction column is not working, make sure you didn't forget to specify the height:
Example:
#container {
display: flex;
width: 100%;
height: 100%;
flex-direction: column;
}
.child {
width: 200px;
/* height: 200px;*/
flex: 1;
}
#child1 {
background-color: red;
flex: 2;
}
#child2 {
background-color: green;
}
#child3 {
background-color: blue;
}
<section id="container">
<div id="child1" class="child"></div>
<div id="child2" class="child"></div>
<div id="child3" class="child"></div>
</section>
I have a container named #center in which I want to display canvas and a button inside it. I want the canvas object to take all the available space (respecting the button inside the container).
This is my code:
html, body {
width: 100%;
height: 100%;
}
#container {
display: flex;
height: 100%;
background-color: blue;
}
.block {
flex: 1;
}
#left {
background-color: green;
}
#center {
display: flex;
flex: 1;
flex-wrap: wrap;
align-content: flex-start;
}
#right {
background-color: orange;
}
#canvasObject {
display: block;
margin: 0 auto;
border: 1px solid;
background-color: yellow;
}
<div id="container">
<div id="left" class="block">Left</div>
<div id="center" class="block">
<canvas id="canvasObject">Your browser does not support Canvas.</canvas>
<button type="button">Click!</button>
</div>
<div id="right" class="block">Right</div>
</div>
If I do not have any button in my code, canvas occupy the full div but when I display the button, canvas does not seem to resize the desired height.
Example 1: Without button.
Example 2. With button.
How can I make that the canvas object will resize until the available height (also width but it is already doing it)?
Thanks in advance!
The problem is that you have align-content: flex-start on a row-direction flex container:
#center {
display: flex;
flex: 1;
flex-wrap: wrap;
align-content: flex-start; /* <-- source of the problem */
}
The align-content property controls the spacing between flex items in the cross-axis when there are multiple lines in the container.
When the button element is excluded, there is only one line in the flex container. In such a case, align-content has no effect (align-items would work).
But when you add the button, there are now two lines on wrap, and align-content takes over (align-items does not work).
Since align-content is set to flex-start in your code, both lines are packed to the top of the container. (For other options, try flex-end, center, space-between, space-around and stretch).
An efficient solution would be to use flex-direction: column and apply flex: 1 to the canvas.
#center {
display: flex;
flex-direction: column; /* new; stack flex items vertically */
flex: 1;
flex-wrap: wrap;
/* align-content: flex-start; <-- remove; not necessary */
}
#canvasObject {
flex: 1; /* new; consume all available free space */
/* display: block; <-- remove; not necessary */
/* margin: 0 auto; <-- remove; not necessary */
border: 1px solid;
background-color: yellow;
}
Revised Fiddle
W3C References:
8.4. Packing Flex Lines: the align-content property
8.3. Cross-axis Alignment: the align-items and align-self properties
With body's flex-direction: row;, I am expecting its align-items: stretch; will stretch the child item vertically to fill the screen height. I don't understand why this is not happening.
Here's a minimal example of what I am trying to do. I am expecting the blue block to fill the entire green body.
body {
display: flex;
flex-direction: row;
align-items: stretch;
align-content: stretch;
background-color: green;
}
.flexContainer {
display: flex;
background-color: blue;
}
<body>
<div class="flexContainer">
Hello
</div>
</body>
https://jsfiddle.net/qc6fu1b3/
It's not happening because the height of body is the height of the content.
See the red border around body in your code: https://jsfiddle.net/qc6fu1b3/2/
As you can see, align-items: stretch has no space to work.
Unlike width, which block elements fill 100% by default, heights must be defined. Otherwise, elements default to auto – the height of the content.
When you say:
I am expecting [...] the child item vertically to fill the screen height.
There's no reason to expect this with CSS default behavior. If you want the element to expand the height of the screen, then define that in your code:
html { height: 100%; }
body {
height: 100%;
display: flex;
flex-direction: row;
align-items: stretch;
align-content: stretch;
background-color: green;
}
.flexContainer {
display: flex;
background-color: blue;
}
<body>
<div class="flexContainer">Hello</div>
</body>