When applying the 'aspect-ratio: 1' property to create square cells, the 3 by 3 CSS Grid exceeds the boundaries of the container with overflowing squares

After countless attempts and hours of tweaking, my goal remains to create a 3x3 grid composed of squares that adjust to fit the content inside. I also want each square to have a corner number, with text content centered both vertically and horizontally. Despite trying various methods, I've only been able to achieve a compromise between square cells and potential overflow outside the container. Setting height and width values are deliberately avoided to allow for dynamic sizing of the cells and grid.

The first snippet displays a grid with square cells and corner numbers. However, the issue of content overflowing persists. The grid container must use position:relative due to a label positioned next to it using 'absolute', which isn't included here.

In the second snippet, the only change made was removing 'aspect-ratio: 1'. This adjustment prevents the cells from overflowing but sacrifices the square shape.

I'm searching for a solution that maintains square grid cells while accommodating varying content sizes without exceeding the boundaries. Is there a way to achieve this?

.basic-text {
     font-size: larger;
     font-family: Arial, Helvetica, sans-serif;
}
.fancy-card {
     border: 3px solid grey;
     border-radius: 15px;
     margin: 1em;
}
#output-card {
     display: inline-block;
     vertical-align: top;
}
#output-grid-container {
     margin: 1em;
     padding: 2em;
     position: relative;
     background-color: white;
     display: grid;
     grid-template-columns: repeat(3, 1fr);
     grid-template-rows: repeat(3, 1fr);
     gap: 20px;
}
.grid-square {
     position: relative;
     border: 2px solid grey;
     border-radius: 3px;
     padding: 1em;
     aspect-ratio: 1;
     display: flex;
     justify-content: center; /* Center horizontally */
     align-items: center; /* Center vertically */
     text-align: center;
     line-height: 150%;
}
p {
     white-space: pre;
     text-wrap: wrap;
}
.corner-rating-number {
     position: absolute;
     bottom: 0.1em;
     left: 0.3em;
     margin: 0;
     padding: 0;
}
select {
     height: 2em;
     width: 10em;
     border-radius: 0.5em;
}
<div class="fancy-card" id="output-card">
  <div id="output-grid-container">
    <div class="grid-square">
      <span class="corner-rating-number basic-text">7</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">8</span>
      <p class="basic-text">Pink</p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">9</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">4</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">5</span>
      <p class="basic-text">Violet</p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">6</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">1</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">2</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">3</span>
      <p class="basic-text">Blue<br><br>Green</p>
    </div>
  </div>
</div>

Answer №1

To address this issue, I implemented a solution by maintaining the aspect-ratio: 1 on the squares and observing their resulting size. Subsequently, I explicitly set the column width to match the current dimensions of the squares. This specific sizing of the squares allows the outer div to adapt accordingly to the inner dimensions. The pertinent code snippet can be found below.

If there is a need for reactive updates on the page, you should follow these steps: upon updating data for the grid, set the flag squareDimensionsNeedUpdate to true. Before the DOM update, if the flag is true, revert the grid-template-columns back to repeat(3, 1fr) in order for the squares to adjust to the new content. After the update, if the flag is still true, reset the flag to false and obtain and set the grid column width as required.

