I am trying to do a flex-wrap with flex-direction column (see #design-content) placed in a grid area (see design-form).
#design-content needs to have the height of the grid area it is placed in.
This works as long as #design-form does NOT have flex-direction: column; but as soon as I add that line the element + the parent grid-template-row height changes (as shown in computed tab in chrome)
Is there a way to force #design content to respect height from the parent elements?
CSS
main {
height: 80vh;
display: grid;
grid-template-areas:
"ref"
"design";
grid-template-rows: fit-content(100%) 1fr;
}
#design-form {
grid-area: design;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr min-content;
grid-template-areas:
"form "
"controls";
gap: var(--standard-gap);
}
#design-content {
height: 100%;
display: flex;
min-height: 0;
flex-direction: column;
flex-wrap: wrap;
border-style: dotted dashed solid double;
gap: var(--standard-gap);
}
Relevant html
<main>
<form id="design-form" class="active">
<div id="design-content">
<div class="card">
<h4>setup</h4>
<div class="check-field-element">
<input
type="checkbox"
name="checkbox"
id="trophicMethod"}="">
<label>trophic method</label>
</div>
... more cards
</div>
</form>
</main>
To ensure that #design-content has a height of the parent grid area, you can set the height attribute to 100%, and then set the flex-direction property to row instead of column.This will cause the flex-wrap to wrap the content horizontally instead of vertically and will ensure that the height of the element is equal to the height of the parent grid area. Additionally, you can set the min-height property to 0 to ensure that the element will always have a height of at least 0. Here is the code with the changes applied:
#design-content {
height: 100%;
display: flex;
min-height: 0;
flex-direction: column;
flex-wrap: wrap;
flex-basis: 100%;
border-style: dotted dashed solid double;
gap: var(--standard-gap);
}
Related
In the example below, the .grid-container div will stretch over the width of the body (that is, the viewport width), but its height will be the same as the .grid-item height.
Any explanations to why that is the case? I'm having trouble wrapping my head around it.
body {
width: 100vw;
height: 100vh;
}
.grid-container {
display: grid;
grid-template: 1fr / 1fr;
place-items: center;
}
<div class="grid-container">
<div class="grid-item">Grid item</div>
</div>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 100vw;
height: 100vh;
}
.grid-container {
display: grid;
grid-template: 1fr / 1fr;
place-items: center;
background-color: red;
}
.grid-item {
background-color: blue;
}
<div class="grid-container">
<div class="grid-item">Grid item</div>
<div class="grid-item">Grid item</div>
</div>
as you can see what you are doing here is not a grid. It would be better if you use CSS flexbox instead of grid for one column grid.
just replace this code with grid-container class
display: flex;
flex-direction: column;
align-items: center;
justify-items: space-around;
and also note that every element of type div in HTML takes the whole width of the line and it's height is defined by the content inside it. It doesn't stretch all the way down to the bottom until you set a fixed height to it. you can set position: relative; to grid container parent and set its position to absolute. then add width: 100%; and height: 100%; to it.
add more information about your code for more detailed help.
After reading MDN's display page, I think I found the answer:
grid The element behaves like a block element and lays out its content according to the grid model.
The grid container by default behaves like a block element, which is why it will span the entire width of the parent when its size is not set explicitly. You can prevent this behavior and make it inline with display: inline grid or display: inline-grid (legacy).
body {
width: 100vw;
height: 100vh;
}
.grid-container {
display: inline grid;
grid-template: 1fr / 1fr;
place-items: center;
}
<div class="grid-container">
<div class="grid-item">Grid item</div>
</div>
I'd like to horizontally center align a flex child inside a flex container.
However, when the child gets align-self: center it shrinks to width = 0.
Note that both the container and the child have max-width.
How would you solve this?
.container {
display: flex;
flex-direction: column;
max-width: 400px;
outline: 2px solid red;
}
.child {
display: flex;
flex-direction: column;
max-width: 200px;
height: 50px;
background-color: #ccc;
/* This causing the child to shrink to width = 0 */
/* align-self: center; */
}
<div class="container">
<div class="child">
</div>
</div>
The issue is the stretch effect that you disable by changing the alignment of the element. By default align-items is set to stretch thus the element will try to fill its parent width (or height for a row direction).
You can put back this feature using width:100%
.container {
display: flex;
flex-direction: column;
max-width: 400px;
outline: 2px solid red;
}
.child {
display: flex;
flex-direction: column;
max-width: 200px;
height: 50px;
width:100%;
background-color: #ccc;
align-self: center;
}
<div class="container">
<div class="child">
</div>
</div>
align-items sets the default alignment for all of the flex container’s items, including anonymous flex items. align-self allows this default alignment to be overridden for individual flex items.ref
There are lots of similar questions, I have reviewed all of them, but none solved my problem.
Premises:
I have a flexbox layout with flex column and the bottom flex-item filling the remainder of the page height. The flex-item gets stretched to the remainder of the page by flex 1.
Goal:
I need my grid (with its children) inside this flex-item to expand to the height of the flex-item.
Problem:
The html wrapper only has a min-height 100vh set. This makes the grid stretch to the flex-item, but not its children!
The only solution I can find is to also set height 100vh on the html wrapper, but I do not want to do this. Is there any way to solve my problem without setting height?
See the codepen here:
https://codepen.io/mesqueeb/pen/aGeKjm
See the animated GIF here to show you what I mean:
You can try this.
remove the flex-direction: column; in the .remaining and it will expand the height.
main{
min-height: calc(100vh - 51px);
display: flex;
flex-direction: column;
}
div{
border: solid goldenrod thick;
padding: 2px;
margin: 2px;
}
.full-page{
display: flex;
flex-direction: column;
height: 100%;
flex: 1;
}
.top-row{
height: 100px;
}
.remaining{
flex: 1;
display: flex;
}
.grid{
border: solid teal thick;
flex: 1;
display: grid;
grid-template-rows: 1fr 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
}
.key{
border: thin green solid
}
.small{
font-size: .8em
}
<main>
<div class="full-page">
<div class="top-row">
grid below will take full height only if body height is set...
</div>
<div class="remaining">
<div class="grid">
<div class="key">1</div>
<div class="key">2</div>
<div class="key">3</div>
<div class="key">4</div>
<div class="key">5</div>
<div class="key">6</div>
<div class="key">7</div>
<div class="key">8</div>
<div class="key">9</div>
<div class="key">C</div>
<div class="key">0</div>
<div class="key">➕</div>
</div>
</div>
</div>
</main>
Not sure if it solves your problem in the best way, but this works:
.remaining {
flex: 1;
/* display: flex; */
flex-direction: column;
position: relative;
}
.grid {
border: solid #008080 thick;
/* flex: 1; */
display: grid;
grid-template-rows: 1fr 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
I have a CSS Grid inside a Flexbox column, and the grid has flex-grow: 1.
In Chrome, the grid expands to fill available space, but its content does not, even with align-content: stretch on the grid. In Firefox and Edge, the content expands to fill the grid's height, as desired.
Here's a pen that reproduces the problem, and images of how it looks in different browsers. Is this a bug with Chrome, and if so, can anyone suggest a straightforward workaround?
Chrome
Firefox
Edge
#wrapper {
display: flex;
flex-direction: column;
height: 15rem;
background-color: #aaa;
}
#grid {
flex-grow: 1;
display: grid;
background-color: #ccf;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
align-content: stretch; /* "end" correctly puts the row to the bottom */
}
#left {
background-color: #fcc;
}
#right {
background-color: #cfc;
}
<div id="wrapper">
<div id="top">not in grid</div>
<div id="grid">
<div id="left">left</div>
<div id="right">right</div>
</div>
</div>
Is this a bug with Chrome, and if so, can anyone suggest a straightforward workaround?
It looks like a bug in Chrome. But I can't say for sure.
Here's what's happening:
You have the flex item grid container set to consume all available height with flex-grow: 1
Because you've only defined the flex-grow property, the other two flexibility properties – flex-shrink and flex-basis – remain at their default values.
The default value of flex-shrink is 1, and is not pertinent to this problem.
The default value of flex-basis is auto, and is the source of the problem.
If you add flex-basis: 0 to your code, the item takes full height in Chrome, as well.
revised codepen
#wrapper {
display: flex;
flex-direction: column;
height: 15rem;
background-color: #aaa;
}
#grid {
/* flex-grow: 1; */
flex: 1; /* fg:1, fs:1, fb:0 */
display: grid;
background-color: #ccf;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
}
#left { background-color: #fcc; }
#right { background-color: #cfc; }
<div id="wrapper">
<div id="top">not in grid</div>
<div id="grid">
<div id="left">left</div>
<div id="right">right</div>
</div>
</div>
i have a complex layout in which i have a div generated by JavaScript with dynamic height, he is called ".outer" . This div has some nested divs, finally leading to a div called ".target". I need the target div to be at ".outers" height. And i don't want to address the inner divs since they are varying markup generated by my JS Framework.
I do not want to set the height via JS, i can not set position to absolute nor relative in ".outer"
HTML:
<div class="outer">
<div class="inner">
<div class="anotherInner">
<div class="target">
This div should be outer's height no matter how many divs are between target and outer like ".inner"
</div>
</div>
</div>
</div>
CSS:
body {
background: #000;
}
.outer {
background: #333;
height: 500px; /* this is not a pixel value, only for example*/
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: flex-start;
align-content: stretch;
align-items: stretch;
}
.inner {
background: #555;
}
.target {
background: #777;
order: 0;
flex: 1 1 auto;
align-self: auto;
}
Example:
http://codepen.io/anon/pen/akwWZK?editors=1100
The only possible way to do this in FlexBox is to address the .inner div's in your CSS by adding display: flex; to them.
I've created a working example for you here: http://codepen.io/mattpark22/pen/rLwwZp
To '.inner' add:
display: flex;
To '.target' add:
height: 100%;
To '.outer' change, flex-direction to:
flex-direction: row;
My codepen example also cleans up some CSS which isn't required.