How about a CSS grid featuring squares with square images?

Just like the inquiry found on this page, I am striving to construct a grid of perfect squares, each containing an image with 100% height.

The issue arises from utilizing the padding-bottom: 100%; height: 0 method, which prevents height: 100% from functioning properly on the image due to the browser perceiving the container as having zero height.

Is there a way to dictate the image's height to match that of the cell?

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  grid-gap: 4px;
}

.item {
  overflow: hidden;
  position: relative;
  background-color: red;
  width: 100%;
  padding-bottom: 100%;
  height: 0;
}

img {
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  display: block;
  /*height: 100%;*/
}
<div class="grid">
  <div class="item">
    <img src="https://picsum.photos/400/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/500/250">
  </div>
  <div class="item">
    <img src="https://picsum.photos/600/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/400">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
</div>

To clarify, my goal is to elongate the image while retaining its aspect ratio. The edges will be clipped when necessary, and the image will remain centered within the cell.

Answer №1

One way to achieve a flexible square grid layout is by creating a "hidden" cell using a pseudo element with specific CSS properties and overlapping it with the real first cell. By setting all cells to the same height with grid-auto-rows: 1fr; and positioning the images absolutely, you can create a visually appealing grid design.

For more detailed information on this technique, check out this article: https://medium.com/cloudaper/how-to-create-a-flexible-square-grid-with-css-grid-layout-ea48baf038f3

.grid::before {
  content: '';
  width: 0;
  padding-bottom: 100%;
  grid-row: 1 / 1;
  grid-column: 1 / 1;
}
.grid > *:first-child {
  grid-row: 1 / 1;
  grid-column: 1 / 1;
}
.item {
  overflow: hidden;
  position: relative;
  background-color: red;
  width: 100%;
  /* padding-bottom: 100%; */
  /* height: 0; */
}
img {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  min-width: 100%;
  min-height: 100%;
}

Answer №2

To ensure that the replaced content maintains its aspect ratio while filling the element’s content box, you can use object-fit: cover and assign an explicit height to the grid items. Check out the details on object-fit MDN for more information.

By employing object-fit: cover, you can eliminate the need for the height: 0 and padding-bottom: 100% workaround. However, keep in mind that if the object's aspect ratio differs from that of its container, it will be clipped to fit the container.

If you prefer not to have the "clipped to fit" effect, stick with this CSS setup where the images fill 100% of the grid item height without any clipping:

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  grid-gap: 4px;
}

.item {
  overflow: hidden;
  position: relative;
  background-color: red;
  width: 100%;
  height: 18rem; /* adjust as needed */
}

img {
  display: block;
  max-width: 100%;
  object-fit: cover;
  width: 100%;
  height: 100%;
}
<div class="grid">
  <div class="item">
    <img src="https://picsum.photos/400/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/500/250">
  </div>
  <div class="item">
    <img src="https://picsum.photos/600/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/400">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
</div>

Answer №3

If you want to achieve this, follow these steps:

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  grid-gap: 4px;
}

.item {
  background-color: red;
  aspect-ratio: 1; /* ensuring square items */
}

img {
  /* no size contribution */
  width: 0;
  height: 0;
  /* */
  /* fill the item space*/
  min-height: 100%;
  min-width: 100%;
  /* */
  display: block;
  object-fit: cover; /* preventing distortion*/
}
<div class="grid">
  <div class="item">
    <img src="https://picsum.photos/400/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/500/250">
  </div>
  <div class="item">
    <img src="https://picsum.photos/600/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/400">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
  <div class="item">
    <img src="https://picsum.photos/300/300">
  </div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Media publications do not conform to the current trends

I'm currently utilizing the HTML-to-paper plugin to print my content on a printer. However, I've encountered an issue where it doesn't seem to apply any of the styles I've defined within @media print. The challenges I'm encounteri ...

Transferring Data through the POST Method

Is there a way for me to send just one variable using the post method? I have retrieved the $row[id] from the database and need to include it in the form submission. We know how to send user input using dfs, but what about sending the specific $row[id] v ...

How do I create more space in Vitepress to prevent the text from feeling cramped and allow it to display in a larger area?

Below is the content of my index.md file: --- # https://vitepress.dev/reference/default-theme-home-page layout: home hero: name: "TP2" text: "Analyzing the code of TP2 by Breno Mazzali Medeiros Tomazelli and Philippe Bouchard" ta ...

