Showcasing pictures with a prominent large image accompanied by two smaller ones on the right side

In my use of Material-ui-next, I am attempting to create images in a specific layout.

   ------  ---------
   |    |  |   | 2 |
   |    |  | 1 |---|
   |    |  |   | 3 |
   ------  ---------

I have encountered some unusual issues.

1 - 3 appears below 1

2 - The images do not occupy the entire space (only half the content space is utilized when highlighted)

3 - Sometimes, I get a display like the one shown below:

   ------  ---------
   |    |  |   | 2 |
   |    |  | 1 |---|
   |    |  |   | 3 |
   |    |  ---------
   ------
In this case, the components on the right side do not extend all the way down

For more information, you can visit the material-ui-next GridList documentation through this link. In the "Advanced Grid List" section, you will see a large image with several smaller ones below. My objective is to flip that horizontally.

I have tried the following approaches:

  <GridList cols={4} rows={2}>
  {
    media.map((file, i) => (
      <GridListTile style={{ display: 'flex', flexFlow: 'wrap row' }} cellHeight={200} key={i} cols={i===0 ? 3 : 1} rows={i===0 ? 2 : 1}>
        <img src={file.url} />
      </GridListTile>
    ))
  }
  </GridList>

The above resulted in 3 appearing below 2

  <GridList cols={2} row={2} className={classes.gridList}>
    {
      <GridListTile cellHeight={200} key={1} cols={2} rows={2}>
        <img src={file.url} />
      </GridListTile>
    }
    </GridList>
  </Grid>

  <Grid item xs={12} md={3} style={{padding: '14px', paddingLeft: 0}}>
    <Typography style={{ visibility: 'hidden' }}>a</Typography>
    <GridList>
    {
      user && user.Media &&
      <GridListTile cellHeight={200} style={{paddingBottom: 0}}>
        <img src={file.url} />
      </GridListTile>
    }
    </GridList>
    <GridList>
    {
      user && user.Media &&
      <GridListTile cellHeight={200} key={1} cols={1}>
        <img src={file.url} />
      </GridListTile>
    }
    </GridList>

This solves issue 1 but does not address issues 2 and 3.

I also attempted using native flexbox, but every time I did, the intended larger image shrunk to match the sizes of the others.

Below is the CSS code I used for flexbox (although minimal).

gridContainer: {
    display: 'flex',
    flexFlow: 'row',
    justifyContent: 'space-around',
    margin: '3rem 0'
},

EDIT - NEW

The following approach has been more successful than previous attempts. The two small side images adjust size properly based on screen size, while the larger central image remains fixed.

New CSS

gridList: {
    transform: 'translateZ(0)',
    display: 'flex',
    justifyContent: 'left',
    alignItems: 'left',
    overflow: 'hidden',
    '& img': {
      flexShrink: 1,
      minWidth: '200%',
      minHeight: '200%'
    }
  },
  gridListSmall: {
    transform: 'translateZ(0)',
    display: 'flex',
    justifyContent: 'left',
    alignItems: 'left',
    overflow: 'hidden',
    '& img': {
      flexShrink: 0,
      minWidth: '100%',
      minHeight: '100%'
    }
  },

New HTML/JSX

       <div cols={2} row={2} className={classes.gridList}>
        {
          <div cellHeight={200} key={1} cols={2} rows={2}>
            <img src={file.url} />
          </div>
        }
        </div>
      </Grid>

      <Grid item xs={12} md={3} style={{padding: '14px', paddingLeft: 0}}>
        <Typography style={{ visibility: 'hidden' }}>a</Typography>
        <div>
        {
          user && user.Media &&
          <div cellHeight={200} style={{paddingBottom: 0}}>
            <img src={file.url} />
          </div>
        }
        </div>
        <div>
        {
          user && user.Media &&
          <div cellHeight={200} key={1} cols={1}>
            <img src={file.url} />
          </div>
        }
        </div>

Answer №1

Make sure to reference the source you mentioned in the example at Advanced Grid List

Now, pay attention to this specific line:

<GridListTile 
  key={tile.img}
  cols={tile.featured ? 2 : 1}
  rows= {tile.featured ? 2 : 1}>

In this setup, all featured images occupy 2 columns by 2 rows.

If you want your featured images to be 1 column by 2 rows, simply change cols={tile.featured ? 2: 1} to cols={tile.cols || 1}.

