I am trying to display fields in a row in the following form: Display 3 fields in a row with equal width, and the rest of them, if I have 2 fields to be in a row with equal width, and if there is one field left to be full width
I tried with this CSS:
root: {
width: '100%',
display: 'grid',
gridTemplateColumns: 'repeat(3, 1fr)',
gridColumnGap: theme.spacing(),
overflow: 'hidden',
},
But this is the result I got:
How can I achieve the expected result(first image) with CSS grid?
I can think of two solutions for this. First instead of dividing the grid to 3 columns, divide to 6 columns and span the grid items into multiple columns by targeting them using nth-child selector. Second Don't use grid at-all, instead create a flex-container that will have another 3 flex-container as child nodes. And make use of flex-basis to get the desired result.
Solution 1
Using a 6 column grid,
You have to target specific grid items and make use of span to span them across n number of columns. For example for the first 3 grid item you need to specify grid-column: span 2;. Example,
.grid-container {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(3, 1fr);
}
.grid-item:nth-child(1),
.grid-item:nth-child(2),
.grid-item:nth-child(3) {
grid-column: span 2;
}
.grid-item:nth-child(4),
.grid-item:nth-child(5) {
grid-column: span 3;
}
.grid-item:last-child {
grid-column: span 6;
}
See the demo in codesandbox.
Solution 2
Since you asked for a solution using CSS-grid, I don't think it is a good idea to include the code for the solution that uses flex-box instead. Have a look at the codesandbox, for the solution using flex-box.
Related
I am building a css grid display with fixed number of column 2 and unknown number of rows.
I'd use something like:
.container {
display: grid;
grid-template-column: repeat(2, 1fr);
grid-auto-rows: 12rem;
}
.component {
grid-row: span 2;
}
Inside my container I would display a list C[] of components C whose width is known and the same for all components, let's call it W
However, the height of my components is different for each (it depends on text inside components, length of the data it should display, how it should display it...). We'll call H(C) the height of each component.
I am looking for a way to change for long components the span they should have to display its content: i.e: What is the value of span vSpan so that
vSpan * 12rem >= H(C) > (vSpan -1) * 12rem
I already tried using a display flex, but I could not find a way to stack blocks below each other
css-grid column-gap property makes it easy to create space between elements. However, it's not so easy to overlay elements and target the edge of the gap. With a 12 column Grid with 16px gaps between the columns and 16px columns on the edges my solution is to have 26 columns, like this:
.wrapper {
grid-template-columns: repeat(12, 16px 1fr) 16px ;
}
Then, if you want to target the gap edge (see images), you can use normal grid-column spacing, you only must keep in mind you have now 26 columns.
div {
grid-column: 1/3;
background-color:blue;
}
Of course the grid-gap, gap, or column-gap property should simplify this, only it doesn't. Using column gaps instead of columns you can't target the edge of the gap unless you enlarge the overlaid div beyond 100% of the columns containing it.
Here are three images to explain what I mean:
Image 1:
In the image above is a blue div overlaying column 1 of a 12 column layout with 16px gap.
.wrapper {
grid-template-columns: repeat(12, 1fr);
column-gap:16px;
}
.div-1 {grid-column:1; background-color:pink;}
.div-2 {grid-column:2; background-color:pink;}
etc..
.div-overlay {grid-column: 1/2; background-color:blue;}
Image 2:
In the second image above everything is the same except the blue div overlaying the pink 12 column grid spans to the third column instead of the second (it looks like the end of the second column, because it's before the first gap, but actually the first gap is included in the third column and line number three is the start of the third column).
.div-overlay {grid-column: 1/3; background-color:blue;}
Image three:
In the third image, above, if you want to target the start of the second column and the end of the first gap, you need to change the width of the overlaying blue div, you can't use the grid-column property with spans to get it done.
.div-overlay{
grid-column:1/2;
width:111%;
background-color:blue;
}
One would think with gap, column-gap, and grid-gap properties you would be able to span just the gap using a key word such as in this ficticious example:
.div-overlay{
grid-column: col 1 / span gap 1;
background-color:blue;
}
Am I missing something, or should I stick with 26 column grids to get it done?
.grid-container {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 100px repeat(3, 1fr);
}
i want the first row to be only 2 columns which will be my navbar, logo and nav links but can't seem to find out how maybe cause im searching the wrong thing.
Use grid-column on your child elements
On your grid child elements (your navbar, for example), you can use the grid-column property. You can set start and end values for where you want the child to be positioned.
For example:
.navbar {
grid-column: 1 / 7;
}
Next level: use grid-areas to label your child elements
You might also want to consider looking into grid-areas, which is a nice way of labelling and referencing areas such as your header and navbar.
References:
MDN: grid-column
MDN: grid areas
I love using CSS grid but can’t for the life of me figure this one out – I have a random number of images which will be inserted into a CSS grid container. Rather than left alignment, as below, I would like central alignment of grid items with the 12 columns.
.section-images {
grid-gap: var(--page-margins);
grid-column: span 12;
display: grid;
grid-template-columns: repeat(12, 1fr);
}
.section-image {
grid-column: span 4;
width: 100%;
}
So I would like this below, instead of the above...
Because there may be 5 images, 6 images, 13 etc. it needs to be automatic – I’m sure there’s an easy way to do this?
So if they were multiline, you’d have this:
Many thanks,
Simon
I wrote a layout as depicted above. I implemented this with the simple usage of display: inline-block and article elements that have different widths and heights, like so:
width: 50%; /* this is variable*/
height: 160px; /* this is also variable*/
padding: 10px;
box-sizing: border-box;
display: inline-block;
vertical-align: top;
Now this already works quite okish, but: You see the gap above boxes 4 and 5? Can I write a pure CSS layout that makes these boxes fill up the space directly below 1? I saw some flex-box solutions but they seemed to work with a fixed set of columns, ideally I just want to pass boxes 1-6 in the layout and they adjust properly. Is that possible with modern CSS? I have no browser restrictions and can work with any modern feature!
Unfortunately you can't accomplish that with flexbox and I think grid layout would also not do the thing. Pure CSS masonry layout is highly expected, but not yet available.
I see two solutions:
1.
Use external package. I would suggest react-grid-layout which uses JS to control position: absolute and transform: translate values of children. It supports resizing and many other features. In your situation it should work just fine.
2.
You could also use some tiny JS (pen's not mine):
#staypuftman pointed out in a comment to use CSS grids and I accomplished what I wanted to do. This is my code:
On the container:
display: grid;
grid-template-columns: repeat(8, 1fr);
grid-template-rows: repeat(12, 1fr);
grid-gap: 15px;
height: 100vh;
what I do is I use the grid layout, I create 8 columns by writing 1fr 8 times in grid-template-columns and 12 rows with the 12 frs in the grid-template-rows property. Also I set a grid-gap for spacing between each item and a height of 100vh to make my grid span over the whole visible space.
Now within my items I do this:
grid-column-end: span 2;
grid-row-end: span 2;
Where grid-column-end: span X tells the browser to span the item over 2 of my columns (of which I created 8) and the same in regards to rows with grid-row-end.
This is the result: