Irregular grid lines on one part of css grid - html

I've got a really simple grid set up in CSS, but when I look at the grid lines in the inspector there's a strange irregularity at the bottom. I can't understand why this exists when the rest of the grid lines are all regular.
There's no special styling on div-4, it's just the same as the rest. Is it something to do with the margins produced by the h3 tag?
HTML
<div class="left-sidebar-grid">
<div class="div1">
<h3>Div1</h3>
</div>
<div class="div2">
<h3>Div2</h3>
</div>
<div class="div3">
<h3>Div3</h3>
</div>
<div class="div4">
<h3>Div4</h3>
</div>
</div>
CSS
.left-sidebar-grid {
height: 100%;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: repeat(8, 1fr);
grid-gap: 16px;
}
.div1 { grid-area: 1 / 1 / 2 / 2; }
.div2 { grid-area: 2 / 1 / 4 / 2; }
.div3 { grid-area: 4 / 1 / 10 / 2; }
.div4 { grid-area: 10 / 1 / 11 / 2; }

You defined only 8 explicit rows and you have placed the div4 starting at line 10 which will create 2 extra rows so you will end up with 10 rows in total where only 8 are sized using the 1fr and 2 will have an auto size: the empty one you see and the one where you placed div4.
To avoid this use grid-auto-rows:1fr instead of your template in order to make sure all the rows are sized the same way:
.left-sidebar-grid {
height: 100%;
display: grid;
grid-template-columns: 1fr;
grid-auto-rows: 1fr;
grid-gap: 16px;
}
.div1 { grid-area: 1 / 1 / 2 / 2; }
.div2 { grid-area: 2 / 1 / 4 / 2; }
.div3 { grid-area: 4 / 1 / 10 / 2; }
.div4 { grid-area: 10 / 1 / 11 / 2; }
<div class="left-sidebar-grid">
<div class="div1">
<h3>Div1</h3>
</div>
<div class="div2">
<h3>Div2</h3>
</div>
<div class="div3">
<h3>Div3</h3>
</div>
<div class="div4">
<h3>Div4</h3>
</div>
</div>
You can also simplify your code like below:
.left-sidebar-grid {
display: grid;
grid-template-columns: 1fr;
grid-auto-rows: 1fr;
grid-gap: 16px;
}
.div1 {
grid-row:span 1;
}
.div2 {
grid-row:span 2;
}
.div3 {
grid-row:span 6;
}
.div4 {
grid-row:span 1;
}
<div class="left-sidebar-grid">
<div class="div1">
<h3>Div1</h3>
</div>
<div class="div2">
<h3>Div2</h3>
</div>
<div class="div3">
<h3>Div3</h3>
</div>
<div class="div4">
<h3>Div4</h3>
</div>
</div>

Related

Grid items wont center align despite using align and justify items