You have the ability to specify the number of columns in your Grid List:

<GridList cols={2}>

Add the option to set the cell height as well:

<GridList cellHeight={160}>

Furthermore, feel free to modify the properties of the entire grid layout:

const styles = theme => ({
  gridList: {
    width: 500,
    height: 450,
  }
});

A more flexible approach would be setting rows to be rows={tile.rows || 1}.

From now on, you will have control over how many columns and rows each image can occupy.

const tileData = [
{
    img: image,
    title: 'Image' // occupies 1x1 space
},
{
    img: image,
    title: 'Image',
    rows: 2 // takes up 2 rows and 1 column
},
{
    img: image,
    title: 'Image',
    cols: 2 // takes up 1 row and 2 columns
},
{
    img: image,
    title: 'Image',
    rows: 2,
    cols: 2 // occupies 2 rows & 2 columns
},

RESPONSE TO YOUR LATEST EDIT

It seems like there is some confusion with how your elements are arranged. The proper structure for the grid should be as follows:

  • Grid-container = a div with classes.root
    • GridList = <GridList> with classes.gridList and cellHeight prop
      • GridListTile = <GridListTile> with cols and rows
        • Your Image
        • Additional content
      • GridListTile = <GridListTile> with cols and rows
        • Your Image
        • Additional content

<GridListTile> determines the necessary size for your image and is the only one that needs an image. It can be configured as 1x1, 1x2, 2x1...

In your code snippet, I see div with cols and rows, div with cellHeight; the structure appears incomplete (as the entire tree isn't visible), making it difficult to interpret.


Queries

  • Are you utilizing the component referred to in your example?
  • Will you require more than those 3 images?

Suggestion

The referenced component does not ensure the exact order of images; they may be rearranged to fill all cells.

Answer №2

For this solution, I took inspiration from Valentin's question and the comments provided. Instead of using GridList, I opted for a Flexbox approach.

html/jsx

            <Grid item xs={12} md={8} style={{paddingRight: 0}}>
              <Typography type="body2">Media</Typography>

                <div>
                {
                  <div className={classes.gridListContainer}>
                    <div className={classes.gridList} style={{width: '70%'}}>
                      <img
                        src={media.url[0]}
                        alt={media[0].name}
                      />
                    </div>
                    <div className={classes.gridListSmall} style={{width: '30%'}}>
                      <img
                        src={media.url[1]}
                        alt={media[1].name}
                      />
                      <img
                        src={media.url[2]}
                        alt={media[2].name}
                      />
                    </div>
                  </div>
                }
                </div>

css

  gridListContainer: {
    display: 'flex',
    flexFlow: 'row'
  },
  gridList: {
    transform: 'translateZ(0)',
    alignItems: 'stretch',
    overflow: 'hidden',
    '& img': {
      width: '100%',
      height: '100%',
    }
  },
  gridListSmall: {
    transform: 'translateZ(0)',
    // flexFlow: 'column',
    justifyContent: 'left',
    alignItems: 'stretch',
    overflow: 'hidden',
    '& img': {
      flexShrink: 0,
      height: '50%',
      verticalAlign: 'middle'
    },
    '& div img': {
      flexShrink: 0,
      height: '50%',
      verticalAlign: 'middle',
      content: 'words'
    }
  }

This configuration achieves the desired layout, depicted below. It is designed to accommodate only three images, hence the direct indexing.

   ---------
   |   | 2 |
   | 1 |---|
   |   | 3 |
   ---------

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

Ways to verify if an ajax function is currently occupied by a previous request

Is there a way to determine if an ajax function is occupied by a prior call? What measures can be taken to avoid invoking an ajax function while it is still processing a previous request with a readyState != 4 status? ...

Sending information from ngRoute resolve to the controller

I am currently working on an application that utilizes ngRoute to create a Single Page Application. One of the requirements is to ensure that the view is not loaded until the data has been successfully fetched from the database. While I have managed to ach ...

The browser is capable of detecting multiple key presses using JavaScript

I'm attempting to trigger an action when certain keys are pressed simultaneously. The keys I need to detect are bltzr, but my browser only registers bltz without the final r. I've tried this on both Windows and OSX, but still can't capture ...

Implementing a time to live feature in socket.io can be accomplished by setting a

After extensive searching online, I haven't been able to find any resources on how to implement the 'time-to-live' function using Socket.io. In my project, I am utilizing Node.js with express. The functionality of the mentioned time-to-live ...

Deleting items from an array in ReactJS

When retrieving a list of users from AWS Cognito, everything works flawlessly. However, the task of iterating over this array and removing users that do not match a specific Client ID is where I'm facing difficulties. What am I doing wrong in this sc ...

What is the best way to horizontally align an element within a Material UI Grid item?

How do I align elements in the center of a Material UI Grid item? Check out this code snippet from my React project: <Grid container> <Grid item xs={4}> // Other content goes here </Grid> <Grid item xs={4}> // How can ...

What is the best way to display a div beneath the highlighted text within a textarea field?

I have encountered a situation where I want to display a div (like a popup) when text is selected in a text area. However, when using mouse-down for this action, the position of the div sometimes does not align directly below the selected text. Below is t ...

Customizable Button component featuring background image options

Need help with creating a versatile Button component in React that can easily accommodate different sizes and shapes of background images? This is how my current implementation looks like - Button.js const Button = ({ url }) => { const inl ...

The authentication callback function fails to execute within Auth0 Lock

I'm having an issue with logging into my application using Auth0. I have integrated Auth0 Lock version 10.3.0 through a CDN link in my project and am utilizing it as shown below: let options = { disableSignupAction: true, rememberLastLogin: f ...

Alignment of Bootstrap thumbnails in a horizontal layout

After adding the thumbnail class to my thumbnails div, I noticed that some of the thumbnails were smaller in size than others. Wanting them all to have the same height, I decided to give each thumbnail a fixed height of 210px. However, this caused the sm ...

Changing the border color in a CSS pseudo-class does not take effect upon clicking

Is it possible to change the border color of an input field when clicked using CSS? I attempted to use the pseudo-class focus for this purpose, but encountered some issues. It seems to only work on select elements and not on elements like text inputs. . ...

Retrieve both the name and id as values in an angular select dropdown

<select (change)="select($event.target.value)" [ngModel]="gen" class="border border-gray-200 bg-white h-10 pl-6 pr-40 rounded-lg text-sm focus:outline-none appearance-none block cursor-pointer" id="gend ...

Animating links with multi-line effects on :before.orEnhancing

As per the given query, I have a code snippet Is there any way to apply this effect to multiple lines of text instead of just one line? Currently, the effect only appears on one of two text lines (as shown in the example). :root { --00a3a3: #00a3a3; ...

Error: The JSONP request encountered an unexpected token, causing a SyntaxError

Asking for data using AJAX: $.getJSON('https://www.cryptocompare.com/api/data/coinsnapshot/?fsym=BTC&tsym=USD&callback=?', function(result) { console.log(result); }); Encountering an error: "Uncaught SyntaxError: Unexpected token :" ...

What are the primary purposes of the site.webmanifest file?

As I navigate through an HTML Boilerplate, I come across a file named site.webmanifest. Despite my efforts to research its purpose online, I am still unclear about its significance. Could this file be essential for website development? What are the specif ...

Prevent event bubbling when clicking

I have a code snippet that I'm struggling with. <p>haha</p> <button class="btn btn-light" onclick="nextSibling.classList.toggle('d-none');"> <i class="fa fa-ellipsis-h"></i> </button> <div class= ...

Obtain the specific key's value from a new Map state

In my code, I've defined a variable called checkedItems as a new Map(); When I try to console.log(checkedItem), the output is as follows: Map(3) {"1" => true, "1.5" => true, "2" => false} Is there a way ...

What is the best method for integrating addEventListener with Javascript functions located in a different file?

I currently have document.addEventListener('DOMContentLoaded', functionName); which uses the function below: function functionName() { $.ajax({ type: 'GET', url: '/populatePage', success: function(data) { ...

Adjusting the format of a JavaScript object

Looking at the object below: {A: 52, B: 33} I want to transform it into this format: ["A", 52], ["B", 33] Any recommendations on how to achieve this conversion? ...

Position child divs at the center of the parent div

I am struggling to center 3 child divs inside a parent div that must remain at a width of 100%. Can someone help me figure out how to achieve this? .parent { width: 100%; border: 1px solid blue; } .child { float: left; borde ...