Filling large gaps between rows - html

In the code box-2 and box-3 row height auto stretches to box-1 height which is tallest item in the row. There is a extra gap in box-2 and box-3 columns. I want that gap to be filled up by the box-5 which is in the second row. Fiddle
.container {
display: grid;
grid-template-columns: 20% 40% 40%;
grid-gap: 20px;
}
.container > div {
border: 1px solid red;
}
.box-1 {
background-color: lightgreen;
height: 300px;
}
.box-2 {
background-color: lightsalmon;
height: 150px;
}
.box-3 {
background-color: lightsalmon;
height: 150px;
}
.box-4 {
background-color: lightskyblue;
height: 500px;
}
.box-5 {
background-color: lightseagreen;
grid-column: 2/-1;
}
<div class="container">
<div class="box-1"></div>
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-4"></div>
<div class="box-5"></div>
</div>
This is the output I am looking for

You're setting the height of the grid items directly, and not defining any rows on the grid container. Therefore, the grid algorithm has to create rows to accommodate the grid areas. It only needs to create two rows to complete the layout. That's why there's a large gap beneath boxes 2 and 3. Box 1, being the tallest, sets the height of top row.
The layout you want requires at least three rows.
Try this approach: Set the rows (and heights) at the container level, then set the grid areas.
.container {
display: grid;
grid-template-columns: 1fr 2fr 2fr;
grid-template-rows: repeat(3, 150px);
grid-gap: 10px;
}
.box-1 {
grid-column: 1;
grid-row: 1 / span 2;
background-color: lightgreen;
}
.box-2 {
grid-column: 2;
grid-row: 1;
background-color: lightsalmon;
}
.box-3 {
grid-column: 3;
grid-row: 1;
background-color: lightsalmon;
}
.box-4 {
grid-column: 2 / -1;
grid-row: 2 / 4;
background-color: lightskyblue;
}
.box-5 {
grid-column: 1;
grid-row: 3;
background-color: lightseagreen;
}
<div class="container">
<div class="box-1">1</div>
<div class="box-2">2</div>
<div class="box-3">3</div>
<div class="box-4">4</div>
<div class="box-5">5</div>
</div>
If you want more options for sizing grid areas, then increase the number of rows / columns.
For example, instead of this:
grid-template-rows: repeat(3, 150px)
...you can do this:
grid-template-rows: repeat(9, 50px)
... then span grid areas across rows as needed.

Keep box 1 and box 3 in one div align it vertically and keep all other 3 boxes in one container in 1 container then u can do this easily

Related

grid-column-end: -1; weird behavior

What I intend to achieve is something that looks as follows:
Where the header spans the full width of the container, where there can be 3 or 4 columns having the same width in the second row, and where the footer has the same width as the first column.
I thought I could achieve this with the following HTML and CSS code, but no. grid-column-end is giving me headaches. If I set it to 5, it looks as I want in the case that there are four items in the second row, but not if there are only 3, in which case grid-column-end should be 4. Hence, the solution of using -1, which refers to the last grid-line, but then a grid containing something like 40 columns is created.
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(10px, 1fr));
grid-template-rows: auto minmax(0, 1fr) auto;
grid-gap: 10px;
width: 100%;
}
.header {
grid-column-start: 1;
grid-column-end: -1;
grid-row: 1;
background-color: #bbb;
padding: 20px;
}
.item {
background-color: #ddd;
border: 1px solid #aaa;
padding: 20px;
grid-row: 2;
}
.footer {
grid-column: 1 / 2;
grid-row: 3;
background-color: #bbb;
padding: 20px;
}
<div class="container">
<div class="header">Header</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="footer">Footer</div>
</div>

How can I insert new items into a grid in the top row?

I am inserting items from list to grid.
When I am inserting 2 items with same grid-column it's inserted one after another (which is good). But if next item is Could fit at top of rows I would like to place it there.
.container {
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(7, 1fr);
}
.item1 {
grid-column: 3 / 4;
background-color: coral;
}
.item2 {
grid-column: 5 / 5;
background-color: red;
}
<div class="container">
<div class='item1'>1</div>
<div class='item1'>2</div>
<div class='item2'>3</div>
</div>
https://jsfiddle.net/epr5atvw/
How can i move item 3 so it will be next to item 1? My list is sorted and i cannot change it.
Use grid-auto-flow:column;
.container {
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(7, 1fr);
grid-auto-flow: column;
}
.item1 {
grid-column: 3 / 4;
background-color: coral;
}
.item2 {
grid-column: 5 / 5;
background-color: red;
}
<div class="container">
<div class='item1'>1</div>
<div class='item1'>2</div>
<div class='item2'>3</div>
</div>

