is there a way how to make gallery with CSS grid with following requirements?
Gallery should always fill entire container and is responsive
Gap between images is fixed
Every image has limited maximum and minimum size (e.g. 200px - 260px)
Code for gallery is following (span represents image in this example):
/* Container */
.grid {
display: grid;
grid-gap: 0.25em;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
/* Image placeholder */
span {
display: block;
background: #eee;
border-radius: 0.25em;
width: 100%;
margin: auto;
}
/* Aspect ratio */
span:before {
content: "";
display: block;
padding-bottom: 100%;
}
<div class="grid">
<div class="item"><span></span></div>
<div class="item"><span></span></div>
<div class="item"><span></span></div>
<div class="item"><span></span></div>
<div class="item"><span></span></div>
<div class="item"><span></span></div>
<div class="item"><span></span></div>
<div class="item"><span></span></div>
<div class="item"><span></span></div>
<div class="item"><span></span></div>
<div class="item"><span></span></div>
<div class="item"><span></span></div>
<div class="item"><span></span></div>
<div class="item"><span></span></div>
</div>
When there are enough items, everything works just fine. But when gallery has only few of them, items are stretched and image becomes blurry and looks terrible. In that case, there should be behavior as with auto-fill used.
We have tried following, but none of these solutions is good enough:
Use auto-fill instead of auto-fit (images tend to be as little as possible instead of as big as possible)
Limit size of single image (gaps become uneven)
Use minmax(200px, 260px) instead of minmax(200px, 1fr) (gallery is not filling entire container)
Do anyone have any idea how to solve that? Any help would be very appreciated!
Use auto-fill instead of auto-fit
Reference: https://css-tricks.com/auto-sizing-columns-css-grid-auto-fill-vs-auto-fit/
.grid {
display: grid;
grid-gap: 0.25em;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
Related
I was searching a way to make a responsive design like so
I have 3 divs inside a parent div
<div style="display: flex">
<div class="logo">some image here</div>
<div class="menu-items">
Home
...
</div>
<div class="login-logout">Here is the login component</div>
</div>
How can I make a responsive version of this to be something like this using only css and sass?
<div style="display: flex; flex-direction: column">
<div style="display: flex">
<div class="logo">some image here</div>
<div class="login-logout">Here is the login component</div>
</div>
<div class="menu-items">
Home
...
</div>
</div>
I want the middle div to stay bellow the other two
I have a guess that this can be possible using grid layout, but honestly I don't understand very much about it and prefer using flex. So if this could be achieved using flex I would be very much appreciated
Edit:
An image of how I want the layout to be.
flex is basically one dimensional whereas grid allows layout in two dimensions.
This snippet takes your code but sets the container to display grid.
grid-template areas are laid out for the wider screens in the ratio 2/3/1 and in the narrower ones in the ratio 2/1 in the top line.
Obviously you'll want to set the relative sizes suitable for your particular case.
.container {
width: 100vw;
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-areas: 'logo logo menu menu menu login';
gap: 2vw;
padding: 2vw;
box-sizing: border-box;
}
.container>* {
border: 3px solid;
box-sizing: border-box;
}
#media (max-width: 768px) {
.container {
grid-template-columns: repeat(3, 1fr);
grid-template-areas: 'logo logo login' 'menu menu menu';
}
}
.logo {
grid-area: logo;
}
.menu-items {
grid-area: menu;
}
.login-logout {
grid-area: login;
}
/* borders added fordemo */
.logo {
border-color: red;
}
.menu-items {
border-color: blue;
}
.login-logout {
border-color: green;
}
<div class="container">
<div class="logo">some image here</div>
<div class="menu-items">
Home ...
</div>
<div class="login-logout">Here is the login component</div>
</div>
I'm trying to create a CSS grid with the following properties:
The grid has a width of 100%
The column's width should be 330px, but should shrink if this allows fitting one more column, but it should never shrink below 288px.
All columns should have the same width
If there is space left, left-align the columns (all remaining space should be on the right side of the grid)
Here a few examples of what I'm trying to achieve
Grid width => columns (width)
----------------------------
658px => |329px|329px|
|329px|
660px => |330px|330px|
|330px|
665px => |330px|330px|5px(whitespace)|
|330px|
863px => |330px|330px|203px(whitespace)|
|330px|
864px => |288px|288px|288px|
867px => |289px|289px|289px|
960px => |320px|320px|320px|
I've tried the following three options:
Approach 1
.grid {
grid-template-columns: repeat(auto-fill, minmax(288px, 1fr));
}
The problem: The columns shrink down to 288px, but they can grow larger than 330px Image with columns larger than the max width
Approach 2
.grid {
grid-template-columns: repeat(auto-fill, minmax(288px, 330px));
}
The problem: the columns never grow, and the columns are left-aligned, but they are always 330px and never shrink down to 288px. Image with columns that don't shrink below the max width
Approach 3
.grid {
grid-template-columns: repeat(auto-fill, minmax(288px, 1fr));
}
.grid > div {
max-width: 330px;
}
The problem: The columns shrink down to 288px, and they never grow larger than 330px, but they are not left-aligned. Image with columns that grow and shrink within boundaries, but are not left-aligned
As you can see, none of the approaches I've tried worked so far. All of them have different problem :( Is there any way to make this layout work with CSS Grid?
This should work, placing it only on the .wrapper - note I did force and exception on a column (.three) to show the effect of that. I used smaller values to accommodate this results execution window
.my-container {
width: 100%;
border: solid green 1px;
padding: 3px;
}
.wrapper {
border: solid cyan 1px;
padding: 3px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100px, 150px), 1fr));
gap: 0.25rem;
}
.thing {
border: solid 1px magenta;
}
.three {
width: 40px;/* to show test of this */
border: solid lime 1px;
}
<div class="my-container">
<div class="wrapper">
<div class="thing one">One comes before two but is a lonely number</div>
<div class="thing two">Two burgers are more than one burger</div>
<div class="thing three">Three</div>
<div class="thing four">Four is the next block of super interesting content with more very happy text.</div>
<div class="thing five">Five test of the test</div>
<div class="thing six">Six</div>
<div class="thing seven">Seven</div>
<div class="thing ">Eight</div>
<div class="thing ">More</div>
<div class="thing ">And More</div>
<div class="thing ">More so more</div>
<div class="thing ">More again</div>
</div>
</div>
I've got CSS grid to produce a two-column layout. But the problem is that it's not top-aligning content in each column.
For example, in the second column, the last element should top-align to but up against the other column-two element.
body>div {
display: grid;
grid-template-columns: 50% 50%;
grid-template-rows: auto auto;
grid-auto-flow: column;
/* https://codepen.io/maddesigns/pen/oZGWRN */
/* https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow */
}
body>div>div:nth-of-type(1) {
height: 300px;
}
body>div>div:nth-of-type(2) {
height: 100px;
}
body>div>div:nth-of-type(3) {
height: 200px;
}
<div style="">
<div style="background:red">
1
</div>
<div style="background:green;">
2
</div>
<div style="background:yellow">
3
</div>
<div style="background:pink">
4
</div>
</div>
I couldn't use flex for this layout because I wanted to achieve this layout without defining the container height. column-count:2 would have worked without defining the container height but then I couldn't use div reordering.
So I'm using CSS grid because div reordering is still available (e.g./i.e. order:–1; works well) and it auto-divies up what to put in each of the two columns.
The gird is acting exactly as intended, to keep order and symmetry just like this. I can recommend using 2 grids side by side to achieve what you're looking for. Here's an example that I made to demonstrate this:
.left{
display: grid;
grid-template-rows: auto auto;
grid-auto-flow: column;
width: 50%;
float: left;
/* https://codepen.io/maddesigns/pen/oZGWRN */
/* https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow */
}
.right{
display: grid;
grid-template-rows: auto auto;
grid-auto-flow: column;
width: 50%;
/* https://codepen.io/maddesigns/pen/oZGWRN */
/* https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow */
}
.left>div:nth-of-type(1) {
height: 300px;
}
.left>div:nth-of-type(2) {
height: 100px;
}
.right>div:nth-of-type(1) {
height: 200px;
}
.right>div:nth-of-type(2) {
height: 50px;
}
<div class="left" style="">
<div style="background:red">
1
</div>
<div style="background:green;">
2
</div>
</div>
<div class="right">
<div style="background:yellow">
3
</div>
<div style="background:pink">
4
</div>
</div>
In fact, until a CSS technology arrives with the ability to automatically close the gaps, CSS in general has no solution. Something like this would probably require reflowing the document, so I'm not sure how useful or efficient it would be.
Source: https://stackoverflow.com/a/45200955/1625909
I'm trying to align a logo and navigation bar in one row across the top of a website using CSS grid.
I've written out the code but can't work out what I'm doing wrong as to why it's not working: https://codepen.io/chloewb/pen/wRRewQ
.logo{
grid-area: logo;
background:white;}
.navi{
grid-area: navi;
background:Yellow;}
.section1{
grid-area: features;
background:LightSalmon;}
.section2{
grid-area: technology;
background:PaleTurquoise;}
.section3{
grid-area: pricing;
background:LightPink;}
.section4{
grid-area: email;
background:PaleGreen;}
.container {
display: grid;
grid-template-rows: repeat (5, auto);
grid-template-columns: 1fr 1fr 1fr;
font-size: 40px;
width: 100%;
background: grey;
grid-template-areas:
"logo navi navi"
"features features features"
"technology technology technology"
"pricing pricing pricing"
"email email email";}
The first thing to notice is that, when you use display: grid on a container element, its direct children will become grid-items, and to these items is that the grid layout you build will apply.
So let's say we have the following:
<div class="container">
<div class="child-1">
<div class="child-2"></div>
<div class="child-2"></div>
</div>
<div class="child-1"></div>
<div class="child-1"></div>
<div class="child-1"></div>
</div>
And this CSS:
.container{
display: grid;
}
Then only the child-1 will become grid items and be able to get properties like grid-area applied to them; everything else inside .child-1, like .child-2 will behave normally, as if there's no Grid. Unless you also specify the .child-1 element to be a grid with display: grid.
In your case, you header element is a direct child of the .container element, so it is a grid item and can be positioned on any place on the grid, but the logo and navi elements are children of header, so the grid layout does not apply to them. You would either have to take them out of the header so the rules you wrote take effect, or create another grid in the header and let it use the full first row. See this example and notice how the nesting of the elements affect them.
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: minmax(50px, auto);
grid-template-areas: "logo navi navi";
margin-bottom: 20px;
border: 1px solid black;
}
.logo {
border: 1px solid red;
grid-area: logo;
}
.navi {
border: 1px solid blue;
grid-area: navi;
}
<div class="container">
<div class="logo">Logo</div>
<div class="navi">Nav</div>
</div>
<div class="container">
<header>
<div class="logo">Logo</div>
<div class="navi">Nav</div>
</header>
</div>
I'm trying create template for rows in my grid block:
grid-template-rows: repeat(3, 150px);
I know, this template should be work for first 3 rows.
However, from 4 row this template is not work.
Can i make template for all rows?
P.S.
This template work only for 1st row.
grid-template-rows: 150px;
Use grid-auto-rows (automatically generated rows) instead of grid-template-rows (manually generated rows). In current case grid-auto-rows: 150px will do the trick. Demo:
.grid {
display: grid;
grid-auto-rows: 150px;
/* space between columns for demo */
grid-gap: 10px;
}
/* just styles for demo */
.grid__item {
background-color: tomato;
color: white;
}
<div class="grid">
<div class="grid__item">One</div>
<div class="grid__item">Two</div>
<div class="grid__item">Three</div>
<div class="grid__item">Four</div>
<div class="grid__item">Five</div>
<div class="grid__item">Six</div>
<div class="grid__item">Seven</div>
<div class="grid__item">Eight</div>
<div class="grid__item">Nine</div>
</div>