Let CSS grid row fill available space - html

I'm working with CSS-grids and I want the last row of my CSS-grid to use all remaining space in the wrapper but at the same time I want all other rows to follow the min-content-strategy.
CSS for the wrapper:
.grid {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 100px auto;
grid-auto-rows: min-content;
row-gap: 7px;
justify-items: start;
align-items: start;
}
My initial idea how to achieve this was to simply add margin-top: auto to the button as one would do with flexbox. I have also tried to set grid-auto-rows: auto for the grid wrapper but it does not work either.
Edit: Example code: https://jsfiddle.net/xt139o2g/ (I want button to appear in lower right corner of the wrapper div)
.wrapper {
border: 1px solid blue;
height: 300px;
width: 250px;
padding: 10px;
}
.grid {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 100px auto;
grid-auto-rows: min-content;
row-gap: 7px;
justify-items: start;
align-items: start;
}
.button {
grid-column: 1 / -1;
justify-self: end;
align-self: end;
}
<div class="wrapper">
<div class="grid">
<div>
R1C1
</div>
<div>
R1C2
</div>
<div>
R2C1
</div>
<div>
R2C2
</div>
<div class="button">
Button
</div>
</div>
</div>
Thanks in advance!

You can use the repeat function to set the first two rows to min-content:
grid-template-rows: repeat(2, min-content);
Then, use display: flex on .button and shift its content to the bottom right using justify-content and align-items:
display: flex;
align-items: flex-end;
justify-content: flex-end;
Demo: (I've added borders to demonstrate the spacing.)
.wrapper {
border: 1px solid blue;
height: 300px;
width: 250px;
padding: 10px;
}
.grid {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 100px auto;
grid-template-rows: repeat(2, min-content);
row-gap: 7px;
}
.grid>div {
width: 100%;
height: 100%;
border: 1px solid;
}
.button {
display: flex;
align-items: flex-end;
justify-content: flex-end;
grid-column: 1 / -1;
}
<div class="wrapper">
<div class="grid">
<div>
R1C1
</div>
<div>
R1C2
</div>
<div>
R2C1
</div>
<div>
R2C2
</div>
<div class="button">
Button
</div>
</div>
</div>

I don't think there is a trivial way to achieve this but you can appromxiate it like below:
.wrapper {
display:inline-block;
border: 1px solid blue;
height: 300px;
width: 200px;
padding: 10px;
}
.grid {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 100px auto;
grid-template-rows:repeat(100,min-content) 1fr; /* big number here*/
}
.grid *:not(:last-child) {
margin-bottom:7px; /* replace the gap */
}
.button {
grid-column: 1 / -1;
grid-row: 101; /* place it at the 1fr template */
margin:auto 0 0 auto;
}
<div class="wrapper">
<div class="grid">
<div>
R1C1
</div>
<div>
R1C2
</div>
<div>
R2C1
</div>
<div>
R2C2
</div>
<div class="button">
Button
</div>
</div>
</div>
<div class="wrapper">
<div class="grid">
<div>
R1C1
</div>
<div>
R1C2
</div>
<div class="button">
Button
</div>
</div>
</div>
<div class="wrapper">
<div class="grid">
<div>
R1C1
</div>
<div>
R1C2
</div>
<div>
R1C1
</div>
<div>
R1C2
</div>
<div>
R1C1
</div>
<div>
R1C2
</div>
<div>
R1C1
</div>
<div>
R1C2
</div>
<div class="button">
Button
</div>
</div>
</div>

Related

How to make an element of a Grid take all remaining space?

I am building a grid layout based on 3 rows and I would like the middle row to take as much space as possible.
The first row should be at the start of the screen (blue bar in the code example) and the third row should be at the end of the screen(red bar in the code example)
How can I achieve this? :S
https://jsfiddle.net/xmghkLvs/31/
.grid {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto auto auto;
row-gap: 1%;
}
.top-bar{
background-color: blue;
border-radius: 5px;
}
.main-menu{
justify-self: center;
display: flex;
flex-direction: column;
background-color: green;
}
.bottom-bar{
background-color: red;
border-radius: 5px;
}
<div class="grid">
<div class="top-bar">
<h1>
Title
</h1>
</div>
<div class="main-menu">
<button>
One Button
</button>
<button>
Other Button
</button>
</div>
<div class="bottom-bar">
<p>
I'm a text
</p>
</div>
</div>
1st: Give the grid a min-height like 100vh (.grid { min-height: 100vh; }). This will make consume at least the viewports height.
2nd: Give the the first and last row a height of min-content. That will make it only consume as much height as needed. auto will then consume all remaining space by default.
.grid {
min-height: 100vh;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: min-content auto min-content;
row-gap: 1%;
}
.top-bar{
background-color: blue;
border-radius: 5px;
}
.main-menu{
justify-self: center;
display: flex;
flex-direction: column;
background-color: green;
}
.bottom-bar{
background-color: red;
border-radius: 5px;
}
<div class="grid">
<div class="top-bar">
<h1>
Title
</h1>
</div>
<div class="main-menu">
<button>
One Button
</button>
<button>
Other Button
</button>
</div>
<div class="bottom-bar">
<p>
I'm a text
</p>
</div>
</div>
Try using 100vh
.grid {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto auto auto;
row-gap: 1%;
height: 100vh;
}
and add specific height for the .top-bar abd .bottom-bar
You could approach this using Flexbox and 100vh as show below.
.grid {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.top-bar{
display: flex;
height: 20%;
}
.main-menu{
display: flex;
align-items: center;
justify-content: center;
height: 60%;
}
.main-menu button {
height: 60px;
width: 120px;
}
.bottom-bar{
display: flex;
align-items: center;
justify-content: center;
height: 20%;
}

How to span a one of the grandchild element to 100% width in CSS Grid

How to span a one of the grandchild element to 100% width in CSS Grid while the parent is container is divided into 3 fractions.
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.container > div {
background-color: #4834d4;
width: 100%;
}
.container > div .child_01 {
background-color: #f9ca24;
width: 80%;
height: 50px;
margin: 1rem auto;
}
.container > div .child_02 {
background-color: #eb4d4b;
width: 80%;
height: 50px;
margin: 1rem auto;
}
<div class="container">
<div>
<div class="child_01"></div>
<div class="child_02"></div>
</div>
<div>
<div class="child_01"></div>
<div class="child_02"></div>
</div>
<div>
<div class="child_01"></div>
<div class="child_02"></div>
</div>
</div>
What I am trying to achieve is this.desired layout
Is this possible to achieve in CSS Grid.
Here you go with a solution
.container {
padding: 20px;
display: flex;
flex-direction: column;
background-color: #4834d4;
}
.container > div {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 1rem;
}
.child_01 {
display: inline-flex;
background-color: #f9ca24;
width: 30%;
height: 50px;
}
.child_02 {
display: flex;
background-color: #eb4d4b;
width: 100%;
height: 50px;
margin: 1rem auto;
}
<div class="container">
<div>
<div class="child_01"></div>
<div class="child_01"></div>
<div class="child_01"></div>
</div>
<div class="child_02"></div>
<div class="child_02"></div>
<div class="child_02"></div>
</div>
I have use flex instead of grid.

Why aren't my CSS grid layout divs centered on large viewports?

I am trying to display div inside a parent div but want the children divs to be in the centre and not from the beginning of the parent div. The HTML/CSS is given below along with a screenshot of how it looks on iPad (seems alright) and computer(not something I want).
.inner-tile {
display: inline-grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr ));
grid-template-rows: 1fr;
justify-items: center;
width: 100%;
height: auto;
font-size: 18px;
padding-bottom: 10px;
}
.event {
border: 1px solid grey;
border-radius: 4px;
min-width: 240px;
min-height: 270px;
width: 90%;
height: auto;
}
<div class = "inner-tile">
<div class = "event">
<div class="event-image"></div>
event
</div>
<div class = "event">
<div class="event-image"></div>
event
</div>
<div class = "event">
<div class="event-image"></div>
event
</div>
<div class = "event">
<div class="event-image"></div>
event
</div>
</div>
If you will always have 4 items you can conside max-width and use grid instead of inline-grid then you can center using margin auto
.inner-tile {
display: grid;
max-width: calc(240px * 4 + 5px * 3);
margin: auto;
grid-gap: 5px;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
justify-items: center;
font-size: 18px;
padding-bottom: 10px;
}
.event {
border: 1px solid grey;
border-radius: 4px;
min-width: 240px;
min-height: 270px;
width: 90%;
}
<div class="inner-tile">
<div class="event">
<div class="event-image"></div>
event
</div>
<div class="event">
<div class="event-image"></div>
event
</div>
<div class="event">
<div class="event-image"></div>
event
</div>
<div class="event">
<div class="event-image"></div>
event
</div>
</div>
use
grid-template-columns: 1fr 1fr 1fr 1fr;
justify-items: center;
for more see https://alligator.io/css/align-justify/
Use justify-content: center;css code instead of justify-items: center; for outer div