HTML grid layout disrupted by SVG child element

I'm trying to make a page with a simple 3x3 grid layout: header top, footer bottom, two sidebars, and the main display. Everything works fine until I add the SVG element that should fill the main-display div:
<div class="main">
<svg viewBox="0 0 500 500"></svg>
</div>
The whole grid layout gets confused at this point, with the browser eliminating the header, extending the page below the height: 100% that I have declared, etc.
I can easily "fix" this by setting my SVG max-height and max-width arbitrarily small (below ~60% in Firefox 62.0.3; in Safari 12.0, <90%). But that isn't really a fix since it leaves a conspicuous gap (a huge one in Firefox). I much prefer to size my SVG 100% to fill its space in the grid. I must be missing something. What am I doing wrong?
Edit: Adding a screenshot of what I want and (one version of) what I have.
Here is what I have. Here is what I want.
The stylesheet for what you see is below. The only difference between the two images is the change in max-width and max-height from 10% to 100%.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
display: grid;
border-style: solid; // to show that body renders improperly
border-color: red;
grid-template-columns: 3fr 9fr 2fr;
grid-template-rows: 1fr 10fr 1fr;
width: 100vw;
height: 100vh;
}
div {
border: solid black 1px; // to show div positions
}
.header {
grid-column: 1 / 4;
grid-row: 1;
}
.main {
grid-column: 2;
grid-row: 2;
}
.side1 {
grid-column: 1;
grid-row: 2;
}
.side2 {
grid-column: 3;
grid-row: 2;
}
.footer {
grid-column: 1 / 4;
grid-row: 3;
}
svg {
max-height: 100%;
max-width: 100%;
}
<body>
<div class="header">Header</div>
<div class="side1">Site 1</div>
<div class="main">
<svg viewBox="0 0 500 500"></svg>
</div>
<div class="side2">Site 2</div>
<div class="footer">Footer</div>
</body>
It turns out that the problem is not with the svg element at all, but with its containing div (.main in the question's code snippet). Like flex items, grid items have a default min-width: auto and min-height: auto. By setting them to 0, the svg is able to size automatically, as it should.
I still don't quite understand why the svg disrupted the layout, especially when it was set to 80% in Firefox, leaving conspicuous space around it, but the problem with the grid layout itself is clear enough.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
display: grid;
grid-template-columns: 3fr 9fr 2fr;
grid-template-rows: 1fr 10fr 1fr;
width: 100vw;
height: 100vh;
}
div {
border: solid black 1px; // to show div positions
}
.header {
grid-column: 1 / 4;
grid-row: 1;
}
.main {
grid-column: 2;
grid-row: 2;
min-width: 0;
min-height: 0;
}
.side1 {
grid-column: 1;
grid-row: 2;
}
.side2 {
grid-column: 3;
grid-row: 2;
}
.footer {
grid-column: 1 / 4;
grid-row: 3;
}
svg {
max-height: 100%;
max-width: 100%;
}
<body>
<div class="header">Header</div>
<div class="side1">Site 1</div>
<div class="main">
<svg viewBox="0 0 500 500"></svg>
</div>
<div class="side2">Site 2</div>
<div class="footer">Footer</div>
</body>
Please see below. No issues encountered.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.wrapper {
display: grid;
grid-template-columns: 3fr 9fr 2fr;
grid-template-areas: "header header header" "side1 main side2" "footer footer footer";
}
.wrapper>div {
border: thin solid black;
/* For visibility only */
}
.header {
grid-area: header;
}
.side1 {
grid-area: side1;
}
.main {
grid-area: main;
}
.side2 {
grid-area: side2;
}
.footer {
grid-area: footer;
}
<div class="wrapper">
<div class="header">Header</div>
<div class="side1">Site 1</div>
<div class="main"><svg viewBox="0 0 500 500"></svg></div>
<div class="side2">Site 2</div>
<div class="footer">Footer</div>
</div>

CSS Grid - auto column height

