What is the best approach for scaling @material-ui Skeleton in a grid row with variable heights?

I am working on creating a grid of Avatar images with a transition state where I want to show a skeleton representation of the image. To achieve this, I am using @material-ui/lab/Skeleton.

The issue I'm facing is that since my images are set to autoscale within a grid using height: auto, width: 100%, and the height/length of the content displayed below the image varies, there is no fixed height value that I can pass to the skeleton component.

You can observe the problem when you resize the width of the sandbox screen. The height of the grid item increases, causing the circular skeleton to start deforming into an oval shape.

Is there a solution that can give me behavior similar to setting the image's height: auto, width: 100%?

You can view the full code I have so far below and in the sandbox here: https://codesandbox.io/s/skeleton-scaling-y00cd.

// Full revised source code goes here. Keep all the contents as it is.

Answer №1

The solution provided below is based on the information found in this article: https://css-tricks.com/aspect-ratio-boxes/#article-header-id-3

Essentially, the approach involves using percentage-based padding-top to create a box with a specific aspect ratio, such as a square. When specifying padding-top or padding-bottom in percentages, it is crucial to remember that it is based on width, resulting in a height equivalent to the specified width.

The relevant CSS/JS snippet is as follows:

  avatarSkeletonContainer: {
    height: 0,
    overflow: "hidden",
    paddingTop: "100%",
    position: "relative"
  },
  avatarLoader: {
    position: "absolute",
    top: 0,
    left: 0,
    width: "100%",
    height: "100%"
  },

This code segment is then utilized in the following manner:

<Grid container item xs={3} spacing={0} direction="column">
          <div className={classes.avatarSkeletonContainer}>
            <Skeleton variant="circle" className={classes.avatarLoader} />
          </div>
          <Skeleton className={clsx(classes.titleLoader, classes.title)} />
          <Skeleton className={clsx(classes.contentLoader, classes.content)} />
        </Grid>

Here's my modified version of your sandbox code:

// The complete code can be found here
// Link: https://codesandbox.io/s/skeleton-scaling-ndzs7?fontsize=14&hidenavigation=1&theme=dark
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Avatar from "@material-ui/core/Avatar";
import Skeleton from "@material-ui/lab/Skeleton";
import Typography from "@material-ui/core/Typography";
import clsx from "clsx";
import Grid from "@material-ui/core/Grid";

const useStyles = makeStyles(theme => ({
  // Styles and classes definition go here
}));

export default function ImageAvatars() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      // Nested grid structure and components are implemented here
    </div>
  );
}

If you need further assistance or clarification, feel free to ask!

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

What ways can I leverage JavaScript to convert a provided array into multiple different arrays?

I am in need of a function that meets the following criteria: Given the dimensions of an array, return all possible combination arrays based on the given numbers. The length of the given array should be equal to the length of the array returned. The size ...

Verifying credentials using Chromium pop-up window with Playwright

In my current project, I am using Playwright to automate the configuration of multiple devices. However, I have encountered a challenge with certain models that require authentication through a popup dialog box in Chrome. https://i.stack.imgur.com/jgnYM.p ...

Most effective method to retrieve yesterday's data

Currently, I'm working on a requirement and I need to validate the logic that I've implemented. Can someone help me with this? The task at hand is to calculate the 1 month, 3 month, and 6 month return percentages of a stock price from the curren ...

What is the best way to prevent labels from floating to the top when in focus?

How can I prevent the label from floating on top when focusing on a date picker using Material UI? I have tried several methods but nothing seems to work. I attempted using InputLabelProps={{ shrink: false }} but it did not resolve the issue. Here is a li ...

When clicking on an item in the wishlist, only the text for that specific item should change,

Hi all, I'm in need of some assistance. I have successfully created a wishlist toggle where clicking on the heart icon changes it from an outline to solid. However, my issue lies in changing the tooltip text from "add to wish list" to "added to wish l ...