Center grid div without items get centered

Here are my code snippets:
.grades_dashboard_m {}
.three_separation {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 60px;
}
.grades_dashboard_box {
height: 130px;
width: 160px;
background-color: #000000;
color: #ffff;
}
<div class="grades_dashboard_m" id="co_1">
<div class="three_separation">
<div class='grades_dashboard_box'>
<h1>12</h1>
</div>
<div class='grades_dashboard_box'>
<h1>12</h1>
</div>
<div class='grades_dashboard_box'>
<h1>12</h1>
</div>
</div>
</div>
As you see the grid div (grades_dashboard_m) is not centered in grades_dashboard_m. How to center it without center the elements in grades_dashboard_m? I already tried this:
.grades_dashboard_m {
display:flex;
justify-content:center;
align-items:center;
}
But without success.
EDIT: I figured out that this is not the problem. The problem is that the content of the 3 grids is not centered. But how to center the content of the grids?
Simply apply margin: 0 auto; to .grades_dashboard_box
likr this
.grades_dashboard_box {
margin: 0 auto;
}
this shall center the element not text.
Pure, CSS Grid Solution
In short, don't use margin: 0 auto to center grid children—use justify-items: center.
.three_separation {
…
justify-items: center;
}
A few words about justify-items from MDN:
In grid layouts, it aligns the items inside their grid areas on the
inline axis
Demo
.grades_dashboard_m {}
.three_separation {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 60px;
justify-items: center; /* <-- Added */
}
.grades_dashboard_box {
height: 130px;
width: 160px;
background-color: #000000;
color: #ffff;
}
<div class="grades_dashboard_m" id="co_1">
<div class="three_separation">
<div class='grades_dashboard_box'>
<h1>12</h1>
</div>
<div class='grades_dashboard_box'>
<h1>12</h1>
</div>
<div class='grades_dashboard_box'>
<h1>12</h1>
</div>
</div>
</div>

How to offset a div in a css grid

It's possible to "offset" a div in a css grid as in the image ?
Consider negative margin:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
width: 500px;
height: 200px;
border: 1px solid;
}
.box {
grid-column: 2/3;
margin-left: -20px;
margin-right: -80px;
background: red;
}
.box-alt {
grid-column: 2/3;
grid-row:2;
background: blue;
}
<div class="container">
<div class="box"></div>
<div class="box-alt"></div>
</div>
<div class="container">
<div class="area1"></div>
<div class="area2"></div>
</div>
.container{
display: grid;
grid-template: 1fr / repeat(3, 1fr);
grid-template-areas: "area1 offset area2";
}
.area{
width: 100%;
height: 40px;
}
.area1{
background-color: red;
}
.area2{
background-color: yellow;
}
If you are using Mozilla's guide in this link, you can use empty div like this as offset div:
<div class="container">
<div class="row">
<!-- Empty/Offset Div Here -->
<div class="col-xl-2"> </div>
<div class="col-xl-8">
<!-- Content Here -->
</div>
</div>
</div>