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 last month.
Improve this question
I am trying to build a footer like following
I am trying to use CSS Grid to implement this. I can divide the whole thing using grid-template- column and grid grid-template-row and keep empty divs in them except for content part or i can use grid - gap property but the gap is different between different columns. The first method seems hacky and in other method I would need to make columns equidistant. Can anyone guide me on how to best approach this?
There are many ways to achieve that. As you mentioned one of them is using grid-template-* properties. The other option you mentioned is grid-gap/gap.
The third option is to split the row into columns (eg. 12) using grid-template-rows: repeat(12, minmax(auto-fill, 1fr)) and then use grid-area's to define where particular areas start and end. Thanks to that you can have more granular flexible width of columns (if you need even more granular you can use more than 12 columns, eg. 24). You can still use gap to adjust it a bit.
<div class="container">
<div class="Benchmark"></div>
<div class="Navigation"></div>
<div class="Social-links"></div>
</div>
.container {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 1fr;
gap: 0px 5px;
}
.Benchmark { grid-area: 1 / 1 / 2 / 5; }
.Navigation { grid-area: 1 / 6 / 2 / 8; }
.Social-links { grid-area: 1 / 9 / 2 / 13; }
Demo: www.grid.layoutit.com?id=VhvjWF7
According to my understanding your main problem seems to be the left column, which you want to give margin-right: 0; but text won't be left aligned in that case:
So, here is my approach:
<footer class='footer-container'>
<div class='left-column'>
<div class="left-column-inner-div">
<!-- left column content-->
</div>
</div>
<div class='middle-column'>
<!-- middle column content-->
</div>
<div class='right-column'>
<!-- right column content -->
</div>
</footer>
<style>
.footer-container {
display: grid;
grid-template-columns: 2fr 1fr 2fr;
}
.left-column {
display: flex;
justify-content: flex-end;
width: fit-content;
}
.middle-column {
display: flex;
justify-content: center;
}
.right-column {
display: flex;
justify-content: flex-start;
}
</style>
Related
Here is a situation I met and I didn't expect that the grid area will span the whole row track.
As you can see, only col-start defined in the layout. How come the whole row track turned into an implicit grid area named as col?
Here is the code.
HTML:
<div class="wrapper">
<div class="content">content</div>
</div>
CSS:
.wrapper {
display: grid;
grid-template-columns: repeat(12, [col-start] 1fr);
}
.content {
grid-area: col;
}
.content div crosses all 12 column tracks.
From my understanding, you have defined all the grid lines to have the same name col-start but you never defined any grid lines called col-end and the trick is here.
When using grid-area: col we need to either have an area called col or grid lines called col-start and col-end. We don't have any named area and we only have col-start so the browser will implicitly create a grid line called col-end to place your element and this will result in 13 columns in total and not 12
Here is an example where I am reducing the number of column to better see
.wrapper {
display: grid;
grid-template-columns: repeat(5, [col-start] 1fr);
grid-auto-columns: 100px;
gap: 10px;
border: 1px solid;
}
.content {
grid-area: col;
}
<div class="wrapper">
<div class="content">content</div>
</div>
Note how we have 5 explicit columns sized with 1fr and an extra implicit column sized with 100px. This extra column is the result of the implicit grid line called col-end that the browser need to create to place your element.
When you define many grid lines with the same name, only the first one will be considered. I still need to find the explanation of this part in the Spec but the demo we have validate this. The element is placed between the first grid line until the extra implicit one.
Related question with a similar situation: Why does a grid-area name absent in grid-template-areas create additional tracks?
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I'm trying to have a grid as shown below. The problem is that I don't know how to combine the responsiveness and the auto generated columns with items that should have different widths.
I know that I can create a responsive grid with
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr))
or an implicit grid with different sizes like
grid-template-columns: minmax(300px, 1.5fr)) minmax(300px, 1fr)) minmax(300px, 1fr)) minmax(300px, 1.5fr))
But that does not auto wrap on smaller screens.
How can I combine these? Can I use the grid-column attribute on an individual item to achieve this?
or is this a wrong approach and it would be better to use the flex system in this case?
You can't use differently sized cells and also use auto-fit or auto-fill to define their behavior upon resizing.
However, to get precisely what your diagrams show, you can enclose your first two and last two divs in their own div, since taken together they are the same size, and use auto-fill on the outer divs:
.container {
padding: 5px;
border: 3px solid green;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(500px, 1fr));
gap: 5px;
}
.cell {
display: flex;
justify-items: stretch;
gap: 5px;
}
.cell div {
border: 3px solid black;
}
.large {
flex-grow: 3;
}
.small {
flex-grow: 2;
}
<div class="container">
<div class="cell">
<div class="large">One</div>
<div class="small">Two</div>
</div>
<div class="cell">
<div class="small">Three</div>
<div class="large">Four</div>
</div>
</div>
So again, this wraps the first two cells and last two cells in their own respective divs, which creates two equivalent cells in the grid. You can then use an auto-fill on these outer divs.
You can make each of the two grid cells a flex display to format the two internal divs. Use flex-grow to size the internal divs by a 3:2 and 2:3 ratio, respectively.
It isn't a very flexible solution, because the outer divs still have to be sized in a repeatable pattern. But in your case, they are, so it solves this specific problem — assuming that you can change your HTML.
This is something that I've been struggling with for a while, but I can't seem to find a way to do it.
If you have an odd number of items in grid and you want 2 items per row (1fr 1fr), you end up with a single item in the last row that is left-centered.
I just want to make it centered so it looks nicer.
Here's a picture too.
You can try something like this jsfiddle:
/* visibility properties */
body {
width: 60%;
margin: 5% auto;
}
div {
margin: 3%;
width: 100px;
height: 100px;
background-color: black;
justify-self: center;
}
div:nth-of-type(2n) {
background-color: red;
}
/* actual code: */
section {
display: grid;
grid-template-columns: 1fr 1fr;
}
#last-div {
grid-column: 1 / span 2;
}
<section>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div id="last-div">
</div>
</section>
Get more info on CSS Grid: complete-guide-grid
You could try something like this since I faced a similar issue in one of my earlier projects.
grid-template-columns : repeat(auto-fit, minmax(<minSize>, 1fr));
Set minSize to whatever minimum width you want an element to occupy.
I have 4 columns. The actual content for columns 1 and 4 is 150px, column 2 is 250px and column 3 is 370px. I want to wrap the columns when the browser width changes. When I decrease the width of the browser, I want each column to shrink down to their lowest width before wrapping. So I imagine the 4th column would fall to the next row with a 100% width after it fell below 150px width.
Here's what I thought should've done the trick:
repeat(auto-fit, minmax(max-content, 1fr))
Is there a way to achieve this without passing a fixed width where 'max-content' is?
Here's my solution using media queries and hard widths
https://jsfiddle.net/9hjb5qv8/
Here's the html/css I used in the fiddle above:
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(370px, 1fr));
grid-gap: 8px;
}
#media (max-width: 799px) {
.container {
grid-template-columns: minmax(max-content, 1fr);
}
}
#media (min-width: 800px) {
.container .p2,
.container .p3 {
grid-column: auto / span 2;
}
}
.container > div {
background-color: gray;
text-align: center;
}
<div class="container">
<div class="p1">
<img src="https://via.placeholder.com/150x150">
</div>
<div class="p2">
<img src="https://via.placeholder.com/250x150">
</div>
<div class="p3">
<img src="https://via.placeholder.com/370x150">
</div>
<div class="p4">
<img src="https://via.placeholder.com/150x150">
</div>
</div>
I had a similar question when playing around with grid:
grid-template-columns: repeat(auto-fit, minmax(max-content, 1fr))
If we take a look at the documentation we can see that minmax command is valid:
https://developer.mozilla.org/en-US/docs/Web/CSS/minmax
But in a repeat documentation on csswg, it states one simple rule that disallows all of this from happening;
https://drafts.csswg.org/css-grid/#funcdef-repeat
The generic form of the repeat() syntax is, approximately,
repeat( [ <positive-integer> | auto-fill | auto-fit ] , <track-list> )
The first argument specifies the number of repetitions. The second
argument is a track list, which is repeated that number of times.
However, there are some restrictions:
The repeat() notation can’t be nested.
Automatic repetitions (auto-fill or auto-fit) cannot be combined with
intrinsic or flexible sizes.
Whats an intrinsic or flexible sizes ?
An intrinsic sizing function (min-content, max-content, auto, fit-content()).
So the command wont work in grid because each column/row will be different sizes and wrapping cannot take place. See bellow picture as example.
This behavior should be executed using flex-box instead.
#kivylius has a great answer to why max-content, min-content or other intrinsic sizing wouldn't work with auto-fit. He also suggested using flexbox to achieve what you are after. So, I am just extending on his answer leaving the flexbox way of doing it.
.flex-auto-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 10px;
}
.flex-auto-wrap > * {
flex: 1; /* this is to make elements/columns in each row have equal width and fill up all available space in the row, similar to auto-fit in grid */
/* flex-grow: 1; this can be used to make elements/columns in each row maintain their individual width but stretch to fill up all available space in the row */
}
div {
color: #ddd;
background-color: #222;
padding: 5px;
text-align: center;
}
<section class="flex-auto-wrap">
<div>1</div>
<div>11</div>
<div>111</div>
<div>1111</div>
<div>11111</div>
</section>
PS: I used to think grid came as an alternative to flexbox so I would try to do everything using the newer grid technology. But as it turned out, even though you can do most things with grid, it still doesn't replace flexbox. In fact, flexbox is one dimensional whereas grid is two dimensional. So, they were meant to do things differently. That's why there are some things like this one that can only be done with flexbox but not grid and there are many things that can only be done with grid but not flexbox.
Currently I try to create an "image gallery" with flex box.
This is what I currently have: https://jsfiddle.net/neu28Lnc/2/
The width of the images are always 50% - meaning I will always have 2 images next to each other.
Height of the page is not fixed - you should be able to scroll / add more images.
The problem I have, is that I want to remove the gaps between those images.
Like this: https://jsfiddle.net/neu28Lnc/1/ (hard coded with margins).
Usually I would use flex-direction: column; but since I have a no height, it will never wrap to a 2nd column.
Maybe some of you can help me with my issue / have a better solution.
Thanks in advance.
Syllz
You can do something with css Grid, but after all, css grid is more for grids, of course.
A grid is made of lines which supports each other. Each rectangular form drawn by those lines inevitably share a common horizontal and vertical line.
Flexbox is another option, but you have to set a height to your container so that columns wrap with the flex-direction: column.
If you have a lot of elements, and they exceed the space given by the height we have established, the container will break, with the remaining elements showing up on one side.
The best option here is Multi-column. Example
Cons:
- We can't have an item span more than 1 column.
- The items aren`t listed horizontally.
For me is the best "css only" solution.
W3C - CSS Multiple Columns
You can use masonary using grid layout. Hope this is helpful to you.
.container {
display: grid;
grid-gap: 10px;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-rows: 20px;
}
.image {
height: 50px;
background: #ddd;
}
.image2 {
height: 150px;
background: #abc;
}
.image3 {
height: 180px;
background: #def;
}
.image4 {
height: 30px;
background: #fad;
}
.image5 {
height: 150px;
background: #ddd;
}
<div class="container">
<div class="image img">img1</div>
<div class="image2 img">img2</div>
<div class="image3 img">img3</div>
<div class="image4 img">img4</div>
<div class="image5 img">img5</div>
<div class="image img">img1</div>
<div class="image2 img">img2</div>
<div class="image3 img">img3</div>
<div class="image4 img">img4</div>
<div class="image5 img">img5</div>
</div>