This question already has answers here:
How to set gaps (gutters) in a flex container?
(3 answers)
Closed 3 years ago.
Codesandbox example: https://codesandbox.io/embed/silly-firefly-87cov
We have random number of element inside parent. Elements position themselfs as it fit using flexbox.
Problem: how to do margins only between elements and not with parent?
I'd like to share a CSS Grid solution with you. We can use grid-gap to specify the spacing between the children themselves. This allows us to remove margin and focus on a more declarative layout from the parent element.
const Parent = styled.div`
display: grid;
grid-auto-rows: 300px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-gap: 5px;
`;
const Element = styled.div`
background-color: black;
border: 1px solid green;
color: white;
`;
CodeSandbox
Related
I'd like to set up a CSS layout where a container contains a fixed number of flexible width tiles with the following properties:
Spacing in between tiles is fixed and consistent
They can expand in size between a fixed min and max width, but should all be the same width irrespective of their content. In the example below I'm using 100px min width and 200px max width.
They should wrap onto multiple lines if at their minimum width they don't all fit horizontally in the container.
If the container is much larger they should not expand larger than their maximum fixed width, should remain centered in the container and the space between them should not expand.
Perhaps it's not possible with pure CSS, but it feels like it should be! There's a minimal example below, which I'll detail here:
https://jsfiddle.net/vztskh6f/1/
Option 1: CSS Grid
This seems to be the best candidate, seeing as we always want tile widths to be consistent. In order to get columns to wrap I believe you need to use the repeat() syntax and repeat(auto-fit, ...) seems best for this use case. The obvious solution seems to be to use repeat(auto-fit, minmax(100px, 200px)). However, this does not work tiles always remain at 200px irrespective of the width of the container. In every other way this is behaving as desired:
.gridContainer {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 200px));
padding: 10px;
gap: 10px;
justify-items: center;
justify-content: center;
}
.child {
width: 100%;
height: 30px;
background: #0f0;
text-align: center;
}
It could be possible to enforce the desired spec with Option 1, by using grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)) and then setting a computed max-width on the container and forcing it to center too, but it feels like this should be possible with CSS Grid alone?
Option 2: Flexbox
Wrapping is much simpler to achieve with flexbox and using the flex on a child means we can easily set flexible tiles with min and max widths. However once a child wraps onto a second line, it will obviously expand to its max width and will be inconsistent with other tiles:
.flexContainer {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child {
height: 30px;
background: #0f0;
text-align: center;
min-width: 100px;
max-width: 200px;
// this seems to create consistent widths better than flex: 1 1 100px;
flex: 1 1 0;
// could use gap if it wasn't for Safari
margin: 0 5px 10px;
}
Screenshots
The first row is the grid layout, the second is the flex layout, you can see these are behaving nicely at full width, not expanding beyond their max widths with consistent spacing between them:
As the container shrinks you can see that the grid layout items are not shrinking with it, but immediately wrap. flex layout behaves nicely:
As the container continues to shrink, the flex starts to wrap in the desired place, but immediately the tile on the next row expands to its max width:
In order to achieve what you're trying to do, you'll need to work on both the container and the child.
On the container, you'll set a min-width to 100px and a max that should be the size of the child:
.gridContainer {
grid-template-columns: repeat(auto-fit, minmax(100px, max-content));
}
And on each child, you'll have a fixed width, but a max-width of 100% so it shrinks if needed:
.child {
width: 200px;
max-width: 100%;
}
Updated fiddle: https://jsfiddle.net/7exd5hom/
I have a display: grid div that contains elements.
These elements should be placed automatically as rows of elements, with a 1 / 1 aspect ratio so the parent should be scrollable.
Let's say I have 32 items, and I want them to show as 4 row of 8 items.
The items' width are shrinked to not overflow the parent, but I want them to overflow if needed.
Here is the parent CSS :
display: grid;
gap: 10px;
padding: 20px;
grid-auto-flow: column;
grid-template-rows: repeat(4, 1fr);
and the items CSS
aspect-ratio: 1 / 1;
It works just well if I explicitly add width or height to the children, but I want them to grow automatically.
CodePen : https://codepen.io/dbenfouzari/pen/GRmdVze?editors=1100
Try to resize the window to a smaller width to see it no working.
Thanks !
Thanks to #G-Cyrillus answer, I finally get it to work simply by adding overflow: auto; on the parent wrapper and min-width: max-content; on each child !
I am using CSS Grid to display some tags. If a tag is large (ie. it's width is more than 150px), I would like that item to span into more columns as needed. For example, in the image I would like the red tag to span into two columns so that the text remains in one line.
Is it possible to do something like that without adding a specific class to the target element? I am mapping through an array in React to generate each of these divs so it won't be possible to add a class to that element only.
index.js
<div className={styles.container}>
<>
{tags.map(tag => {
return <TagBlock tag={tag} />
})}
</>
</div>
style.css
.container {
margin: 30px auto;
width: 90%;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, auto));
grid-gap: 20px;
}
Don't know a way to implement a gradual column width increase via CSS only. A JS logic will be required to set "how many columns it should take". Then one of the following cases.
explicitly style for the "wide" column:
grid-column: span X;
where X is how many columns should take your element.
Set predefined classes (like at Bootstrap: col-1, col-2), then apply them.
If a column could have any width, then I would recommend you to use a flexbox with wrapping. Kind of:
.container {
margin: 30px auto;
width: 90%;
/*added properties below*/
display: flex;
flex-wrap: wrap;
align-content: flex-start;
}
/*TagBlock base style that grid generated on its own*/
TagBlock {
margin: 25px;
min-height: 120px;
min-width: 120px;
}
Hope, this will help a little.
I have such container
#container{
display: grid;
grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}
of such items
.picture_tile{
width:200px;
height: 200px;
position: relative;
background: white;
color: black;
margin: auto;
}
it adjusts nicely horizontally. It nicely adjusts while scaling my monitor, is it possible to apply space between the images to rows as well? I am total beginner to CSS. Is it possible to apply the same space that is changing between the items on vertical gap? When I scale my monitor and the items' horizontal gap is anything between 10-50px. Can the same change apply on vertical gap while changing horizontal size of my window? I hope it's understandable. I only want to have perfect grid with perfect gaps, everything same, but the content would be dynamic and behave like when display: grid is applied
You can use grid-gap: value property on your #container
This question already has answers here:
What is difference between justify-self, justify-items and justify-content in CSS grid?
(4 answers)
Closed 4 years ago.
I am new in CSS-Grid topic, I created a header for a website with the help of GRID, I created header with logo , navBar , searchbar , button with grid
.header {
height: 60px;
margin-bottom: 20px;
display: grid;
grid-template-columns: 1fr 3fr 0.1fr 0.5fr;
grid-auto-rows: 70px;
align-items:center;
justify-items: center;
}
Now these last two properties align-items and justify-items are apply for all ie, for logo , navbar , searchbar , button.
My problem is :I want to override this justify-items:center property
to justify-items:flex-start for navBar only. So who can I do this?
Here is screenshot of header:
If you're writing in pure CSS, you can add another line that is more specific, like this
.header .navBar {
justify-items:flex-start;
}
This will take priority over the previous css style you have. Generally speaking the more specific styles are applied first.