This question already has answers here:
CSS-only masonry layout
(4 answers)
Closed 1 year ago.
Hey,
i am trying to achieve this kind of layout with css grid.
I have set the container div of these items to
display: gridand grid-template-columns: repeat(3, 1fr). Then i layed out the items with grid-column and grid row.
This gives me an 3x3 grid. But i need a grid with 2 rows in the first column, 3 rows in the middle column and two rows in the third column. Based on the size of the item. Is there any way of doing this with css grid, i am stuck at the moment. Thanks in advance
You can take up to 2 spaces with grid-row: span 2;
.grid {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 50px;
}
.gr2 {
grid-row: span 2;
}
.box {
background-color: red;
}
<div class="grid">
<div class="box gr2">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box gr2">5</div>
<div class="box">6</div>
<div class="box">7</div>
</div>
Related
I need to place 4 div containers in a 2 by 2 matrix. The width of the columns must be equal (and is therefore fixed), while the height of the rows must adapt itself to the content of the cells (and is therefore variable).
This is simple to do as long as the markup structure looks something like this:
<div class="wrapper">
<div class="cell a1">...</div>
<div class="cell a2">...</div>
<div class="cell b1">...</div>
<div class="cell b2">...</div>
</div>
The corresponding CSS would look like this:
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
}
Unfortunately, my markup (which I cannot change easily) contains the cells in a nested markup structure:
<div class="wrapper">
<div class="container">
<div class="cell a1">...</div>
<div class="cell a2">...</div>
</div>
<div class="container">
<div class="cell b1">...</div>
<div class="cell b2">...</div>
</div>
</div>
As long as the height of the two rows can be equal, declaring .container as secondary grid solves the issue. But since the row height must be adjusted according to the cell content, this doesn't work.
Is there a way to place all four div.cell in the same grid defined by div.wrapper, although they are not direct child elements?
What you are looking for is Subgrid, feature currently (December 2021) only tested on Firefox Nightly.
Info about this CSS attribute (from the Mozilla Web Docs page) :
When you add display: grid to a grid container, only the direct children become grid items and can then be placed on the grid that you have created.
You can "nest" grids by making a grid item a grid container. These grids however are independent of the parent grid and of each other, meaning that they do not take their track sizing from the parent grid. This makes it difficult to line nested grid items up with the main grid.
For example, if you use grid-template-columns: subgrid and the nested grid spans three column tracks of the parent, the nested grid will have three column tracks of the same size as the parent grid.
When the feature will be available and supported by multiple browsers this example below will work (I guess):
html, body {
width: 100%;
height: 100%;
margin: 0;
}
.wrapper {
display: grid;
height: 100vh;
width: 100vw;
background: grey;
grid-auto-flow: rows;
grid-template-columns: auto auto;
grid-template-rows: auto auto;
}
.container {
display: grid;
grid-column: 1 / 3;
grid-row: 1 / 3;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
}
.a1{
background-color: blue;
grid-row: 1;
grid-column: 1;
}
.a2{
background-color: yellow;
grid-row: 1;
grid-column: 2;
}
.b1 {
background-color: red;
grid-row: 2;
grid-column: 1;
}
.b2 {
background-color: green;
grid-row: 2;
grid-column: 2;
}
<div class="wrapper">
<div class="container a">
<div class="cell a1">A1</div>
<div class="cell a2">A2</div>
</div>
<div class="container a">
<div class="cell b1">B1</div>
<div class="cell b2">B2</div>
</div>
</div>
And will render something like this :
This question already has answers here:
Why doesn't min-content work with auto-fill or auto-fit?
(2 answers)
Closed 2 years ago.
I am trying to do a layout using CSS where I have a grid of 2 columns and 2 rows.
The first column should have a width of 1fr and the second column 4fr.
I tried using auto-fit:
HTML
<body>
<header>
<div class="item1">GRID ITEM 1</div>
<div class="item2">GRID ITEM 2</div>
<div class="item1">GRID ITEM 3</div>
<div class="item2">GRID ITEM 4</div>
</header>
</body>
CSS
header {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}
div {
border: 1px solid;
}
I am having trouble setting 2 different column widths (1fr, 3fr) only using auto-fit and auto-fill when in desktop screen mode. Is there any way to achieve this without using media queries? Or auto-fit and auto-fill are only used when columns are of the same width?
So if I understood right. Your layout should have 5 columns (1 x 1fr , 1 x 4fr) and 2 rows. Here is something that MIGHT answer your question.
.parent {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(2, 1fr);
height: 300px;
}
.item1 { grid-area: 1 / 1 / 2 / 2; background: red;}
.item2 { grid-area: 1 / 2 / 2 / 6; background: green; }
.item3 { grid-area: 2 / 1 / 3 / 2; background: yellow; }
.item4 { grid-area: 2 / 2 / 3 / 6; background: blue; }
<div class="parent">
<div class="item1"> </div>
<div class="item2"> </div>
<div class="item3"> </div>
<div class="item4"> </div>
</div>
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
With
grid-template-columns:1fr 1fr;
the 2 columns have different width in small(narrow) screen. I can not understand.
Thank you for any help.
In the ideal case, the two cells will have the same size.
But every cell has a minimum size! It is defined as the minimum content width. For example: the larger word, the larger button, or the larget image that it contains.
To avoid this, you should use minmax(0, 1fr) for each column definition. It allows you to say that 1fr, one fraction, is the maximum width of the column.
To sum up, use this code:
.grid {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
Here is a live demo of the problem and solution.
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
}
.grid--fix {
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
/* Demo styles */
.grid {
grid-gap: 20px;
max-width: 400px;
}
.cell {
background: hotpink;
text-align: center;
padding: 1em;
}
<p>Exact same cells</p>
<div class="grid">
<div class="cell">Cell 1</div>
<div class="cell">Cell 2</div>
</div>
<p>The cells adapt their size to contain their content</p>
<div class="grid">
<div class="cell">Cell 1</div>
<div class="cell">Cell 2 is biiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiig</div>
</div>
<p>This behaviour could be disabled with <code>minmax(0, 1fr)</code></p>
<div class="grid grid--fix">
<div class="cell">Cell 1</div>
<div class="cell">Cell 2 is biiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiig</div>
</div>
This question already has answers here:
Make a grid item span to the last row / column in implicit grid
(5 answers)
Closed 4 years ago.
I have a CSS grid with automatic columns and 2 rows, where all but a specific element go into the first row. The special element is placed on the second row, and should fill the whole space used by all columns.
The current implementation is like this:
.TabArea {
display: grid;
grid-auto-columns: auto;
grid-template-rows: auto 1fr;
grid-auto-flow: column;
/* for visualization purposes */
background: gainsboro;
}
.Tab-title {
grid-row: 1;
}
.Tab-body {
grid-row: 2;
grid-column: 1 / -1;
/* for visualization purposes */
background: beige;
}
<div class="TabArea">
<div class="Tab-title">Title A</div>
<div class="Tab-title">Title B</div>
<div class="Tab-title">Title B</div>
<div class="Tab-body">content</div>
</div>
But as you can see, the Tab-body is only placed on the first column, despite the fact there are additional columns. How can I make it span all columns?
The solution in https://stackoverflow.com/a/44052563/1045510 does not work here because the number of columns is variable, and columns would take up space on the end, pushing the Tab-titles to the left.
I think you need to use span in order to make it span across columns as you can only use negative integers in an explicit grid:
.TabArea {
display: grid;
grid-auto-columns: auto;
grid-template-rows: auto 1fr;
grid-auto-flow: column;
/* for visualization purposes */
background: gainsboro;
}
.Tab-title {
grid-row: 1;
}
.Tab-body {
grid-row: 2;
grid-column-start: 1;
grid-column-end: span 3;
/* for visualization purposes */
background: beige;
}
<div class="TabArea">
<div class="Tab-title">Title A</div>
<div class="Tab-title">Title B</div>
<div class="Tab-title">Title B</div>
<div class="Tab-body">content</div>
</div>
Consider the following snippet:
#container{
border: solid 1px black;
display: inline-grid;
grid-template-columns: repeat(3, auto);
}
<div id="container">
<div class="row">
<div class="item">A1111</div>
<div class="item">B1</div>
<div class="item">C1</div>
</div>
<div class="row">
<div class="item">A2</div>
<div class="item">B2222</div>
<div class="item">C2</div>
</div>
<div class="row">
<div class="item">A3</div>
<div class="item">B3</div>
<div class="item">C3333</div>
</div>
</div>
The end result is a table-like display where each item of every row is the width of the widest item in that column.
A1111 A2 A3
B1 B2222 B3
C1 C2 C3333
Which is great - but I need the table laid out as rows...
A1111 B1 C1
A2 B2222 C2
A3 B3 C3333
display: table solves this - but table has some drawbacks around spacing, alignments and so-on. Therefore, grid and flex looks attractive.
Alas I cannot figure out how to get the information laid out as desired.
Adding display: grid to .row helps the order of information, but doesn't retain the equal column widths.
The item content will vary, and so cannot use fixed widths and it is not desired that the grid/flex spans the entire page/containing width.
You can define which column the grid item should be using grid-column. This means the row doesn't require a containing row div.
Working example...
#container{
border: solid 1px black;
display: inline-grid;
grid-auto-flow: row;
grid-gap: 10px;
padding: 10px;
}
.col1{
grid-column: 1;
}
.col2{
grid-column: 2;
}
.col3{
grid-column: 3;
}
<div id="container">
<div class="col1">A11111</div>
<div class="col2">B1</div>
<div class="col3">C1</div>
<div class="col1">A2</div>
<div class="col2">B2222222</div>
<div class="col3">C2</div>
<div class="col1">A3</div>
<div class="col2">B3</div>
<div class="col3">C33333333</div>
</div>
</div>
Your main problem is your markup is too deep. You have table-like markup, three levels deep: table, rows, and cells. For grid layout, you don’t need the “row” elements at all.
When you use display: grid or display: inline-grid on an element, it makes that element a grid container. Each of its child elements then become grid items. Grid items will be laid out in the grid defined by their container.
You also said you want columns of equal width. For this, you should use the fr unit rather than auto for your column sizes:
grid-template-columns: repeat(3, 1fr);
…this will make each column one “fraction” unit wide.
#container{
border: solid 1px black;
display: inline-grid;
grid-template-columns: repeat(3, 1fr);
}
<div id="container">
<div class="item">A1111</div>
<div class="item">B1</div>
<div class="item">C1</div>
<div class="item">A2</div>
<div class="item">B2222</div>
<div class="item">C2</div>
<div class="item">A3</div>
<div class="item">B3</div>
<div class="item">C3333</div>
</div>
There's way which I would make it.
Attached JSFiddle(click)
.row {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
}
.row > .item {
display:block;
flex: 1 1;
border: 1px solid #000;
}
There's such great guide about flex; Click here.