Learn how to create a logarithmic scale graph using CanvasJS by fetching data from an AJAX call

window.onload = function() { var dataPoints = []; // fetching the json data from api via AJAX call. var X = []; var Y = []; var data = []; function loadJSON(callback) { var xobj = new XMLHttpRequest(); xobj.overrideMimeType("applicatio ...

Get hands-on experience with API Gateway Tutorial by running it on

After successfully deploying the app from the tutorial found here: https://github.com/awslabs/aws-api-gateway-developer-portal, I am now looking to heavily customize the client or create a new one. Can development be done locally and then connected to AW ...

Enhance the dropdown menu by incorporating a caret icon

Click here for the image, I am trying to incorporate the Bootstrap caret class into my select dropdown menu. .select_menu{ font-size: 12px; outline: none; border: thin #ddd solid; -webkit-appearance: none; -moz-appearance: none; appearance: ...

To enhance user experience, it is recommended to reload the page once

Hello, I'm looking for a way to automatically refresh the page after submitting an AJAX form. Currently, I have an onClick function that seems to refresh the page, but I still need to press F5 to see the changes I've made. Here's the JavaSc ...

Once logged out in Vue Router, the main app template will briefly display along with the login component

After clicking the logout button, I am experiencing an issue where my main UI remains visible for a few seconds before transitioning to a blank page and displaying the login form component. This behavior is occurring within the setup of my App.vue file: & ...

Query about Javascript/Node/JSON - why isn't this functioning properly?

I thought I had a good grasp on what I was doing until the process started getting jumbled. My code is being executed through Node, not a web browser. For some reason, it jumps to the prompt at the end of the while loop first and I'm not sure why tha ...

Incorporate Thymeleaf's HTML using the powerful JavaScript framework, jQuery

I am facing an issue where the Thymeleaf rendered HTML code is not being displayed by the Browser when I try to insert it using JavaScript. $('<span [[$ th:text#{some.property.key}]] id="counter" class="UI-modern"> </ ...

Can information be saved to a JSON file without using a server-side language?

Previously, I've come across questions where the recommended solution involves using a server-side language. However, since I don't have knowledge of a server-side language yet, I was curious to know if it's possible to achieve this with my ...

Deleting specialized object using useEffect hook

There's a simple vanilla JS component that should be triggered when an element is added to the DOM (componentDidMount) and destroyed when removed. Here's an example of such a component: class TestComponent { interval?: number; constructor() ...

Extract table information from MuiDataTable

I am having trouble retrieving the row data from MuiDataTable. When I try to set the index from the onRowSelectionChange function to a state, it causes my checkbox animation to stop working. Below is how my options are currently configured: const option ...

Upon calling the createModalAddPost() function, a single window is triggered to open

Hey there, I'm having a JavaScript question. So, I have a panel that opens a window, and it works fine. But the issue arises when I close the window and try to open it again - it doesn't work. I have to reload the page every time in order to open ...

Have you ever wondered why a listener on the 'data' event interprets two separate requests as one, unless a timeout is added?

It seems that there is a tricky issue with node where it combines 2 different requests into one unless a timeout is added. In the code snippet below, if we write 'one' and 'two' to the server and push the result to an array, node interp ...

Designating a certain function to a designated button

On my page, I have three different forms with submit buttons in each. There is a code that is supposed to change the value of a button in a specific form when clicked. However, whenever I click on any submit button, all the values in the buttons of the v ...

Tips for safely storing JWT tokens in a react/next.js app:

After a valid user login following proper registration through REST API, I am looking for the best way to store the JWT token that is generated. I have researched various methods of storing JWT on the client side, including local storage, session storage, ...

Steps to automatically launch a URL upon button click and executing PHP script

I have a Joomla website and I am facing a challenge in automatically triggering a modal window that displays a web page based on parameters passed through the URL. The scenario on my website is as follows: A trip leader selects a trip and schedules it by ...