I created a grid using 6 images and structured it the way how i want it. The only issue im having with my grid is that I cannot center it. It's leaning too far to the left and have a huge gap on the right. I tried using align items: Center and justify content: center but my grid does not move at all. If i were to use padding it will move but it does not translate well when i look at my project from a different device. What can i do to fix this issue? Thanks.
.PophikeMargin{
margin-top: 50px;
margin-bottom: 50px;
text-align: center;
}
.PophikeMargin h1{
margin: 30px;
}
.Hiking-grid-container{
display: grid;
grid-template-columns: repeat(9, 1fr);
grid-template-rows: repeat(4, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
justify-content: center
}
.Hiking-item1 {
grid-area: 1 / 1 / 3 / 2;
height: 400px;
width: 350px;
}
.Hiking-item2 {
grid-area: 3 / 1 / 5 / 2;
height: 400px;
width: 350px;
}
.Hiking-item3 {
grid-area: 1 / 2 / 6 / 4;
height: 800px;
width: 700px;
}
.Hiking-item4 {
grid-area: 1 / 4 / 3 / 6;
height: 400px;
width: 705px;
}
.Hiking-item5 {
grid-area: 3 / 4 / 5 / 5;
height: 400px;
width: 350px;
}
.Hiking-item6 {
grid-area: 3 / 5 / 5 / 6;
height: 400px;
width: 350px;
}
<section class="Popular-Hiking-Trails">
<div class="PophikeMargin">
<h1>Popular Hiking Destinations</h1>
<div class="Hiking-grid-container">
<div class="Hiking-item1">
<img src="Images/****" width="350" height="400">
</div>
<div class="Hiking-item2">
<img src="Images/****" width="350" height="400">
</div>
<div class="Hiking-item3">
<img src="Images/****" width="350" height="400">
</div>
<div class="Hiking-item4">
<img src="Images/****" width="350" height="400">
</div>
<div class="Hiking-item5">
<img src="Images/****" width="350" height="400">
</div>
<div class="Hiking-item6">
<img src="Images/****" width="350" height="400">
</div>
</div>
</div>
</section>
Several points in your code:
you defined a 9 cols and 4 rows grid
you position the item inside with their row-start, col-start, row-end, col-end but not with the good values. If you want to design grid with grid-area check here: http://cssgridbuilder.com/
if you want to center the element use ...-self for the element to center
Here a snippet with 2 cols, 2 rows and images inside with grid-area. If you need dynamic numbering of images, it's more an approach with span to take.
.PophikeMargin {
margin-top: 50px;
margin-bottom: 50px;
text-align: center;
}
.PophikeMargin h1 {
margin: 30px;
}
.Hiking-grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 10px;
}
.Hiking-item1 {
grid-area: 1 / 1 / 2 / 2;
}
.Hiking-item2 {
grid-area: 1 / 2 / 2 / 3;
}
.Hiking-item3 {
grid-area: 1 / 3 / 2 / 4;
}
.Hiking-item4 {
grid-area: 2 / 1 / 3 / 2;
}
.Hiking-item5 {
grid-area: 2 / 2 / 3 / 3;
}
.Hiking-item6 {
grid-area: 2 / 3 / 3 / 4;
}
.Hiking-grid-container>div {
height: auto;
width: 33%;
justify-self: center;
align-self: center;
}
<section class="Popular-Hiking-Trails">
<div class="PophikeMargin">
<h1>Popular Hiking Destinations</h1>
<div class="Hiking-grid-container">
<div class="Hiking-item1">
<img src="https://picsum.photos/id/237/350/400">
</div>
<div class="Hiking-item2">
<img src="https://picsum.photos/id/184/350/400">
</div>
<div class="Hiking-item3">
<img src="https://picsum.photos/id/125/350/400">
</div>
<div class="Hiking-item4">
<img src="https://picsum.photos/id/85/350/400">
</div>
<div class="Hiking-item5">
<img src="https://picsum.photos/id/51/350/400">
</div>
<div class="Hiking-item6">
<img src="https://picsum.photos/id/100/350/400">
</div>
</div>
</div>
</section>

Make a grid as big as the screen

