Grid layout: cell isn't covering all specified rows [duplicate] - css

This question already has answers here:
Make row stretch across all columns in CSS Grid
(3 answers)
Closed 4 years ago.
Could anyone help me figure out why .side isn't covering the third row in the following snippet? (Also, why is the third row so far down it generates a vertical scrollbar?)
I'm sorry to ask what is probably an extremely basic question, this is for a side project and I usually don't do CSS myself, just trying to learn grid as it feels the most natural to me.
Note: I'm guessing grid-row: 2 is equivalent to grid-row: 2 / 2 (same for the rest) but I wrote it explicitly just to be 100% sure (makes no difference).
.layout {
display: grid;
height: 100vh;
grid-template-rows: 50px 1fr 50px;
grid-template-columns: 250px 1fr;
}
header {
grid-row: 1 / 1;
grid-column: 2 / 2;
background-color: #ccf;
}
.side {
grid-row: 1 / 3;
grid-column: 1 / 1;
background-color: #ddd;
}
.main {
grid-row: 2 / 2;
grid-column: 2 / 2;
}
footer {
grid-row: 3 / 3;
grid-column: 2 / 2;
background-color: #ccf;
}
<div class="layout">
<header>header</header>
<div class="side">side</div>
<div class="main">main</div>
<footer>footer</footer>
</div>

You just have to change the 3 to a 4 as you want .side to start at the first line (the top of row 1) and end at the fourth line (the bottom of row 3). There is a good resource here: https://css-tricks.com/snippets/css/complete-guide-grid/
.layout {
display: grid;
height: 100vh;
grid-template-rows: 50px 1fr 50px;
grid-template-columns: 250px 1fr;
}
header {
grid-row: 1 / 1;
grid-column: 2 / 2;
background-color: #ccf;
}
.side {
grid-row: 1 / 4;
grid-column: 1 / 1;
background-color: #ddd;
}
.main {
grid-row: 2 / 2;
grid-column: 2 / 2;
}
footer {
grid-row: 3 / 3;
grid-column: 2 / 2;
background-color: #ccf;
}
<div class="layout">
<header>header</header>
<div class="side">side</div>
<div class="main">main</div>
<footer>footer</footer>
</div>

You should use n+1 in the grid-row-end to place the element until the nth row. Your code need to be like this:
.layout {
display: grid;
height: 100vh;
grid-template-rows: 50px 1fr 50px;
grid-template-columns: 250px 1fr;
}
header {
grid-row: 1 / 2;
grid-column: 2 / 3;
background-color: #ccf;
}
.side {
grid-row: 1 / 4;
grid-column: 1 / 2;
background-color: #ddd;
}
.main {
grid-row: 2 / 3;
grid-column: 2 / 3;
}
footer {
grid-row: 3 / 4;
grid-column: 2 / 3;
background-color: #ccf;
}
<div class="layout">
<header>header</header>
<div class="side">side</div>
<div class="main">main</div>
<footer>footer</footer>
</div>

.layout {
display: grid;
height: 100vh;
grid-template-rows: 50px 1fr 50px;
grid-template-columns: 250px 1fr;
}
header {
grid-row: 1 / 1;
grid-column: 2 / 2;
background-color: #ccf;
}
.side {
grid-row: 1 / 4;
grid-column: 1 / 1;
background-color: #ddd;
}
.main {
grid-row: 2 / 2;
grid-column: 2 / 2;
}
footer {
grid-row: 3 / 3;
grid-column: 2 / 2;
background-color: #ccf;
}
<div class="layout">
<header>header</header>
<div class="side">side</div>
<div class="main">main</div>
<footer>footer</footer>
</div>

Related

When using CSS Grid is it possible to have a child expand beyond their parent's grid placement?

