Resize elements in same grid column to fit - html

I have a CSS grid with several columns and many rows (I'm building a timetable view). The rows and columns are defined on the grid element itself, and then on the elements within the grid I set their column (always only one column) and their rows (might be more than one row).
An example is as follows:
.grid {
display: grid;
grid-template-rows: [row-a] 1fr [row-b] 1fr [row-c] 1fr [row-d] 1fr;
grid-template-columns: [col] 1fr;
flex-grow: 1;
}
.entry-one {
grid-column: col;
grid-row: row-a/row-d;
background-color: red;
}
.entry-two {
grid-column: col;
grid-row: row-b;
background-color: green;
}
<div class='grid'>
<div class='entry-one'>
Foobar
</div>
<div class='entry-two'>
Barfoo
</div>
</div>
Now, what I would like to have is that the elements resize themselves and flow nicely, such that they fit next to each other. I can mock this using width and margin on the elements:
.grid {
display: grid;
grid-template-rows: [row-a] 1fr [row-b] 1fr [row-c] 1fr [row-d] 1fr;
grid-template-columns: [col] 1fr;
flex-grow: 1;
}
.entry-one {
grid-column: col;
grid-row: row-a/row-d;
background-color: red;
width: 50%; /* ADDED */
}
.entry-two {
grid-column: col;
grid-row: row-b;
background-color: green;
width: 50%; /* ADDED */
margin-left: 50%; /* ADDED */
}
<div class='grid'>
<div class='entry-one'>
Foobar
</div>
<div class='entry-two'>
Barfoo
</div>
</div>
However this is not optimal, especially as the elements are inserted dynamically. Is there a way to have the elements size & align themselves automatically using CSS? I've tried to use display: flex on the entries, but that did not result in what I want (or maybe I forgot to add another rule).
Thank you for any ideas, and have a nice day!

I made this to see if that is what you are looking for
.grid{
display: flex;
grid-template-rows: [row-a] 1fr [row-b] 1fr [row-c] 1fr [row-d] 1fr;
grid-template-columns: [col] 1fr;
flex-grow: 1;
}
I just changed your display to flex and delete your margin-left: 50%; on the entry two, hope it is what you are looking for

Related

Div inside grid not taking the alloted area

I have a container where I am using grid layout as show below
My HTML looks like this
<div class='pagelayout'>
<div class="tophalf">This div needs to occupy entire width of the page</div>
</div>
CSS looks like this
.pagelayout {
display: grid;
flex-grow: 1;
grid-template-columns: 70fr 30fr;
grid-template-rows: auto auto;
overflow: auto;
grid-template-areas:
'tophalf tophalf'
'leftside rightside'
}
.tophalf{
grid-area: tophalf;
}
Snippet:
.pagelayout {
display: grid;
flex-grow: 1;
grid-template-columns: 70fr 30fr;
grid-template-rows: auto auto;
overflow: auto;
grid-template-areas: 'tophalf tophalf' 'leftside rightside'
}
.tophalf {
grid-area: tophalf;
}
<div class='pagelayout'>
<div class="tophalf">This div needs to occupy entire width of the page</div>
</div>
But the div(This div needs to occupy entire width of the page) is only taking 70fr and the rest 30fr is left unused.
If I change the grid template like this, everythign is working fine.
.pagelayout {
display: grid;
flex-grow: 1;
grid-template-columns: 1fr;
grid-template-rows: auto;
overflow: auto;
grid-template-areas:
'tophalf tophalf'
'leftside rightside'
}
.tophalf{
grid-area: tophalf;
}
Snippet:
.pagelayout {
display: grid;
flex-grow: 1;
grid-template-columns: 1fr;
grid-template-rows: auto;
overflow: auto;
grid-template-areas: 'tophalf tophalf' 'leftside rightside'
}
.tophalf {
grid-area: tophalf;
}
<div class ='pagelayout'>
<div class ="tophalf">This div needs to occupy entire width of the page</div>
</div>
What is that I'm doing wrong in the first case?
grid-template-columns: 70fr 30fr; this means create two colums one which takes 70fr & other which takes 30fr
grid-template-columns: 70fr 30fr;
grid-template-rows: auto auto;
.pagelayout {
display: grid;
flex-grow: 1;
grid-template-columns: 70fr 30fr; /*this means create two colums one which takes 70fr & other which takes 30fr*/
grid-template-rows: auto;
overflow: auto;
outline:2px solid green;
}
.tophalf {
outline:2px solid red;
}
<div class='pagelayout'>
<div class="tophalf">This div needs to occupy entire width of the page</div>
</div>

Why doesn't this CSS grid create the right number of rows and columns?

This CSS grid creates 7 rows only, as you can see by using "Inspect tool" of the browser.
Why?
.grid {
display: grid;
grid-gap: 1em;
height: 100%;
}
.grid8x8 {
grid-template-rows: repeat(8, 1fr);
grid-template-columns: repeat(8, 1fr);
}
.element {
background-color: yellow;
}
<div class="grid grid8x8">
<div class="element" style="grid-row: 2 / 4; grid-column: 3 / 6;">TEST</div>
</div>
You have actually 8 rows. What you see with the inspector is the gap between the cells, so for 8 rows there are 7 gaps (red lines are gaps):
If you reduce the gap size, you'll notice how the rows appear:
Note the 8 rows:
Your problem is the grid cell overflowing all the other cells because there's not enough space, because your grid-gap is too high.
Try this:
.grid { display: grid; grid-gap: 1em; height: 70vh; }
.grid8x8 { grid-template-rows: repeat(8, 1fr); grid-template-columns: repeat(8, 1fr); }
.element { background-color: yellow; }
<div class="grid grid8x8">
<div class="element" style="grid-row: 2 / 4; grid-column: 3 / 6;">TEST</div>
</div>

My css grid layout doesn't fill its container on chrome. What's causing the loss of a fraction of a pixel?

The markup below works as expected on firefox (paragraph is 980px), but not on chrome (paragraph is 979.94px). Does anyone know how to prevent this from happening?
codepen example: https://codepen.io/isaacsgraphic/pen/jOVrrMO
body {
width: 980px;
background: #99c;
margin: 0 auto;
}
.row {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-column-gap: 20px;
background: white;
}
.content-wrap {
grid-column: span 12;
width: 100%
}
<div class="row">
<div class="content-wrap">
<p>Example paragraph which is 979.94px, not 980 like the row it's within</p>
</div>
</div>
here's a longer example which shows how this problem breaks my column layout on chrome: https://codepen.io/isaacsgraphic/pen/yLVJGqp
It seems that this is a rounding error in chrome. It is possible to recreate the problem with any layout which creates a recurring number sub-pixel fraction for column widths (like 3 or 12 column layouts with 980px), whereas numbers of columns which divide the width easily like 5 or 10 work without issues. The same issues can be caused by grid-column-gap numbers which don't divide nicely.
The simplest fix is to make sure the layout pixel width divides neatly into 12 (6 and 3 work too actually, since chrome can handle one or two decimal places)
body {
width: 984px;
background: #99c;
margin: 0 auto;
}
.row {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-column-gap: 18px;
background: white;
}
.content-wrap {
grid-column: span 12;
width: 100%
}
<div class="row">
<div class="content-wrap">
<p>Example paragraph which is fits the full width of the row it's within</p>
</div>
</div>
Maybe it is because of the different fonts different browsers use?

Grid items laying out as rows, but should be columns

I am trying out some very basic grids using display: grid. I have a simple grid with one row, divided into 6 columns. In the HTML I have a div containing the grid, then 6 nested divs containing the 6 items, which should display along one row in 6 columns.
However, instead, they stack on top of each other - why?
This is what it looks like when run:
.gridnav {
display: grid;
/*Gap between columns cells*/
grid-column-gap: 15px;
grid-row-gap: 2px;
/*Padding on left and right edges*/
padding: 0px 10px 0px;
/*Centres items vertically and horizontally*/
align-items: center;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-areas: '1 2 3 4 5 6';
}
.navitem1 { grid-area: 1; }
.navitem2 { grid-area: 2; }
.navitem3 { grid-area: 3; }
.navitem4 { grid-area: 4; }
.navitem5 { grid-area: 5; }
.navitem6 { grid-area: 6; }
<div class="gridnav">
<div class="navitem1">1</div>
<div class="navitem2">2</div>
<div class="navitem3">3</div>
<div class="navitem4">4</div>
<div class="navitem5">5</div>
<div class="navitem6">6</div>
</div>
Any ideas most welcome, thanks
I have a simple grid with one row, divided into 6 columns.
Actually, you have the reverse. You have a grid with one column, divided into 6 rows.
The grid-area property is a shorthand property. It breaks down like this:
grid-row-start
grid-column-start
grid-row-end
grid-column-end
Therefore, your code:
.navitem1 { grid-area: 1; }
.navitem2 { grid-area: 2; }
.navitem3 { grid-area: 3; }
.navitem4 { grid-area: 4; }
.navitem5 { grid-area: 5; }
.navitem6 { grid-area: 6; }
Is equivalent to this:
.navitem1 {
grid-row-start: 1;
grid-column-start: auto;
grid-row-end: auto;
grid-column-end: auto;
}
.navitem2 {
grid-row-start: 2;
grid-column-start: auto;
grid-row-end: auto;
grid-column-end: auto;
}
...
So here's what's really happening:
This rule in the container is doing exactly what you expect.
grid-template-areas: '1 2 3 4 5 6'
But then the grid-area rules are overriding grid-template-areas. Above is what it looks like in Chrome dev tools.
As you can see, the items are originally lined up in one row and six columns (as you expect). But in the end, all items line up on six rows in a one column (because of the grid-area overrides).
However, if you use a non-integer value, like this:
.navitem1 { grid-area: a; }
It would translate to this:
.navitem1 {
grid-row-start: a;
grid-column-start: a;
grid-row-end: a;
grid-column-end: a;
}
... which would work for your purposes, as the values of grid-template-areas and grid-area are fully aligned.
Spec reference for the grid-area property.
It seems that grid template areas can't be named integers. Changing them to a, b, c, etc. makes it work.
.gridnav {
display: grid;
/*Gap between columns cells*/
grid-column-gap: 15px;
grid-row-gap: 2px;
/*Padding on left and right edges*/
padding: 0px 10px 0px;
/*Centres items vertically and horizontally*/
align-items: center;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-areas: 'a b c d e f';
}
.navitem1 { grid-area: a; }
.navitem2 { grid-area: b; }
.navitem3 { grid-area: c; }
.navitem4 { grid-area: d; }
.navitem5 { grid-area: e; }
.navitem6 { grid-area: f; }
<div class="gridnav">
<div class="navitem1">1</div>
<div class="navitem2">2</div>
<div class="navitem3">3</div>
<div class="navitem4">4</div>
<div class="navitem5">5</div>
<div class="navitem6">6</div>
</div>
The solution can be achieved without writing these many lines of code. You don't need to use grid-template-area until and unless you want to switch the div positions. Let me take you to the solution real quick.
.gridnav {
width: 90%;
margin: 0 auto;
display: grid;
grid-template-rows: 1fr; /* Optional */
grid-template-columns: repeat(6,1fr);
grid-column-gap: 15px;
grid-row-gap: 2px;
align-items: center;
}
.gridnav div {
border: 2px solid red;
text-align: center;
}
First thing, define some width to the parent container. In your case it is div with class .gridnav. Since you already defined this section as a grid, I would define the rows and columns first. Since you don't need many rows but just one, it is okay not to define row.
For columns, you can have 1fr 1fr 1fr 1fr 1fr 1fr; but I would reduce code to grid-template-columns: repeat(6,1fr);
Further styling you can have as you want. Let me know if you have any further questions regarding this.
For more details you can always visit these two links:
https://mozilladevelopers.github.io/playground/css-grid/02-first-grid/
https://css-tricks.com/snippets/css/complete-guide-grid/
Hope you will find your answer in this. You can see code working here : Hit that Run Code Snippet button
.gridnav {
width: 90%;
margin: 0 auto;
display: grid;
grid-template-rows: 1fr; /* Optional */
grid-template-columns: repeat(6,1fr);
grid-column-gap: 15px;
grid-row-gap: 2px;
align-items: center;
}
.gridnav div {
border: 2px solid red;
text-align: center;
}
<div class="gridnav">
<div class="navitem1">1</div>
<div class="navitem2">2</div>
<div class="navitem3">3</div>
<div class="navitem4">4</div>
<div class="navitem5">5</div>
<div class="navitem6">6</div>
</div>

Align overflowing container to right of grid cell, not grid row

I have a 12 column grid. Column 1 is a month number and column 2-12 are a text title.
However, the font of the number is so large that it was forcing the column width to be larger than the other columns. I'm trying to keep equal column width while also not letting the contents of the first column overlap the title text.
To do this, I was hoping I could just align the contents of the first column to the right edge of the column... alas, it's not working.
Codepen
Here is the columns:
and this is the div inside column 1 that is holding the H3 number text:
How can I get the .date-container div to align it's right edge, to the right edge of it's parent column?
and of course, some code:
.month-title-grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: repeat(2, auto);
column-gap: 10px;
}
.date-container{
position: absolute;
}
.date-container h1{
position: relative;
text-align: end;
}
.col-1
{
grid-column-end: span 1;
}
<div class="month-title-grid">
<div class="col-12"><h3 class="lightbrown">January</h3></div>
<div class="col-1"><div class="date-container"><h1 class="lightbrown">01</h1></div></div>
<div class="col-11"><h2 class="darkbrown">IT'S COMPLICATED</h2>
Now that i understood this really should fix your problem, it works in your codepen for me.
.month-title-grid {
display: grid;
/*this will help to keep the columns even*/
grid-template-columns: repeat( 12, minmax(50px, 1fr) );
grid-template-rows: repeat(2, auto);
column-gap: 10px;
}
.col-1
{
/*this will force the overflow to the left*/
direction: rtl;
grid-column-end: span 1;
}
<div class="month-title-grid">
<div class="col-12"><h3 class="lightbrown">January</h3></div>
<div class="col-1"><div class="date-container"><h1 class="lightbrown">01</h1></div></div>
<div class="col-11"><h2 class="darkbrown">IT'S COMPLICATED</h2>