let outputGridContainer = document.getElementById('output-grid-container');
let firstGridSquare = outputGridContainer.querySelector('.grid-square');
let firstGridSquareDimensions = firstGridSquare.getBoundingClientRect();
let firstGridSquareWidth = firstGridSquareDimensions.width;
outputGridContainer.style.gridTemplateColumns = `repeat(3, ${firstGridSquareWidth}px)`;
.basic-text {
     font-size: larger;
     font-family: Arial, Helvetica, sans-serif;
}
.fancy-card {
     border: 3px solid grey;
     border-radius: 15px;
     margin: 1em;
}
#output-card {
     display: inline-block;
     vertical-align: top;
}
#output-grid-container {
     margin: 1em;
     padding: 2em;
     position: relative;
     background-color: white;
     display: grid;
     grid-template-columns: repeat(3, 1fr);
     grid-template-rows: repeat(3, 1fr);
     gap: 20px;
}
.grid-square {
     position: relative;
     border: 2px solid grey;
     border-radius: 3px;
     padding: 1em;
     aspect-ratio: 1;
     display: flex;
     justify-content: center;
    /* Center horizontally */
     align-items: center;
    /* Center vertically */
     text-align: center;
     line-height: 150%;
}
p {
     white-space: pre;
     text-wrap: wrap;
}
.corner-rating-number {
     position: absolute;
     bottom: 0.1em;
     left: 0.3em;
     margin: 0;
     padding: 0;
}
select {
     height: 2em;
     width: 10em;
     border-radius: 0.5em;
}
<div class="fancy-card" id="output-card">
  <div id="output-grid-container">
    <div class="grid-square">
      <span class="corner-rating-number basic-text">7</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">8</span>
      <p class="basic-text">Pink</p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">9</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">4</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">5</span>
      <p class="basic-text">Violet</p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">6</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">1</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">2</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">3</span>
      <p class="basic-text">Blue<br><br>Green</p>
    </div>
  </div>
</div>

Answer №2

Is there a way to create square grid cells that adjust to the content's width and height without overflowing? The issue lies in the fact that the aspect-ratio is based on the width-to-height ratio, making it challenging to achieve perfect squares when the height exceeds the width. To address this, ensure that elements with the class .grid-square do not stretch by adding either overflow: hidden; or min-width: 0; minimum height: 0;.

.basic-text {
     font-size: larger;
     font-family: Arial, Helvetica, sans-serif;
}
.fancy-card {
     border: 3px solid grey;
     border-radius: 15px;
     margin: 1em;
}
#output-card {
     display: inline-block;
     vertical-align: top;
}
#output-grid-container {
     margin: 1em;
     padding: 2em;
     position: relative;
     background-color: white;
     display: grid;
     grid-template-columns: repeat(3, 1fr);
     grid-template-rows: repeat(3, 1fr);
     gap: 20px;
}
.grid-square {
     position: relative;
     border: 2px solid grey;
     border-radius: 3px;
     padding: 1em;
     aspect-ratio: 1;
     display: flex;
     justify-content: center;
     align-items: center;
     text-align: center;
     line-height: 150%;
     
     overflow: hidden;
}
p {
     white-space: pre;
     text-wrap: wrap;
}
.corner-rating-number {
     position: absolute;
     bottom: 0.1em;
     left: 0.3em;
     margin: 0;
     padding: 0;
}
select {
     height: 2em;
     width: 10em;
     border-radius: 0.5em;
}
<div class="fancy-card" id="output-card">
  <div id="output-grid-container">
    <div class="grid-square">
      <span class="corner-rating-number basic-text">7</span>
      <p class="basic-text"></p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">8</span>
      <p class="basic-text">Pink</p>
    </div>
    <div class="grid-square">
      <span class="corner-rating-number basic-text">9</span>
      <p class="basic-text"></p>
    </div>
    <!-- Additional grid-square elements -->
  </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

Missing value: Attempted to access properties of an undefined variable

I've been encountering an issue while trying to transfer data from one component to another using a service. The error message that I keep running into is: ERROR TypeError: Cannot read properties of undefined (reading 'statistics') at St ...

Why is there space between two divs if there are no `margin`, `padding`, or `border` properties set?

Using vue.js, I created a page called index.vue which includes the components header.vue and home.vue: The code for index.vue: <template> <div class="index"> <i-header></i-header> <router-view></router-view> ...

Generate random positions for several divs using jQuery

Here is my code snippet: http://jsfiddle.net/BREvn/2/ (it's functional). However, I want each div to have a unique position coordinate. Currently, the script moves others to the place of the first one. How can I resolve this issue? I attempted using a ...

"Incorporating JavaScript into Website, Navigating Browser Discrepan

Upon designing a simple webpage that requires minimal JavaScript functionality, I encountered varying behaviors across different browsers depending on the placement of the <script> tag. In Chrome (65) and Firefox (59), the position of the <script ...

Guide on Updating the ColModel Dynamically in JAVASCRIPT/HTML using clearGridData, setGridParam, and reloadGrid Functions