I have a simple CSS grid with 5 columns and two rows. The first row contains 5 elements but I want the second row to contain the 5th element's child for all 5 columns, is this possible?
I want the red element (the child of element 5) to be 100% the width in the row below all the other elements.
.container {
display: grid;
grid-template-columns: [line1] min-content [line2] min-content [line3] min-content [line4] max-content [line5] max-content [end];
grid-template-rows: [row1-start] 10% [row1-end row2-start] auto [row2-end];
column-gap: 1em;
row-gap: 2em;
}
.element1 {
max-height: 2em;
grid-column-start: 1;
grid-column-end: 1;
grid-row-start: 1;
grid-row-end: 1;
background-color: pink;
}
.element2 {
max-height: 2em;
grid-column-start: 2;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 1;
background-color: blue;
}
.element3 {
max-height: 2em;
grid-column-start: 3;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 1;
background-color: orange;
}
.element4 {
max-height: 2em;
grid-column-start: 4;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 1;
background: yellow;
}
.element5 {
grid-column-start: 5;
grid-column-end: 5;
grid-row-start: 1;
grid-row-end: 1;
justify-self: end;
background-color: purple;
}
.element-sub5 {
grid-column: 1 / 5;
grid-row: 2;
border: 1px solid red;
background-color: red;
padding: 0 1em;
margin-top: 2.5em;
width: 100%;
height: 10em;
float: left;
}
<div class="container">
<div class="element1">
element1
</div>
<div class="element2">
element2
</div>
<div class="element3">
element3
</div>
<div class="element4">
element4
</div>
<div class="element5">
element5
<span class="element-sub5">
REALLY BIG BOX OF TEXT
</span>
</div>
</div>
Example layout
It’s possible to set up a grid like this but only if your 5th items element isn’t inside it…
CSS
.parent {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(2, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
.div1 { grid-area: 1 / 1 / 2 / 2; }
.div2 { grid-area: 1 / 2 / 2 / 3; }
.div3 { grid-area: 1 / 3 / 2 / 4; }
.div4 { grid-area: 1 / 4 / 2 / 5; }
.div5 { grid-area: 1 / 5 / 2 / 6; }
.div6 { grid-area: 2 / 1 / 3 / 6; }
HTML
<div class="parent">
<div class="div1"> </div>
<div class="div2"> </div>
<div class="div3"> </div>
<div class="div4"> </div>
<div class="div5"> </div>
<div class="div6"> </div>
</div>

CSS Expand grid item to left or right when space freed up

I have the following template with a grid template and some buttons that hide and show div1 and div4, and the area of div2 and div3 should expand accordingly. I want that when div1 is not present, that div2 and div3 area should expand to the left (start from column 1 instead of column 2), and similarly div3 should end at column 6 when div4 is not present.
.parent {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(5, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
height: 500px;
}
.parent div {
border: 1px black solid;
}
.div1 {
grid-area: 1 / 1 / 6 / 2;
}
.div2 {
grid-area: 1 / 2 / 2 / 6;
}
.div2.expandedLeft {
grid-area: 1 / 1 / 2 / 6;
}
.div3 {
grid-area: 2 / 2 / 6 / 5;
}
.div3.expandedLeft {
grid-area: 2 / 1 / 6 / 5;
}
.div3.expandedRight {
grid-area: 2 / 2 / 6 / 6;
}
.div3.expandedLeft.expandedRight {
grid-area: 2 / 1 / 6 / 6;
}
.div4 {
grid-area: 2 / 5 / 6 / 6;
}
<div class="parent">
<div class="div1" *ngIf="!hideDiv1"></div>
<div class="div2" [class.expandedLeft]="hideDiv1"></div>
<div class="div3" [class.expandedLeft]="hideDiv1" [class.expandedRight]="hideDiv2"></div>
<div class="div4" *ngIf="!hideDiv2"></div>
</div>
<div>
<button (click)="hideDiv1 = true">hide it</button>
<button (click)="hideDiv1 = false">show it</button>
</div>
<div>
<button (click)="hideDiv2 = true">hide it</button>
<button (click)="hideDiv2 = false">show it</button>
</div>
As you can see what I have tried was to add some classes when div1 or div4 are removed from DOM, and I play with the grid-area. It works. But I am wondering if there is a more automatic way of doing it?
Here is a stackblitz that shows my working solution https://stackblitz.com/edit/angular-rp5xkh
With a series of selectors this is actually possible but I'd suggest it's not really scalable.
.parent {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(5, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
height: 20vh;
margin-bottom: 2vh;
}
.parent div {
border: 1px black solid;
display: flex;
justify-content: center;
align-items: center;
font-size: 8vh;
}
.div1 {
grid-row: 1 / 6;
grid-column: 1;
background: lightblue;
}
.div2 {
grid-row: 1 / 2;
grid-column: 1 / -1;
background: lightgreen;
}
.div1+.div2 {
grid-row: 1 / 2;
grid-column: 2 / -1;
}
.div3 {
grid-row: 2 / 6;
grid-column: 1 / 5;
background: red;
}
.div1~.div3 {
grid-row: 2 / 6;
grid-column: 2 / 5;
}
.div3:last-child {
grid-row: 2 / 6;
grid-column: 1 / -1;
}
.div1~.div3:last-child {
grid-row: 2 / 6;
grid-column: 2 / -1;
}
.div4 {
grid-row: 2 / 6;
grid-column: 5 /6;
background: orange;
opacity: .5
}
<div class="parent">
<div class="div1">1</div>
<div class="div2">2</div>
<div class="div3">3</div>
<div class="div4">4</div>
</div>
<div class="parent">
<div class="div2">2</div>
<div class="div3">3</div>
<div class="div4">4</div>
</div>
<div class="parent">
<div class="div1">1</div>
<div class="div2">2</div>
<div class="div3">3</div>
</div>
<div class="parent">
<div class="div2">2</div>
<div class="div3">3</div>
</div>

How to fix css grid-rows that are not spanning correctly?

I have content that won't span 2 rows unless I give it a position: absolute for some reason, but then it overlaps the footer on pages with longer content. This is an example on the site I'm working on: https://carlisleacademymaine.com/pony-club-riding-center-program/
When I test it on the simple code below it seems to work fine, but on my site it doesn't. Maybe something else on the site is causing problems, but I can't figure it out.
.container {
display: grid;
width: 100%;
grid-template-columns: 400px auto;
grid-template-rows: 40px minmax(760px, auto) auto auto;
min-height: 100%;
grid-gap: 0;
position: relative;
grid-template-areas: none;
}
.header {
background-color: aqua;
grid-column: 1 / span 2;
grid-row: 1 / 2;
}
.sidebar {
background-color: red;
grid-column: 1 / span 1;
grid-row: 2 / 3;
}
.main-content {
background-color: chartreuse;
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 4;
}
.sidebar-widget {
background-color: lightblue;
grid-column: 1 / span 1;
grid-row: 3 / 4;
}
.footer {
background-color: aqua;
grid-column: 1 / span 2;
grid-row: 4 / 5;
}
<div class="container">
<div class="header">header</div>
<div class="sidebar">sidebar</div>
<div class="main-content">content </div>
<div class="sidebar-widget">extras</div>
<div class="footer">This is my foot</div>
</div>

CSS Grid row/column gap on specific elements? [duplicate]

This question already has answers here:
Setting different lengths for grid gaps in CSS Grid
(2 answers)
Can grid-row-gap / grip-column-gap be overridden for a single gutter?
(1 answer)
Closed 4 years ago.
I have created the grid below using CSS Grid and I am wondering if it's possible to have a gap only between specific elements within the grid, rather than applying a universal gap to all grid elements. Here's what I have right now:
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: [col] 100px [col] 100px [col] 100px;
grid-template-rows: [row] auto [row] auto [row] ;
background-color: #fff;
color: #444;
}
.box {
background-color:#444;
color:#fff;
padding:20px;
font-size:150%;
}
.a {
grid-column: col / span 2;
grid-row: row 1 / 3;
}
.b {
grid-column: col 3 / span 1;
grid-row: row ;
}
.c {
grid-column: col 3 / span 1;
grid-row: row 2 ;
}
.d {
grid-column: col / span 1;
grid-row: row 3;
}
.e {
grid-column: col 2 / span 1;
grid-row: row 3;
}
.f {
grid-column: col 3 / span 1;
grid-row: row 3;
}
.g {
grid-column: col / span 1;
grid-row: row 4;
}
.h {
grid-column: col 2 / span 1;
grid-row: row 4;
}
.i {
grid-column: col 3 / span 1;
grid-row: row 4;
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
</div>
I would like to remove the gap between the top 2 rows on the right side and between each cell on the rows below that. I would like to keep the cells broken up as they are now because the layout will be different on desktop. Here's a graphical representation of what I'm going for:
It's impossible to change the gap on specific elements.
However, you can reference specific grid item with grid-item:nth-child(n) and set negative margins to it.
For example, with a class of picture-1 it may look like this in the CSS file:
.picture-1:nth-child(3) {
margin-bottom: -50px;
}
I have a work around to get your desired result. I just moved all the three rows in a separate grid section. I am not sure if it helps or not but here it is:
body {
margin: 40px;
}
.wrapper1 {
display: grid;
grid-gap: 10px;
grid-template-columns: [col] 100px [col] 100px [col] 100px;
grid-template-rows: [row] auto [row] auto [row] ;
background-color: #fff;
color: #444;
margin-bottom: 10px;
}
.wrapper2 {
display: grid;
grid-template-columns: [col] 100px [col] 100px [col] 100px;
grid-template-rows: [row] auto [row] auto [row] ;
background-color: #fff;
color: #444;
margin-bottom: 10px;
}
.wrapper3 {
display: grid;
grid-template-columns: [col] 100px [col] 100px [col] 100px;
grid-template-rows: [row] auto [row] auto [row] ;
background-color: #fff;
color: #444;
margin-bottom: 10px;
}
.box {
background-color:#444;
color:#fff;
padding:20px;
font-size:150%;
}
.a {
grid-column: col 1 / span 2;
grid-row: row 1 / 3;
}
.b {
grid-column: col 3 / span 1;
grid-row: row ;
}
.c {
grid-column: col 3 / span 1;
grid-row: row 2 ;
}
.d {
grid-column: col 1 / span 1;
grid-row: row 3;
width: 80%;
}
.e {
grid-column: col 2 / span 1;
grid-row: row 3;
width: 80%;
}
.f {
grid-column: col 3 / span 1;
grid-row: row 3;
width: 80%;
}
.g {
grid-column: col 1 / span 1;
grid-row: row 4;
width: 80%;
}
.h {
grid-column: col 2 / span 1;
grid-row: row 4;
width: 80%;
}
.i {
grid-column: col 3 / span 1;
grid-row: row 4;
width: 80%;
}
<div class="wrapper1">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
</div>
<div class="wrapper2">
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
</div>
<div class="wrapper3">
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
</div>

CSS3 Grid - why the rows are not positioned as per column/row stmt

I'm trying to design a tv remote control with up/OK/down/left/right buttons using a grid layout. The issue is that the result is unexpected to me. I simply want to define 3 rows and 3 columns with specific position and space equally divided between them. What am I doing wrong? The result looks like this
Up left OK
right down
Instead of
Up
|
<left----OK---Right-->
|
Down
Code
#grid {
display: grid;
grid-template-columns:
/* 1 */ auto
/* 2 */ auto
/* 3 */ auto;
grid-template-rows:
/* 4 */ auto
/* 5 */ auto
/* 6 */ auto;
}
#up { grid-column: 2; grid-row: 1; }
#ok { grid-column: 2; grid-row: 2; }
#down { grid-column: 2; grid-row: 3; }
#left { grid-column: 1; grid-row: 3; }
#right { grid-column: 3; grid-row: 3; }
}
<div id="grid">
<div class="up">Up</div>
<div class="left">left</div>
<div class="ok">OK</div>
<div class="right">right</div>
<div class="down">down</div>
</div>
Your main problem is that you have set classes on your inner elements, and are styling ids
#grid {
display: grid;
grid-template-columns:
/* 1 */ auto
/* 2 */ auto
/* 3 */ auto;
grid-template-rows:
/* 4 */ auto
/* 5 */ auto
/* 6 */ auto;
width: 200px;
}
#grid div {
width: 50px;
height: 50px;
background-color: lightblue;
margin: 3px;
}
.up { grid-column: 2; grid-row: 1; }
.ok { grid-column: 2; grid-row: 2; }
.down { grid-column: 2; grid-row: 3; }
.left { grid-column: 1; grid-row: 2; }
.right { grid-column: 3; grid-row: 2; }
<div id="grid">
<div class="up">Up</div>
<div class="left">left</div>
<div class="ok">OK</div>
<div class="right">right</div>
<div class="down">down</div>
</div>

Resources