I need the grid ad big as the page (it should touch the top the bottom and both sides) and I'd like it to be non-scrollable.
HTML:
<div class="wrapper">
<div class="prova">One</div>
<div class="prova"> </div>
<div class="prova">Three</div>
<div class="prova">Four</div>
<div class="prova"> five </div>
<div class="prova">Six</div>
<div class="prova">Seven</div>
<div class="prova">Eight</div>
<div class="prova">Nine</div>
<div class="prova">Ten</div>
<div class="prova">Eleven</div>
<div class="prova">Twelve</div>
</div>
CSS:
.wrapper {
padding-top: 10%;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 100px;
}
.prova{
border: 1px solid;
}
.wrapper div:nth-child(2) {
grid-column: 3;
grid-row: 2 / 4;
}
.wrapper div:nth-child(5) {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
I've read multiple questions but I couldn't find any solution that works fine for me.
As you can see in the picture above the grid doesn't touch neither the top or the bottom!
Set gird-auto-rows to use a percentage of the viewport height. Equal amounts per expected row. So in your case 25vh. Then remove any padding or margin around the grid.
html, body {
margin: 0
}
.wrapper {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 25vh;
width: 100%;
}
.prova{
border: 1px solid;
}
.wrapper div:nth-child(2) {
grid-column: 3;
grid-row: 2 / 4;
}
.wrapper div:nth-child(5) {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
<div class="wrapper">
<div class="prova">One</div>
<div class="prova"> </div>
<div class="prova">Three</div>
<div class="prova">Four</div>
<div class="prova"> five </div>
<div class="prova">Six</div>
<div class="prova">Seven</div>
<div class="prova">Eight</div>
<div class="prova">Nine</div>
<div class="prova">Ten</div>
<div class="prova">Eleven</div>
<div class="prova">Twelve</div>
</div>
If you want it to touches the top just remove the padding
And for other sides just set the width and height of the wrapper to 100vh and 100vw

How to align grid items vertically using display:grid and fill all vertical empty space? [duplicate]

This question already has answers here:
How can I make a div span multiple rows and columns in a grid?
(3 answers)
Closed 1 year ago.
I use display:grid not flex to display some divs.
Here's what my page looks like:
And here is how I would like it to look:
And here's the code:
.container {
display: grid;
grid-template-columns: 1.5fr 2fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-auto-columns: 1fr;
grid-auto-rows: 1fr;
gap: 40px 40px;
grid-auto-flow: row dense;
justify-items: stretch;
align-items: stretch;
grid-template-areas: "left1 center-div right1" "left1 center-div right2" "left2 center-div right3";
width: 100%;
height: 100%;
}
.left1 {
grid-area: left1;
}
.left2 {
grid-area: left2;
}
.center-div {
grid-area: center-div;
}
.right1 {
grid-area: right1;
}
.right2 {
grid-area: right2;
}
.right3 {
grid-area: right3;
}
<div class="container owl-carousel owl-theme">
<div class="grid-item left1">
left image 1
</div>
<div class="grid-item left2">
left image 2
</div>
<div class="grid-item center-div">
center image
</div>
<div class="grid-item right1">
right image 1
</div>
<div class="grid-item right2">
right image 2
</div>
<div class="grid-item right3">
right image 3
</div>
</div>
In short, I want to bring the divs closer so that they appear as they are in the second photo
Using CSS Grid
Following demo shows how you can achieve the desired layout using just the grid layout.
Its a 6 x 3 grid where items on the left span 3 rows each and the items on the right span 2 rows each. The item in the center spans all 6 rows.
Each grid items is adjusted in its place using the grid-row and grid-column properties.
The trick to achieving this layout is having more rows than columns.
.container {
display: grid;
grid-template-columns: 1.5fr 2fr 1fr;
grid-template-rows: repeat(6, 1fr);
grid-gap: 30px;
height: 100vh;
}
.grid-item {
background: #eee;
width: 100%;
}
.center {
grid-row: 1 / span 6;
grid-column: 2 / span 1;
}
.left1 {
grid-row: 1 / span 3;
grid-column: 1 / span 1;
}
.left2 {
grid-row: 4 / span 3;
grid-column: 1 / span 1;
}
.right1,
.right2,
.right3 {
grid-column: 3 / span 1;
}
.right1 { grid-row: 1 / span 2; }
.right2 { grid-row: 3 / span 2; }
.right3 { grid-row: 5 / span 2; }
<div class="container">
<div class="grid-item left1">left1</div>
<div class="grid-item left2">left2</div>
<div class="grid-item center">center</div>
<div class="grid-item right1">right1</div>
<div class="grid-item right2">right2</div>
<div class="grid-item right3">right3</div>
</div>
Using CSS Grid along with Flexbox
Another option is to have a 1 x 3 grid and make each grid column a flex container.
You will need to change the structure of the HTML if you use this approach.
:root {
--spacing: 30px;
}
.container {
display: grid;
grid-template-columns: 1.5fr 2fr 1fr;
grid-gap: var(--spacing);
height: 100vh;
}
.grid-item {
display: flex;
}
.grid-item div {
background: #eee;
flex-basis: 100%;
}
.col-1,
.col-3 {
flex-direction: column;
justify-content: space-between;
}
.margin-bottom {
margin-bottom: var(--spacing);
}
<div class="container">
<div class="grid-item col-1">
<div class="margin-bottom">left1</div>
<div>left2</div>
</div>
<div class="grid-item col-2">
<div>center</div>
</div>
<div class="grid-item col-3">
<div class="margin-bottom">right1</div>
<div class="margin-bottom">right2</div>
<div>right3</div>
</div>
</div>

Empty overlapping css grid cell prevents clicks in Firefox and Edge

In one page of our app we have a grid with two cells stacked one on top of the other.
On Chrome the middle textbox in the grid shown below is clickable, but in Firefox and Edge(17) it cannot be clicked.
I'm curious about which browser has the bug or whether this is undefined behaviour?
More immediately though is there a workaround for Firefox?
Thanks.
.grid {
display: grid;
align-items: stretch;
justify-items: stretch;
grid-template-rows: [first] repeat(2, minmax(auto, auto)) [last];
}
input {
width: 100%;
}
.a {
grid-area: 1 / 1 / span 1 / span 4;
}
.b {
grid-area: 1 / 5 / span 1 / span 4;
}
.c {
grid-area: 1 / 5 / span 1 / span 4;
}
.d {
grid-area: 1 / 9 / span 1 / span 4;
}
<div class="grid">
<div class="a">
<input>
</div>
<div class="b">
<input>
</div>
<div class="c">
</div>
<div class="d">
<input>
</div>
</div>
Stackblitz link: https://stackblitz.com/edit/js-pukd5g?file=index.html
you can reset pointer-events to allow clicking through an element, or reset position to bring an element on top of static elements:
pointer-events:
.grid {
display: grid;
align-items: stretch;
justify-items: stretch;
grid-template-rows: [first] repeat(2, minmax(auto, auto)) [last];
}
input {
width: 100%;
}
.a {
grid-area: 1 / 1 / span 1 / span 4;
}
.b {
grid-area: 1 / 5 / span 1 / span 4;
}
.c {
grid-area: 1 / 5 / span 1 / span 4;
pointer-events:none;/* here it won't catch mouse events */
}
.d {
grid-area: 1 / 9 / span 1 / span 4;
}
<div class="grid">
<div class="a">
<input>
</div>
<div class="b">
<input>
</div>
<div class="c">
</div>
<div class="d">
<input>
</div>
</div>
position
.grid {
display: grid;
align-items: stretch;
justify-items: stretch;
grid-template-rows: [first] repeat(2, minmax(auto, auto)) [last];
}
input {
width: 100%;
position:relative;/* will be at front of static positionned elements */
}
.a {
grid-area: 1 / 1 / span 1 / span 4;
}
.b {
grid-area: 1 / 5 / span 1 / span 4;
}
.c {
grid-area: 1 / 5 / span 1 / span 4;
}
.d {
grid-area: 1 / 9 / span 1 / span 4;
}
<div class="grid">
<div class="a">
<input>
</div>
<div class="b">
<input>
</div>
<div class="c">
</div>
<div class="d">
<input>
</div>
</div>
I'm not sure if it's a bug or just a difference in rendering behavior among browsers.
But a simple workaround is to layer the clickable element over the empty element using z-index.
Add this to your code:
.b {
z-index: 1;
}
.grid {
display: grid;
grid-template-rows: [first] repeat(2, minmax(auto, auto)) [last];
}
input {
width: 100%;
}
.a {
grid-area: 1 / 1 / span 1 / span 4;
}
.b {
grid-area: 1 / 5 / span 1 / span 4;
z-index: 1; /* new */
}
.c {
grid-area: 1 / 5 / span 1 / span 4;
}
.d {
grid-area: 1 / 9 / span 1 / span 4;
}
<div class="grid">
<div class="a">
<input>
</div>
<div class="b">
<input>
</div>
<div class="c">
</div>
<div class="d">
<input>
</div>
</div>

Css grid, large size on some cards, how to place them like this

I'm using grid for this layout and I'm halfway through. As you can see number 10,20,30,40,50 gets placed on the same spot (I place them there). I would like to have my layout as from 1 to 10 are
Large on the left (1,11,21,31,41...), 4 small on the right
Large on the right (10,20,30,40...), 4 small on the left
NOTE, this list can contain from 40-100 items, so using fixed positions to place it there would not be an option. Also the making nr 6 large and changing the order does not work either due to sorting.
Hope it's clear what I'm trying to do here.
.layout-scale {
display: grid;
grid-template-columns: repeat(4, 25%);
grid-gap: 1rem;
}
.layout-scale__items {
background-color: aqua;
min-height: 10rem;
}
.layout-scale__items:nth-child(10n + 1) {
background-color: deeppink;
grid-column: span 2;
grid-row: span 2;
}
.layout-scale__items:nth-child(10n + 10) {
background-color: lime;
grid-column: 3 / span 2;
grid-row: 3 / span 2;
}
<div class="layout-scale">
<div class="layout-scale__items">1</div>
<div class="layout-scale__items">2</div>
<div class="layout-scale__items">3</div>
<div class="layout-scale__items">4</div>
<div class="layout-scale__items">5</div>
<div class="layout-scale__items">6</div>
<div class="layout-scale__items">7</div>
<div class="layout-scale__items">8</div>
<div class="layout-scale__items">9</div>
<div class="layout-scale__items">10</div>
<div class="layout-scale__items">11</div>
<div class="layout-scale__items">12</div>
<div class="layout-scale__items">13</div>
<div class="layout-scale__items">14</div>
<div class="layout-scale__items">15</div>
<div class="layout-scale__items">16</div>
<div class="layout-scale__items">17</div>
<div class="layout-scale__items">18</div>
<div class="layout-scale__items">19</div>
<div class="layout-scale__items">20</div>
<div class="layout-scale__items">21</div>
<div class="layout-scale__items">22</div>
<div class="layout-scale__items">23</div>
<div class="layout-scale__items">24</div>
<div class="layout-scale__items">25</div>
<div class="layout-scale__items">26</div>
<div class="layout-scale__items">27</div>
<div class="layout-scale__items">28</div>
<div class="layout-scale__items">29</div>
<div class="layout-scale__items">30</div>
<div class="layout-scale__items">31</div>
<div class="layout-scale__items">32</div>
<div class="layout-scale__items">33</div>
<div class="layout-scale__items">34</div>
<div class="layout-scale__items">35</div>
<div class="layout-scale__items">36</div>
<div class="layout-scale__items">37</div>
<div class="layout-scale__items">38</div>
<div class="layout-scale__items">39</div>
<div class="layout-scale__items">40</div>
<div class="layout-scale__items">41</div>
<div class="layout-scale__items">42</div>
<div class="layout-scale__items">43</div>
<div class="layout-scale__items">44</div>
<div class="layout-scale__items">45</div>
<div class="layout-scale__items">46</div>
<div class="layout-scale__items">47</div>
<div class="layout-scale__items">48</div>
<div class="layout-scale__items">49</div>
<div class="layout-scale__items">50</div>
</div>
All green boxes start at 3rd row (grid-row: 3 / span 2) so they are in the same place.
Also, if I understood the pattern in your mind, you have to use indexes 1,11,21,.. and indexes 8,18,28,...
Try this:
.layout-scale {
display: grid;
grid-template-columns: repeat(4, 25%);
grid-gap: 1rem;
}
.layout-scale__items {
background-color: aqua;
min-height: 10rem;
}
.layout-scale__items:nth-child(10n + 1) {
background-color: deeppink;
grid-column: span 2;
grid-row: span 2;
}
.layout-scale__items:nth-child(10n + 8) {
background-color: lime;
grid-column: span 2;
grid-row: span 2;
}
I have landed in solving it with "fixed" position on grid-row. I have a loop in scss that generates it for the :nth-child(). The 10 extra classes are worth it compared to the extra markup and css to solve it with a "row" "bootstrap if you will" approach, and even more css for eventually that would be for a fallback solution. For my use case it will not be more than 100 items. If your case use more then 100 items just change the loop times.
$increment: 3;
// change the 10 to your wanted amount
#for $i from 1 through 10 {
.layout-scale__items:nth-child(#{$i*10}) {
grid-row: #{$increment} / span 2;
}
$increment: $increment + 4;
}
My full solution is on jsfiddle (due to internal code editor does not support scss)
<div class="layout-scale">
<div class="layout-scale__items">1</div>
<div class="layout-scale__items">2</div>
<div class="layout-scale__items">3</div>
<div class="layout-scale__items">4</div>
<div class="layout-scale__items">5</div>
<div class="layout-scale__items">6</div>
<div class="layout-scale__items">7</div>
<div class="layout-scale__items">8</div>
<div class="layout-scale__items">9</div>
<div class="layout-scale__items">10</div>
<div class="layout-scale__items">11</div>
...
</div>
.layout-scale {
display: grid;
grid-template-columns: repeat(4, 25%);
grid-gap: 1rem;
}
.layout-scale__items {
background-color: aqua;
min-height: 10rem;
}
.layout-scale__items:nth-child(10n + 1) {
background-color: deeppink;
grid-column: span 2;
grid-row: span 2;
}
.layout-scale__items:nth-child(10n + 10) {
background-color: lime;
grid-column: 3 / span 2;
}
$increment: 3;
#for $i from 1 through 10 {
.layout-scale__items:nth-child(#{$i*10}) {
grid-row: #{$increment} / span 2;
}
$increment: $increment + 4;
}