I'm quite new to css grids. I need to code a 2 columns component, with fluid equal height images inside. I could do it with flexbox, but this time I need a css grid, and it must be responsive.
That said, this component has 2 images, 1 per column. The original img files have equal heights (340x300, 708x300). I need to show them about 30% and 70% width, minus gap. I tried to use both 'auto' and fr units, also combined, but no luck.
On the last/large breakpoint, it's all fine:
The problem comes when on smaller breakpoints: I can't keep the 2 images the same exact height (make them scale with same height):
Here's some code, one of the versions. But any variation of this code (different unit combinations) give some kind of problems, and none of them makes me having equal height images:
.images-block-box{
display: grid;
grid-gap: 16px;
grid-template-columns: auto auto;
//grid-template-columns: 1fr auto;
//grid-template-columns: 1fr 2fr;
//grid-template-columns: 33.333% 66.666%;
}
Ah, and obviously, the images are fluid (max-width:100%; height: auto).
How to solve?
The original img files have equal heights (340x300, 708x300).
You can exploit the fact that fractional units work in proportions of the items. So use grid-template-columns: 340fr 708fr if the images file are not going to change. See demo below:
.images-block-box{
display: grid;
grid-gap: 16px;
grid-template-columns: 340fr 708fr;
}
img {
max-width: 100%;
height: auto;
display: block;
}
<div class="images-block-box">
<img src="https://via.placeholder.com/340x300"/>
<img src="https://via.placeholder.com/708x300"/>
</div>
This is my answer. The trick is using img{object-fit: cover;}
.wrap{
width:100vw;
display:grid;
grid-template-columns:3fr 7fr;
grid-gap:1em;
}
.a img{width:100%;height:100%;object-fit: cover;}
<div class="wrap">
<div class="a">
<img src="http://via.placeholder.com/340x300" />
</div>
<div class="a">
<img src="http://via.placeholder.com/708x300" />
</div>
</div>
Related
I have a group of items that I want to behave like display: flex but in a display: grid layout. What I mean by this is that they are in a grid but the sizes of each grid box are flexible to allow more space for larger titles.
I tried to get the display: grid elements to be more flexible with the css selector grid-auto-columns
<div id="grid">
<div id="item1"></div>
<div id="item2"></div>
<div id="item3"></div>
</div>
#grid {
height: 100px;
display: grid;
grid-template-areas: "a a";
gap: 10px;
grid-auto-columns: 200px;
}
But I would prefer teat the sections remain rigid in size once they are set instead of being truly flexible
I'm looking to implement a set of cards that fill the full width of the page.
However, I'd still need the cards to keep within the dimensions of the parent for the left hand side, I only need to 'break' the restrictions of the right-hand side.
Please see image attached to help better explain what I'm trying to achieve.
The left side remains within parent's dimensions, but I need the right-hand side to fill the remainder of the page.
<div class="container">
<div class="cards">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
</div>
.container{
max-width:1020px;
position:relative;
margin:0 auto;
}
.cards{
position:absolute;
width: 100%; (not sure what to set here to make it fill the remainder of the page instead of just the parent's dimensions)
}
.card{
width: 268px;
display:inline-block;
}
Any help would be greatly appreciated.
Many thanks
You can use a grid to set it fully-responsive:
<div class="container">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
.container{
max-width:1020px;
display: grid;
grid-template-columns: repeat(3, 1fr); // for 3 cards in a row, fully strached
// OR
grid-template-columns: repeat( auto-fill, minmax(150px, 300px) ); // for auto-fill the screen, based on min and max size for each card, and the screen size
grid-auto-rows: 100px; // set all cards height to 100px, can be changed as well
margin:0 auto;
}
.card{
// to fill the all grid-cell completely
width: 100%;
height: 100%;
}
If you don’t need to take care of both rows and cols, consider using flex instead of grid.
currently I’m struggling with positioning these 3 text columns just like in picture. Each column contains 3 patagraphs.
Problem is, paragraph’s width is not equal, so grid-template-columns:repeat(3, 1fr) is not ideal solution because second and third paragraph will have unnecessary big white-space and that’s the problem when responsibility comes in. (Layout will break very soon because of that white-space).
I’ve tried min-content or max-content atributes but still I can’t figure it out, so it will look just as in the picture.
So goal is to align columns and paragraphs in it just like in the picture but without unwanted whitespace so work with responsibility will be easier.
Is there any better solution for it?
I have tried my best, here’s codepen
Thank you!
You can use minmax in your grid-template-column property, minmax(5rem, 10rem) minmax(3rem, 5rem) auto;, this will set the minimum width of the first column to 5rem and the maximum width to 10rem, the second to min of 3rem and max of 5rem, then the last columns width will be the width of its content => auto.
css-grid-layout-minmax ~ MDN
.card {
background: silver;
padding: 0 1rem;
border-radius: 12px;
}
.column {
display: grid;
grid-template-columns: minmax(5rem, 10rem) minmax(3rem, 5rem) auto;
justify-content: flex-start;
}
p:nth-of-type(3),
p:nth-of-type(4),
p:nth-of-type(2) {
text-align: right;
}
p + p {
margin-left: 1rem;
}
<div class="card">
<div class="column-wrapper">
<div class="column">
<p>lorem:</p>
<p>282726€</p>
<p>28%</p>
</div>
<div class="column">
<p>lorem ipsum:</p>
<p>287€</p>
<p>10%</p>
</div>
<div class="column">
<p>lorem:</p>
<p>19118€</p>
</div>
</div>
</div>
I wist to make a layout like this one:
Layout Description:
A grid surrounded with a 30px gap
Each cell contains an image (430 X 882)
I want the user who enters the page will see only the grid and it's padding (i.e the Viewport area) from screen width of 767px and up, while keeping the 30px gap and the images aspect ratio (even in weird ratios where the width is way longer then the height).
I am not a web developer, but the behavior I seek is like WPF ViewBox which all it does is "scale to fit the content".
Here's what I did:
.grid-container {
margin: 30px 0;
}
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: 1fr;
grid-gap: 30px 30px;
grid-template-areas: "a1 a2 a3 a4";
}
.background-cover {
object-fit: cover;
width: 100%;
}
<div class="grid-container">
<div class="grid">
<div class="grayscale grid-cell ">
<img class="background-cover" src="http://via.placeholder.com/430x882">
</div>
<div class="grayscale grid-cell ">
<img class="background-cover" src="http://via.placeholder.com/430x882">
</div>
<div class="grayscale grid-cell ">
<img class="background-cover" src="http://via.placeholder.com/430x882">
</div>
<div class="grayscale grid-cell ">
<img class="background-cover" src="http://via.placeholder.com/430x882">
</div>
</div>
</div>
I don't know what to do to keep the the grid in fullscreen.
I tried setting 90vh height to the grid, but it didn't help.
Am I on the right track? or I should use something else like flex, or even use JS?
Is there a way in Boostrap to make grid columns adjust according to the width of the viewport? I have the following page, where the first column is col-md-3 and the second col-md-9:
The right hand column is supposed to show a list of files when the user selects a folder in the left hand column. Yet the column widths stay fixed, and if I reduce the screen width just the tiny bit, the right-hand column is moved to below the left-hand column. The left hand column then fills the height and width of the screen, and the file list column is invisble below it, making for a very bad UX.
Is there some way, preferably in Bootstrap, to have the columns adjust their width in proportion to the screen width, or is there some alternative to Bootstrap with a grid that can work like that?
You can simply achieve this using css grid.
body{
margin:0;
}
.container{
display:grid;
grid-template: 100vh / repeat(12, 1fr);
color:#fff;
}
.container > div{
display: flex;
justify-content: center;
align-items:center;
font-size: 2em;
}
.left-panel{
grid-column: 1 / 4;
background: #F7A072;
}
.right-panel{
grid-column: 4 / -1;
background: #0FA3B1;
}
<body>
<div class="container">
<div class="left-panel">Left</div>
<div class="right-panel">Right</div>
</div>
</body>