The cart form is stretching vertically and the thumbs are positioning in the bottom left corner, when I'd like them to sit directly under the cart form like so:
.product-page--main-content {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto 1fr auto;
}
.product-page--main-content>* {
padding: 50px 100px;
border: 1px solid #ccc;
}
.product-page--cart-form-block {
grid-row: 2;
}
.product-page--thumbs {
grid-row: 3;
}
.product-page--images {
grid-column: span 2;
grid-row: span 3;
height: 400px;
}
.product-page--description {
grid-row: span 3;
}
<div class="product-page--main-content">
<div class="product-page--title-n-vendor">Title</div>
<div class="product-page--cart-form-block">Cart form</div>
<div class="product-page--thumbs">Thumbs</div>
<div class="product-page--images">Images</div>
<div class="product-page--description">Description</div>
</div>
Codepen: https://codepen.io/paulmason/pen/rYXyYW
The code you have is working perfectly, as written.
Your image grid item is set to height: 400px.
.product-page--images {
grid-column: span 2;
grid-row: span 3;
height: 400px;
}
Then you have 50px in top and bottom padding.
.product-page--main-content > * {
padding: 50px 100px;
border: 1px solid #ccc;
}
So the image grid item is 500px tall, in a row set to 1fr, in a grid with three rows. It all works perfectly, as specified.
Maybe what you want is four rows:
.product-page--main-content {
display: grid;
grid-template-columns: repeat(4, 1fr);
/* grid-template-rows: auto 1fr auto; */ /* now defaults to grid-auto-rows: auto */
}
.product-page--main-content > * {
padding: 50px 100px;
border: 1px solid #ccc;
}
.product-page--cart-form-block {
grid-row: 2;
}
.product-page--thumbs {
grid-row: 3;
}
.product-page--images {
grid-column: span 2;
grid-row: span 4; /* changed from 3 */
height: 400px;
}
.product-page--description {
grid-row: span 4; /* changed from 3 */
}
<div class="product-page--main-content">
<div class="product-page--title-n-vendor">Title</div>
<div class="product-page--cart-form-block">Cart form</div>
<div class="product-page--thumbs">Thumbs</div>
<div class="product-page--images">Images</div>
<div class="product-page--description">Description</div>
</div>
I'm not sure this is what you're asking but this seems to fit: change
grid-template-rows: auto 1fr auto;
to
grid-template-rows: 3;

Flexbox/Float anchor items to top [duplicate]

This question already has answers here:
Create a Masonry grid with flexbox (or other CSS)
(3 answers)
Closed 5 years ago.
Consider this example:
Notice that that 4th item is pushed to top instead of aligning with the 3rd item. I can't achieve this using flexbox's align-items: flex-end, neither with floats.
I am aware of achieving this by using masonry/isotope, but I would like to avoid using javascript just for this layout.
Is it possible to achieve using only CSS?
Yes, it's possible via CSS Grid Layout:
.grid {
display: grid;
grid-gap: 10px 30px;
grid-template-rows: auto 1fr auto;
}
/* styles just for demo */
.grid__item {
background-color: #e0e0e0;
font-size: 30px;
padding: 10px;
}
.b, .d {
align-self: flex-start;
}
.a {
grid-row: 1 / span 2;
/* setting height just for demo */
height: 200px;
}
.b {
grid-column: 2;
}
.c {
grid-row: 3;
}
.d {
grid-column: 2;
}
<div class="grid">
<div class="grid__item a">1</div>
<div class="grid__item b">2</div>
<div class="grid__item c">3</div>
<div class="grid__item d">4</div>
</div>
If you need IE\Edge support you should use old grid syntax. You can fake grid-gap using additional grid columns and rows. Demo:
.grid {
display: -ms-grid;
display: grid;
-ms-grid-columns: 1fr 30px 1fr;
grid-template-columns: 1fr 30px 1fr;
-ms-grid-rows: auto 10px 1fr 10px auto;
grid-template-rows: auto 10px 1fr 10px auto;
}
/* styles just for demo */
.grid__item {
background-color: #e0e0e0;
font-size: 30px;
padding: 10px;
}
.b, .d {
-ms-grid-row-align: start;
align-self: flex-start;
}
.a {
-ms-grid-row-span: 3;
grid-row: 1 / span 3;
/* setting height just for demo */
height: 200px;
}
.b {
-ms-grid-column: 3;
grid-column: 3;
}
.c {
-ms-grid-row: 5;
grid-row: 5;
}
.d {
-ms-grid-column: 3;
grid-column: 3;
-ms-grid-row: 3;
grid-row: 3;
}
<div class="grid">
<div class="grid__item a">1</div>
<div class="grid__item b">2</div>
<div class="grid__item c">3</div>
<div class="grid__item d">4</div>
</div>