I am attempting to assign a default value to a TextField by retrieving data from a GetMapping call in React, however, the value is not being successfully set

I am facing an issue with setting a default value for a TextField in my code. Even though I am trying to populate it with data from a GetMapping call, the value is not being set as expected. Here is the JSON response I receive from the API call: { "id": 1 ...

What is the best way to position this grid container directly beneath the search box using absolute positioning?

<!DOCTYPE html> <html lang="tr"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Unique Starter</title> ...

Which event listener in the DOM API should I use to trigger an action when a form field is focused, whether through a mouse click or by tabbing?

My aim is to increase the size of form fields when the cursor focuses on them, either through a mouse click or by tabbing using the keyboard. By utilizing document.activeElement focus, I can identify when the user clicks inside a text input or selects an ...

bring in all the files located within the Directory

Is there a way to import all CSS files from a specific folder without having to import each file individually? Looking to import assets/css/* ? <link href="<?php echo base_url(); ?>assets/css/*" rel="stylesheet"/> <title&g ...

What is the best way to modify CSS animation property without causing any disruptions?

Could you help me with modifying this CSS animation? I want to adjust the animation-iteration-count to 1 only when a certain property, status, is added to the element. Currently, the animation is not working as expected. For example: setTimeout(() => ...

I am seeking advice on how to incorporate JavaScript to adjust slider values and add numerical values or prices. Any suggestions would

Seeking assistance with a unique project: I am currently developing a calculator that allows users to utilize sliders to select the best option for themselves across various categories. My experience with JavaScript is limited, so I decided to reach out h ...

Is it possible to toggle between thumbnails and a larger image in a jQuery gallery?

Hello, I am new to website development and I would like to create a jquery based photo gallery for my personal website. One feature that really catches my eye is this one (for example): The gallery has a large thumbnail grid where you can click on a thumb ...

Utilizing CSS float with dynamic height

Is there a way to achieve height:auto; for a parent element even when child elements are using float:left; or float:right? Solution for the Parent Element: #parent { width:100px; height:auto; padding-bottom:10px; background:#0F0; ...

Switch out the rowspan attribute in HTML for a CSS alternative

Hello there, I've been experimenting with replacing my table layout with divs and CSS, but I'm struggling to find a way to replicate the behavior of the rowspan attribute. Here is the original code snippet: <table> <tr> <td> ...

Converting a table into JSON format

I'm working on developing a live application that will showcase data in a table format like the one below: Machine Production Scanned Delta Mach 1 2500 1000 1500 Mach 2 1500 1300 200 Mach 3 6500 5000 1500 Mac ...

The JQuery TextNTags plugin eliminates tag formatting once the trigger syntax has been modified

I have incorporated the JQuery TextNTags plugin into my web application. Here is the original code snippet: $.browser = { webkit: true }; $(function () { $('textarea.tagged_text').textntags({ triggers: {'!': { ...

Tips for aligning a div within a flexbox to the bottom position

I'm having trouble aligning the div at the bottom of the flex box. I attempted to use align-content: flex-end; but it didn't work. Is there a way to keep the <.div class="parameters"> at the bottom of the row? Especially when the ...

Unable to set the correct title view for mobile devices

We have successfully styled the products for desktop view and larger phones, but we are facing challenges in adjusting them properly for smaller phones. Below you will find a photo and corresponding code snippets: /* Products list - view list */ .product ...

Issue encountered while determining the specificity of a CSS selector involving pseudo-classes

As I delved into a tutorial on MDN, an intriguing code snippet caught my attention: /* weight: 0015 */ div div li:nth-child(2) a:hover { border: 10px solid black; } An unanswered question lingers in my mind: Why does this rule's specificity displa ...

Searching dynamically using class names with JQuery

I am seeking to create a dynamic search input based on the class names within the span tags. However, I am struggling with displaying the class name that I have identified. My goal is to show the class names that match the entered value in the input on the ...

Using CSS to Put Text in the Back of Other Text

After being inspired by the structure of view-source:, I attempted to layer one instance of text behind another using z-index. However, my initial attempt failed as it became clear that utilizing z-index required the position attribute to work effectively. ...

Incorporate 'Additional features' into the Navbar when adjusting window size

When the window is resized, I want to display a collapsed 'More options' button that will collapse all hidden <li> elements. Here is an example: <li id="menu_more_container" class="dropdown" style="display: none; ...