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

Navigate through input fields while they are hidden from view

Picture this scenario: <div> <input tabindex="1"> </div> <div style="display:none"> <input tabindex="2"> </div> <div> <input tabindex="3"> </div> As I attempt to tab through these input f ...

Experience the classic game of rock-paper-scissors brought to life through JavaScript and HTML,

I've been working on a rock, paper, scissors game in JavaScript and I'm struggling to get the wins and losses to register correctly. The game keeps resulting in a draw even though I've checked my code multiple times. It's frustrating be ...

What is the best way to modify a Bootstrap class' SASS attribute within a React component?

Just to clarify, I am utilizing react-bootstrap and attempting to incorporate bootstrap. Here is the code I have: import React from 'react' // bootstrap import { Button } from 'react-bootstrap'; const MainDisplay = () => { return ...

Alignment of Material-UI dialogue buttons on the left side

I have a Dialog containing three buttons as shown below: https://i.stack.imgur.com/T6o35.png Here is the JSX code: <DialogActions classes={{ root: this.props.classes.dialogActionsRoot }} > <Button classes={{ root: this.props ...

Setting a constant width for text characters across all devices using CSS and HTML

I am looking to display text in my textarea with the same width in pixels across all devices. Essentially, I want to set the character width in pixels so that it appears consistently on any device (Desktop/Mobile). <html> <head> <styl ...

How come e.target.value always shows the most recent value?

Starting out in HTML and I have a question regarding input. Here is the HTML code I am working with: <input type="text" value="abc" onChange={(e) => { console.log(e.target.value); }}/> I am puzzled because even though the default v ...

Delay the occurrence of a hover effect until the previous effect has finished executing

As I hover over an element, the desired animation is displayed while hiding other elements on the page. The challenge I'm encountering is that if I quickly hover over many divs, the animations queue up and hide the divs sequentially. I want only one ...

How to activate select only when specific options are chosen using jQuery

I am working on a form that has 1 select element disabled, with 4 options. I am looking to implement a jQuery function that will perform the following actions: If OPTION #1 is clicked, it should check if any other options are selected and reset them (eras ...

Sort the currency column in an HTML table through JavaScript

I have a code snippet below that I'm currently utilizing to arrange columns in an HTML table. The code works perfectly for alphabetical sorting and also for single-digit numbers. However, when attempting to sort a column containing currency values, t ...

Is there a way to create an effect where the color of a floating action button changes when you hover over it, similar to a filter?

I'm new to using the <Fab /> element and I'm struggling to figure out how to implement a hover effect that will change the button's color. Here's what I have so far: JavaScript: <Fab variant="extended" className=&quo ...

Is it possible to incorporate both Bootstrap 3 and Bootstrap 4 within the same HTML file for separate div elements on a webpage? If so, what is the best way to achieve this?

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Using Bootstrap 3 and Bootstrap 4 in the Same HTML File</title> </head> <body> <div class="bootstrap3"> Some code her ...

Generate an HTML table from a CSV file with no success in finding a working solution

I came across a solution here However, I am having trouble implementing it. It seems like there might be a basic issue. Can someone provide some advice? This is the snippet of PHP code on my server: $ cat table.php <?php echo "<html><body&g ...

Automating the process of choosing a dropdown option on a website with a Python script

When navigating the website, I found that I needed to choose a specific time duration from a drop-down menu, as shown in the image. My goal is to automate this process using a Python script. I already have a script in place, but it requires an additional c ...

css Repaint the CSS by filtering out list items with odd indexes

Having a list of over 20 items, I utilized the :nth-child(2n+1) selector to alternate the background color (even item in black, odd item in white). However, when using the jQuery Isotope plugin to filter out specific items by adding a .isotope-hidden class ...

Tips for displaying the Year Dropdown before the Month Dropdown in Jquery Datepicker

Currently utilizing the jQuery UI datepicker. Is there a way to display the Year Dropdown first and the Month Dropdown second in the jQuery Datepicker? I am looking to achieve a layout similar to this: ...

"Ensuring Your SVG Icon is Perfectly Centered: A Step

My SVG icon is currently aligned to the left, but I want to center it. I tried using the following code, but it doesn't seem to be working: .parent{ display: flex; align-items: center; font-size: 13px; } span{ margin-right:10px } When I look at the S ...

Express JS is experiencing difficulties with the functionality of the iframe

When I'm using iframe in HTML, it works perfectly fine: <iframe src="main.html" height="100px"></iframe> But when I use Iframe in Express, it shows an error: <iframe src="main.html" height="100px&qu ...

Unable to hide the mobile menu button

I am currently working on a fun website project . I am facing an issue with the mobile menu button not disappearing using display:none in Safari on my iPhone when in landscape mode, even though it works fine in Chrome. My goal is to make the #menu-button ...

I'm having trouble removing records from MySql

I am facing an issue with two tables in my database. Table a is referencing table b, or so I believe. Whenever I attempt to delete the entire package using the following query: $query="DELETE a, b FROM classified as a, $sql_table as b WHERE a.ad_id = &ap ...

Angular text input with customizable placeholder text and embedded icon

Hey there, I'm looking to create a unique custom textbox that includes a text placeholder and a help icon that will display useful information in a popover. https://i.sstatic.net/Zh0IK.png When typing into the input, the textbox should have a specif ...