Reputation: 614
I am creating a CSS grid that displays the photos of the guests in my podcast.
For my particular case, the grid will assume:
The basic structure of the HTML looks like this:
<div class="cards">
<img src="/guests/guest1.png" alt="" class="card" class="card">
<img src="/guests/guest2.png" alt="" class="card" class="card">
<img src="/guests/guest3.png" alt="" class="card" class="card">
<img src="/guests/guest4.png" alt="" class="card" class="card">
</div>
I want the guests to display within a CSS grid container.
Note: I do not want the images to look stretched, so I use
object-fit: cover
(but that is not the issue, I do not think)
.cards {
display: grid;
grid-template-columns: repeat(2, minmax(50%, 100%));
gap: 2px;
width: 110px;
height: 110px;
}
.card {
width: 100%;
object-fit: cover;
}
The rules I want to set are as follows:
As you can see in the screenshot, The grid does not display as I would hope for 2 guests or 1 guest.
Perhaps CSS Grid is the wrong choice or maybe I am missing something?
Ideally, I do not want to use JavaScript, but scss mixins would be okay (which may be a choice here?), but I would like to know if I can do this purely with CSS Grid or maybe Flexbox(?). If it helps any, I am using Jekyll with the Liquid language.
Is there a way I can create a CSS Grid that properly displays the photos so they are the correct size based on the number of images displayed?
Upvotes: 4
Views: 1789
Reputation: 4421
Give the nested images inside your .cards
grid a height: 100%
declaration so they occupy 100% of each grid items height. To handle the scenario when there is only a single <img>
element without any siblings inside the grid, you could use the :only-child
pseudo class to target the .card
which doesn't have any siblings. Then make it occupy both of the columns with grid-column: -1 / 1
. This way the single image will span both columns occupying the original 110px width of your two column grid.
.cards {
display: grid;
grid-template-columns: repeat(2, minmax(50%, 1fr));
gap: 2px;
width: 110px;
height: 110px;
border: 2px solid #000;
margin: 1rem 0;
}
.cards .card:only-child {
grid-column: -1 / 1;
}
.card {
width: 100%;
height: 100%;
object-fit: cover;
}
<!-- Four cards -->
<div class="cards">
<img src="https://images.unsplash.com/photo-1516125073169-9e3ecdee83e7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8NXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt="cat" class="card" class="card">
<img src="https://images.unsplash.com/photo-1516125073169-9e3ecdee83e7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8NXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt="cat" class="card" class="card">
<img src="https://images.unsplash.com/photo-1516125073169-9e3ecdee83e7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8NXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt="cat" class="card" class="card">
<img src="https://images.unsplash.com/photo-1516125073169-9e3ecdee83e7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8NXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt="cat" class="card" class="card">
</div>
<!-- Three cards -->
<div class="cards">
<img src="https://images.unsplash.com/photo-1516125073169-9e3ecdee83e7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8NXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt="cat" class="card" class="card">
<img src="https://images.unsplash.com/photo-1516125073169-9e3ecdee83e7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8NXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt="cat" class="card" class="card">
<img src="https://images.unsplash.com/photo-1516125073169-9e3ecdee83e7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8NXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt="cat" class="card" class="card">
</div>
<!-- Two cards -->
<div class="cards">
<img src="https://images.unsplash.com/photo-1516125073169-9e3ecdee83e7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8NXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt="cat" class="card" class="card">
<img src="https://images.unsplash.com/photo-1516125073169-9e3ecdee83e7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8NXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt="cat" class="card" class="card">
</div>
<!-- One card -->
<div class="cards">
<img src="https://images.unsplash.com/photo-1516125073169-9e3ecdee83e7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8NXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt="cat" class="card" class="card">
</div>
Upvotes: 2
Reputation: 1227
Nevertheless, it will be optimal for your task to use "display: flex". The blocks will themselves be arranged in the correct order. If the block is both the first and the last child (that is, the only one), then the block is stretched to fit the parent. I would do it like this:
.cards {
display: flex;
flex-flow: row wrap;
gap: 4px; padding: 8px;
height: 150px; width: 150px;
box-shadow: -1px -2px 2px -1px #0004, inset 1px 2px 5px 0px #0004;
}
.card {
width: calc((100% - 4px) / 2);
height: calc((100% - 4px) / 2);
object-fit: cover;
box-shadow: 0 1px 3px #000;
}
.card:first-of-type:last-of-type {
height: 100%; width: 100%;
}
body { margin: 0; min-height: 100vh; display: flex; justify-content: space-evenly; align-items: center; }
<div class="cards">
<img src="https://i.pravatar.cc/?img=1" alt="1" class="card">
</div>
<div class="cards">
<img src="https://i.pravatar.cc/?img=1" alt="1" class="card">
<img src="https://i.pravatar.cc/?img=2" alt="2" class="card">
</div>
<div class="cards">
<img src="https://i.pravatar.cc/?img=1" alt="1" class="card">
<img src="https://i.pravatar.cc/?img=2" alt="2" class="card">
<img src="https://i.pravatar.cc/?img=3" alt="3" class="card">
</div>
<div class="cards">
<img src="https://i.pravatar.cc/?img=1" alt="1" class="card">
<img src="https://i.pravatar.cc/?img=2" alt="2" class="card">
<img src="https://i.pravatar.cc/?img=3" alt="3" class="card">
<img src="https://i.pravatar.cc/?img=4" alt="4" class="card">
</div>
If you need two blocks to have 100% height, then add one more rule:
.cards {
display: flex;
flex-flow: row wrap;
gap: 4px; padding: 8px;
height: 150px; width: 150px;
box-shadow: -1px -2px 2px -1px #0004, inset 1px 2px 5px 0px #0004;
}
.card {
width: calc((100% - 4px) / 2);
height: calc((100% - 4px) / 2);
object-fit: cover;
box-shadow: 0 1px 3px #000;
}
.card:first-of-type:last-of-type {
height: 100%; width: 100%;
}
.card:nth-last-of-type(2):first-of-type,
.card:nth-of-type(2):last-of-type {
height: 100%;
}
body { margin: 0; min-height: 100vh; display: flex; justify-content: space-evenly; align-items: center; }
<div class="cards">
<img src="https://i.pravatar.cc/?img=1" alt="1" class="card">
</div>
<div class="cards">
<img src="https://i.pravatar.cc/?img=1" alt="1" class="card">
<img src="https://i.pravatar.cc/?img=2" alt="2" class="card">
</div>
<div class="cards">
<img src="https://i.pravatar.cc/?img=1" alt="1" class="card">
<img src="https://i.pravatar.cc/?img=2" alt="2" class="card">
<img src="https://i.pravatar.cc/?img=3" alt="3" class="card">
</div>
<div class="cards">
<img src="https://i.pravatar.cc/?img=1" alt="1" class="card">
<img src="https://i.pravatar.cc/?img=2" alt="2" class="card">
<img src="https://i.pravatar.cc/?img=3" alt="3" class="card">
<img src="https://i.pravatar.cc/?img=4" alt="4" class="card">
</div>
Upvotes: 0
Reputation: 643
This should work for what you are asking for, You can add or remove the img src
to get the different results.
html
<div class="cards">
<img src="https://www.w3schools.com/images/lamp.jpg" alt="" class="card" class="card">
<img src="https://www.w3schools.com/images/lamp.jpg" alt="" class="card" class="card">
<img src="https://www.w3schools.com/images/lamp.jpg" alt="" class="card" class="card">
</div>
Css
.cards {
display: grid;
grid-template-columns: repeat(2, minmax(50%, 100%));
gap: 2px;
width: 300px;
height: 110px;
}
.card {
width: 100%;
object-fit: cover;
}
/* one item */
img:first-child:nth-last-child(1) {
/* -or- li:only-child { */
width: 300px;
height: 300px
}
/* two items */
img:first-child:nth-last-child(2),
img:first-child:nth-last-child(2) ~ img {
width: 150px;
height: 300px;
}
/* three items */
img:first-child:nth-last-child(3),
img:first-child:nth-last-child(3) ~ img {
}
/* four items */
img:first-child:nth-last-child(4),
img:first-child:nth-last-child(4) ~ img {
}
You can change the nth
element in the way you want them to display. If you change the width
and height
to %
it will take the %
of the image.
That's why I added the width
and height
in pixels according to the grid size. I'm not sure how to use the grid width and height as a % there. (There's probably a way to do that too. I'll add it if I find a way).
But everything else should work.
Upvotes: 1