I want to use a CSS-Grid-Layout (ideally with an explicit column-grid).
And I would like to have a flexible item that absorbs any extra space along the x axis / spans as many columns as are not used by other items.
The perfect solution would be a property that makes an item span across all unoccupied columns (similar to the flex-property) - but I guess that's not possible in a CSS-Grid.
I'll try to make an example:
The following Layout uses several elements that are positioned on a grid.
I would like to have a flexible header, that absorbs any extra space on the right if the item in the area "aside1" is cut.
.grid{
display: grid;
grid-template-columns: none 1fr 1fr none;
grid-template-areas: "header header header aside1"
"nav main main aside2"
"nav main main aside3"
;
}
header {
grid-area: header;
}
main {
grid-area: main;
}
nav {
grid-area: nav;
}
.aside1 {
grid-area: aside1;
}
.aside2 {
grid-area: aside2;
}
.aside3 {
grid-area: aside3;
}
But, of course, as long as there are any items on the right side, the header will stay in it's column an the Layout will look like this:
In a Flexbox-Layout I could use the flex: 1 property to accomplish this.
In Grid... I guess I would need a way to have a box Item to absorb all unused columns. Maybe that is not possible to do.
.grid{
display: grid;
grid-template-columns: none 1fr none;
}
header {
grid-column: 1 / ????;
grid-row: 1 / 2;
}
main {
grid-column: 2 / 3;
grid-row: 1 / 2;
}
nav {
grid-column: 2 / 3;
grid-row: 1 / 2;
}
.aside1 {
grid-column: 2 / 3;
grid-row: 1 / 2;
}
.aside2 {
grid-column: 2 / 3;
grid-row: 2 / 3;
}
.aside3 {
grid-column: 2 / 3;
grid-row: 3 / 4;
}
What I am trying to do ist to build a small "framwork" with a flexible xy-Grid, similar to foundation, but um.. not that cool (it's a school project).
And I was wondering if it's possible to build a grid system with both:
Grid Items, that absorb any free space/columns along the x-axis - possible with flex-Grid and in foundation.
Grid items, that span several rows - not possible with flex-Grid, see: Is it possible for flex items to align tightly to the items above them? (the first answer explains it pretty well)
I hope I made myself a little bit more clear.
One possible solution would be to use grid-template-columns for your explicitly sized columns and grid-auto-columns for any additional flexible columns.
While grid-template-columns sizes columns in the explicit grid, grid-auto-columns sizes columns in the implicit grid.
So try sizing your columns like this:
grid-template-columns: 100px 100px /* sizes the first two columns */
grid-auto-columns: 1fr /* distributes free space among additional columns; if
there is only one column, it consumes all space; */
This post may also be useful:
CSS Grid: How to make a column span full width when a second column is not there?
Related
This question already has answers here:
How to center elements on the last row in CSS Grid?
(8 answers)
Closed 10 months ago.
I have container like this :
At the moment there is an empty case after element 5. So I would like to center the elements of the second line :
For the code i've already done :
.country-grid
display: grid
grid-template-columns: repeat(auto-fill,minmax(320px, 1fr))
This depends on the exact use case and how many grid items you are expecting. If you know you are always going to have 5 items, you could just set a specific number of columns and offset the 4th item like so:
.grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
}
.grid-item {
grid-column: span 2;
}
.grid-item:nth-child(4) {
grid-column: 2 / span 2;
}
If the layout could have any number of items and you are looking at a more fluid approach when it comes to wrapping, then I'd suggest using flex for this as it's a lot simpler for setting up alignment like this:
.flex {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.flex-item {
width: calc(100% / 3);
min-width: 320px;
}
This question already has answers here:
CSS-only masonry layout
(4 answers)
Closed 10 months ago.
I have been trying to recreate the below picture in css but have been having trouble implementing it with both grids and flexboxes.
I want each of the boxes to simpy fit its content, and the remaining empty boxes to fill the space of the column.
When I try with grids I can easily create three columns with a fixed even gap inbetween columns and rows however I get stuck on how to make the individual boxes dynamic in size depending on its content.
When I try with flex boxes, I can create teh individual boxes of flexible size but it is very hard to limit the boxes to three columns of even size, but let the columns each have multiple elements.
I have thought about simply creating three different flex boxes but wanted to avoid a hardcoded solution, but maybe for this case this is the best solution?
Would I use grids or flexboxes for this kind of design?
Any insight on how to approach such a design would be very helpful thanks.
What you could do is to create 3 different classes for each column in the grid:
Each class should have align-self: flex-start as well as display: grid; in order to create space between different rows in the column. Here's the full code:
.base-layout {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-column-gap: 2rem;
}
.col-1 {
display: grid;
grid-gap: 2rem;
grid-column: 1 / span 1;
}
.col-2 {
display: grid;
grid-gap: 2rem;
grid-column: 2 / span 1;
align-self: flex-start;
}
.col-3 {
display: grid;
grid-gap: 2rem;
grid-column: 3 / span 1;
align-self: flex-start;
}
.single-content {
background-color: pink;
padding: 2rem;
}
here's an Imagesample Image
display: grid;
grid-template-columns:var(--side-bar-width) 1fr;
grid-template-rows: 60px 1fr 90px;
gap: 0px 0px;
grid-template-areas:
"Sidebar Header"
"Sidebar Body"
"Player Player";
I have three components, each render a div with a classname of
.Body { ... grid-area: Body; },
.Sidebar { ... grid-area: Sidebar; },
.Player{ ... grid-area: Player; }
respectively
The Player component is a conditional render of height 90px, it is not visible initially so sometimes it looks like the viewport has 90px of empty space at the bottom of the screen at page load
The Player component/content belongs to the Player grid-area. How do you hide the grid-area with empty content dynamically in the grid template? Hiding could mean min-height 0 or display none
In other words, i want to show/hide the last grid-template-row if Player component was rendered then adjust the grid to fill screen
I also saw CSS Grid. Hide unused area & Preventing fixed footer from overlapping content
update:
The Player css has these additional attributes
.Player {
...
height: 90px;
display: flex;
width: 100%;
position: fixed;
bottom: 0;
}
Updated Answer (based on changes to the question)
If the Player grid area must be explicitly defined, then change its row in grid-template-rows to auto or min-content. You can then define the height in the component itself (i.e., height: 90px).
Original Answer
Consider leaving the Player component out of the explicit grid. In other words, don't define it in grid-template-areas or grid-template-rows.
Use grid-auto-rows: 90px.
If necessary, apply grid-row: 3 to the component.
Or even grid-area: 3 / 1 / auto / -1, which is equivalent to:
grid-row-start: 3
grid-column-start: 1
grid-row-end: auto
grid-column-end: -1
So I found this layout and I wanted to make it using display: grid
So far I came up with this
.header__grid {
display: grid;
grid-template-columns: 380px 500px 500px;
grid-template-rows: 305px 305px;
grid-template-areas:
"sweets food meat"
"sweets text fruits"
}
.header__grid-sweets {
grid-area: sweets;
}
.header__grid-food {
grid-area: food;
}
.header__grid-meat {
grid-area: meat;
}
.header__grid-text {
grid-area: text
}
.header__grid-fruits {
grid-area: fruits;
}
And it looks like this
The problem is the the last block, with fruits, should take more than one cell in grid and the block to its left should take less. I guess it is because I'm setting with of columns with grid-template-columns
So the question is is there a way to work around this?
All the help will be much appreciated
Instead of this:
grid-template-columns: 380px 500px 500px;
Try something like this:
grid-template-columns: repeat(100, 10px)
Then used line-based placement to created grid areas across those tracks.
Here's an example from another answer.
e.g. with the box that says "Poster Set" on attached image: , I need this box to extend the full width of the container. Can this be done with CSS grid? It is one of three list items, injected by liquid, contained within a div with the following CSS:
.two-columns {
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 1em;
justify-content: center;
}
Since the grid is two columns, make the poster element cover a 2-column grid area.
There are several ways to do this:
poster-set-element {
grid-column: 1 / span 2; /* start at grid column line 1 and span across 2 more lines */
}
OR
poster-set-element {
grid-column: 1 / 3; /* start at grid column line 1; end at grid column line 3 */
}
OR
poster-set-element {
grid-column: 1 / -1; /* start at grid column line 1 starting at the starting edge;
end at grid column line 1 starting at the ending edge;
(note: this method works only with explicit grids) */
}