I want to place box 2 on top of both other boxes by half of them, however, even having explicitly defined grid-template-columns propriety to 1fr it automatically creates another column.
Here is my attempt
index.html
<div class="grid-overlap">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
style.scss
.grid-overlap {
max-width: 40rem;
width: 95%;`your text`
margin: 2rem auto;
gap: 1rem;
display: grid;
grid-template-rows: repeat(4, 1fr);
grid-template-columns: 1fr;
.box {
width: 300px;
height: 300px;
margin: 0 auto;
text-align: center;
font-size: 3rem;
}
.box:nth-child(1) {
grid-row: 1 / 3;
background-color: dodgerblue;
}
.box:nth-child(2) {
background-color: red;
grid-row: 2 / 4;
z-index: 100;
}
.box:nth-child(3) {
grid-row: 3 / 5;
background-color: tomato;
}
}
Thanks in advance.
I am giving one example of overlap, try to see how it works and use it in your use case.
.grid-overlap {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 100px;
}
.grid-overlap .box:nth-child(1) {
grid-row: 1/3;
grid-column: 1/3;
background-color: dodgerblue;
}
.grid-overlap .box:nth-child(2) {
background-color: rgba(255, 0, 0, 0.6);
grid-row: 2/4;
grid-column: 2/4;
}
<div class="grid-overlap">
<div class="box">1</div>
<div class="box">2</div>
</div>
Looking at the grid we can see that the second square starts in the middle of the first one and that the last one is positioned at one quarter along and three quarters down the first square.
This leads to a grid of width 6 and height 7 square cells.
As it's not possible to have both the grid imensions set at 300px and the width of the grid to be defined in rems (and % units) this snippet drops the 300px settings and sets the overall grid to be the width as defined in the question and the aspect ratio 6/7.
Note that the grid gap is not set (defaults to 0) as no gap was shown in the picture given in the question.
body {
width: 100vw;
height: 100vh;
}
.grid-overlap {
max-width: 40rem;
width: 95%;
aspect-ratio: 6 / 7;
margin: 2rem auto;
gap: 1rem;
gap: 0;
display: grid;
grid-template-rows: repeat(7, 1fr);
grid-template-columns: repeat(6, 1fr);
}
.box {
/*width: 300px;
height: 300px;*/
width: 100%;
height: 100%;
margin: 0 auto;
text-align: center;
font-size: 3rem;
}
.box:nth-child(1) {
grid-column: 1 / span 4;
grid-row: 1 / span 4;
background-color: dodgerblue;
}
.box:nth-child(2) {
background-color: red;
grid-column: 3 / span 4;
grid-row: 3 / span 4;
z-index: 100;
}
.box:nth-child(3) {
grid-column: 2/ span 4;
grid-row: 4 / span 4;
background-color: tomato;
}
<body>
<div class="grid-overlap">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
</body>
If the important dimensions were the 300px then use those to set the width of the overall grid.
Related
enter image description here
How do I make my grid cell same size after spanning it over the next cell? This is what I have tried so far
.factory {
display: grid;
grid-template-columns: 1fr 1fr 2fr;
height: 600px;
gap: 10px;
margin-top: 100px;
padding: 10px;
}
.factory>div {
background-color: gray;
border: 1px green solid;
}
.image-1 {
width: 100%;
height: auto;
}
.div-3 {
grid-column: 3 / span 5;
}
.div-5 {
grid-column: 1 / span 2;
}
<div class="factory">
<div class="div-1">box1</div>
<div class="div-2">box2</div>
<div class="div-3">box3</div>
<div class="div-5">box5</div>
<div class="div-6">box6</div>
</div>
As you can see box6 is smaller than the rest of the boxes.
Your issue is that on div-3 you try to span 5 columns after it has started at column 3 which will make the browser attempt to add 5 more columns to the grid.
.div-3 {
grid-column: 3 / span 5;
}
You can either remove this section completely because you have already specified in your grid-template-columns: 1fr 1fr 2fr; that the third column should be double the space of the first two.
Another option would be to span 1
.div-3 {
grid-column: 3 / span 1;
}
You can see this clearly by using the inspection tools.
.factory {
display: grid;
grid-template-columns: 1fr 1fr 2fr;
height: 600px;
gap: 10px;
margin-top: 100px;
padding: 10px;
}
.factory>div {
background-color: gray;
border: 1px green solid;
}
.image-1 {
width: 100%;
height: auto;
}
/*.div-3 {
grid-column: 3 / span 5;
}*/
.div-5 {
grid-column: 1 / span 2;
}
<div class="factory">
<div class="div-1">box1</div>
<div class="div-2">box2</div>
<div class="div-3">box3</div>
<div class="div-5">box5</div>
<div class="div-6">box6</div>
</div>
I'm trying to create a simple layout, where I have a grid made up of three rows. I want my first element to take up 2 rows, and the second element to take up the remaining row. That works, but when I introduce a grid-row-gap: 30px;, it seems to add an additional 30px to the height of my first element.
<div id="grid">
<div id="one">1 - height is actually 332px</div>
<div id="two">2 - height is 150px, which I'd expect</div>
</div>
<style>
body {
background: #000;
color: #fff;
}
#grid {
display: grid;
grid-template-columns: 1;
grid-template-rows: repeat(3, 150px);
grid-row-gap: 30px; // the problem with this is that it takes space away from the lower rows, but not the top ones. seeming to add height to the top section
height: calc(450px + 30px);
width: 600px;
}
#grid div {
margin: 0;
padding: 0.75rem;
border: 3px solid #FFF;
border-radius: 12px;
overflow: hidden;
background: #3A3A3A;
}
#one {
grid-row: span 2;
max-height: 300px;
}
#two {
grid-row: span 1;
}
</style>
I made an example codepen at https://codepen.io/grayayer/pen/xxzQWex
Seems like this should be simpler than it is.
I was expecting the first element to be 300px high, but it's 330px high. The second element is 150px as expected.
I've added box-sizing: border-box; — perhaps this reduces the confusion? Remember that with the default box-sizing method, the size of your boxes does not include any padding.
https://css-tricks.com/box-sizing/
But the basic equation is pretty simple: you have two rows which are each 150px high, plus you have a 30px gap between them, so the height of an element which spans both rows will be 150px + 30px + 150px = 330px.
body {
background: #000;
color: #fff;
margin: 30px;
}
#sponsors_grid {
display: grid;
grid-template-columns: 2;
grid-template-rows: repeat(3, 150px);
gap: 30px;
}
#sponsors_grid div {
margin: 0;
padding: 0.75rem;
border: 3px solid #FFF;
border-radius: 12px;
overflow: hidden;
background: #3A3A3A;
box-sizing: border-box;
}
#one {
grid-column: 1;
grid-row: 1 / span 2;
}
#two {
grid-column: 1;
grid-row: 3;
}
#three {
grid-column: 2;
grid-row: 1;
}
#four {
grid-column: 2;
grid-row: 2;
}
#five {
grid-column: 2;
grid-row: 3;
}
<div id="sponsors_grid">
<div id="one">1 - 330px</div>
<div id="two">2 - 150px</div>
<div id="three">3 - 150px</div>
<div id="four">4 - 150px</div>
<div id="five">5 - 150px</div>
</div>
I have a comments box that displays a lit of existing comments. This box should overlap an image and be fixed to the bottom of the image. I have overlapped the box but the 'existing-comments-container' keeps stretching to the end of the page. The expected behavior is that it stretches across the width of the image container.
Here is an image which will hopefully make it clearer:
Here is the relevant HTML:
<div class="overlay">
<div class="full-view-container">
<div class="overlay-inner-portrait">
<img [src]="image.imagePath" alt="photo" (click)="closeImage()">
</div>
<div class="existing-comments-container">
<div class="existing-comments" *ngFor="let comment of comments">
<p class="commentor-name">{{comment.name}}</p>
<p class="comment">{{comment.usersComment}}</p>
</div>
</div>
</div>
And the relevant CSS:
.overlay {
position: fixed;
background: rgba(0, 0, 0, 0.7);
top: 0;
right: 0;
bottom: 0;
left: 0;
display: none;
z-index: 4;
display: grid;
align-items: center;
justify-items: center;
grid-template-columns: 1;
grid-template-rows: 1;
}
.full-view-container {
display: grid;
grid-column: 1 / -1;
grid-row: 1 / -1;
display: grid;
grid-template: 1fr / 1fr;
}
.overlay-inner-portrait {
background: white;
width: 450px;
height: 580px;
padding: 20px;
grid-column: 1 / -1;
grid-row: 1 / -1;
display: grid;
grid-template: 1fr / 1fr;
align-items: end;
}
.overlay img {
width: 100%;
height: 100%;
}
.existing-comments-container {
display: grid;
grid-template-columns: 1fr;
grid-column: 1 / -1;
grid-row: 1 / -1;
align-self: end;
justify-items: center;
max-height: 100px;
background: white;
}
i found out the cause of this issue was that the text in one of the users comments box was very long and causing the boxes to stretch. I resolved this by setting a max-width on the p tag which has the class .comment
Both divs display correctly alone, but if both img-1 and img-2 divs are both in the container, the second div disappears.
HTML:
<div class="body-background">
<div class="background-img-1"></div>
<div class="background-img-2"></div>
</div>
CSS
.body-background {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: 1fr;
width: 100%;
height: 100%;
}
.background-img-1 {
background: red;
grid-column: 1 / 3;
}
.background-img-2 {
background: blue;
grid-column: 2 / 4;
}
Shouldn't the boxes overlap normally?
Give both background divs a grid-row: 1 property (which becomes grid-row: 1 / 2). I don't think the browser likes having to give it implicitly to two overlapping cells.
.body-background {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: 1fr;
width: 100vw;
height: 100vh;
}
.background-img-1 {
background-color: red;
grid-column: 1 / 3;
grid-row: 1;
}
.background-img-2 {
background-color: blue;
grid-column: 2 / 4;
grid-row: 1;
}
<div class="body-background">
<div class="background-img-1"></div>
<div class="background-img-2"></div>
</div>
I have a basic 2-column layout: One for an image, one for text. Since the text column can potentially become quite long I'd like the image to scroll along. I can achieve that easily enough with position: sticky;, but at the end there is a third container spanning both columns. Since all three elements are in the same grid, the image with position: sticky; overlaps the third container.
Is there way to confine the image to the first grid row, without using JS or adding additional containers?
Example: https://jsfiddle.net/y27unz9L/
.element-1 is the one I want to confine to the first grid row.
<div class="grid-container">
<div class="element-1"></div>
<div class="element-2"></div>
<div class="element-3"></div>
</div>
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 2em;
align-items: start;
}
.element-1 {
min-height: 10vh;
grid-row: 1;
grid-column: 1 / 2;
position: sticky;
top: 1em;
background: red;
}
.element-2 {
min-height: 100vh;
grid-row: 1;
grid-column: 2 / 3;
background: blue;
}
.element-3 {
min-height: 100vh;
grid-row: 2;
grid-column: 1 / 3;
background: yellow;
}
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 2em;
align-items: start;
}
.element-1 {
min-height: 10vh;
grid-row: 1;
grid-column: 1 / 2;
position: sticky;
top: 1em;
background: red;
}
.element-2 {
min-height: 100vh;
grid-row: 1;
grid-column: 2 / 3;
background: blue;
}
.element-3 {
min-height: 100vh;
grid-row: 2;
grid-column: 1 / 3;
background: yellow;
position: sticky;
}
<div class="grid-container">
<div class="element-1"></div>
<div class="element-2"></div>
<div class="element-3"></div>
</div>
Hmmm I would have element-1 to be the cell and stick something inside it. Like this https://jsfiddle.net/7pcr8fvz/.
<div class="element-1">
<div class='sticky'>
</div>
</div>
.element-1 {
grid-row: 1;
grid-column: 1 / 2;
align-self: stretch; //so it's 100% of the available height
}
.element-1 .sticky {
position: sticky; //make this element sticky
top: 1em;
background: red;
height: 10vh;
}
The problem with making .element-1 sticky is that it's relative to the grid, if you make a child sticky the child is positioned relative to .element-1.