I am trying to figure out how to dynamically change the colmodel of my grid using a function that is called by a SELECT. The reason for this is because my grid has different periods and needs to display either cost or tons based on user selection. Below i ...

Click here to access the identical page

Longtime follower of stackoverflow but only my second time posting a question. Here is the code I am currently working on: echo "<td><a href = 'http://localhost/map/index.php' value='$id' >Delete</a></td>"; ...

The functionality of the Angular ng-bind-html directive may be unreliable in specific scenarios

I've exhausted all the solutions found on stack overflow but still haven't found a solution. Using angular 1.4.4 and ng-repeat directive, I am attempting to display a HTML comment inside a table row. A sample comment looks like 'Test commen ...

First-character styling not applying to ID in CSS

My CSS :first-letter selector is effective on all p elements, however when applied to a span with the id #fletter, it doesn't seem to work... #fletter span:first-letter { font-weight: 600; font-size: 25px; } <span id="fletter"> The : ...

I want to perfectly center the text horizontally within a table while still aligning it to the left [Using HTML and CSS]

I have a few tables displayed on my website and I am seeking ways to enhance their appearance. Here is how my table currently appears (http://prntscr.com/gpa4w6) I am aiming for this desired look (http://prntscr.com/gpa52q) In the image above, you can n ...

Customize the background color of Material UI input components on standard labels

Currently using react material ui and interested in changing the background color of a standard input. The issue arises when the label is overridden by the background color when the input is not selected. Input selected Input not selected This is my att ...

Tips for arranging a menu horizontally with buttons in CSS

I am currently working with a dropdown menu that I coded using CSS, similar to the one shown at . My issue is that I have 4 menu items and I want the total width of the parent div to be divided equally among each item, regardless of the resolution. Curre ...

Communicating between iframes and parent elements via events

I'm trying to trigger an event in my iframe using the following code: $('body').trigger('my_event'); However, I want to bind this event on my main page that contains the iframe like this: $('iframe').find('body&ap ...

Keeping the header fixed on a sticky div (tocbot)

While working on my website, I decided to implement a Table of Contents section using tocbot. However, I encountered an issue where the Title I added above the table doesn't stay fixed when scrolling. https://i.stack.imgur.com/vCm1K.gif Here's ...

Is HTML5 data-target used for loading pages?

Currently, I am working with some HTML5 code: <li class="tile google" data-target-activation="click" data-target="loading"> <div> <a href="#">Search Google</a> <h2>Google</h2> </div> </li> Upon ...

The CSS styles are not being applied correctly in the HTML document

I have this snippet in my .css file: .attachment-label { font-size: 10px; font-style: italic; color: rgba(0,0,0,.5); } When I try to use it in my HTML like this: <div class="card-body"> <span class=" ...

apply jQuery to add a class to the parent element when clicked

I am currently facing an issue with my code. It was working fine in jsFiddle, however, when I try to use it outside of fiddle, I am getting errors and it's not working properly. $('.down-photo').click(function() { $(this).parent(&apos ...

Navigate post Ajax call

When I make an unauthenticated GET request using AJAX, my server is supposed to redirect my application. However, when I receive the redirect (a 303 with /login.html as the location), the response tab in the Firebug console shows me the full HTML of the lo ...

Using Javascript's OnChange event to dynamically update data

Attempting to achieve a seemingly straightforward task, but encountering obstacles. The goal is to trigger a JavaScript onChange command and instantly update a radar chart when a numerical value in a form is altered. While the initial values are successful ...

Guide on incorporating the WHERE clause into an insert statement in PHP version 5.1.6

What is the correct way to incorporate a where clause into an insert statement in PHP 5.1.6? In my code, I have declared a global variable $module and I am trying to use a where clause to refine my search results. Specifically, I want to include where mod ...

Set the height of the div to be the full height of the page when designing for responsiveness

For my responsive design, I am looking to have a footer that sticks to the bottom of the page while allowing the content to fill up the remaining space. You can view an example here: http://jsfiddle.net/rzjfhggu/1/ In this example, the header has a fixed ...