Pierre
Pierre

Reputation: 99

complex grid layout which collapse into a single column on small screen

In the code below, I am trying to implement a grid made of 2 rows of 3 images in the bottom right corner only. The grid should not be bigger than the other quarters. In other words, I would like each quarter to be of the same size, but the bottom right one should have these 2 rows of 3 images.

My key objective is to have a method which collapses into a single column on small screens, with the images on top of each other. So on small screens, there shouldn't be any more grids, but just a column of images below the 3 quarters:

On normal screen:

| Hello World   |      2      |
|               |             |

|     3         | img img img |
|               | img img img |

On small screens:

Hello World
2
3
img
img
img
img
img
img

Here is my code, which does not work...

<!DOCTYPE html>
<html>
<head>
<style>
.box.md {
  grid-column: span 2;
  grid-row: span 2;
}
.box.lg {
  grid-column: span 2;
  grid-row: span 2;
}

.container {
  padding: 20px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  grid-auto-rows: 240px;
  grid-auto-flow: dense;
  grid-gap: 8px;
}


.box {
  background: yellow;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 48px;
  font-weight: bold;
}

.grid-container {
  display: grid;
  grid-template-columns: auto auto auto;
}

.item1 {
  grid-row-start: 1;
  grid-row-end: 3;
}

</style>
</head>
<body>

<h1>Test:</h1>


<div class="container">
  <div class="box md">
   <p> Hello World </p>
  </div>
  <div class="box md">2</div>
</div>
<div class="container">
  <div class="box md">3</div>

    <div class="container">
      <div class="row" >
        <div class="grid-container">
          <div class="item1">
            <a><img src="AI.jpg"></a>
          </div>
          <div class="item2">
            <a><img src="AI.jpg"></a>
          </div>
          <div class="item3">
            <a><img src="AI.jpg"></a>
          </div>
          <div class="item4">
            <a><img src="AI.jpg"></a>
          </div>
          <div class="item5">
            <a><img src="AI.jpg"></a>
          </div>
          <div class="item6">
            <a><img src="AI.jpg"></a>
          </div>
        </div>
      </div>
    </div>
 </div>

.box.md {
  grid-column: span 2;
  grid-row: span 2;
}

.box.lg {
  grid-column: span 2;
  grid-row: span 2;
}

.container {
  padding: 20px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  grid-auto-rows: 240px;
  grid-auto-flow: dense;
  grid-gap: 8px;
}

.box {
  background: yellow;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 48px;
  font-weight: bold;
}

.grid-container {
  display: grid;
  grid-template-columns: auto auto auto;
}

.item1 {
  grid-row-start: 1;
  grid-row-end: 3;
}
<h1>Test:</h1>


<div class="container">
  <div class="box md">
    <p> Hello World </p>
  </div>
  <div class="box md">2</div>
</div>
<div class="container">
  <div class="box md">3</div>

  <div class="container">
    <div class="row">
      <div class="grid-container">
        <div class="item1">
          <a><img src="AI.jpg"></a>
        </div>
        <div class="item2">
          <a><img src="AI.jpg"></a>
        </div>
        <div class="item3">
          <a><img src="AI.jpg"></a>
        </div>
        <div class="item4">
          <a><img src="AI.jpg"></a>
        </div>
        <div class="item5">
          <a><img src="AI.jpg"></a>
        </div>
        <div class="item6">
          <a><img src="AI.jpg"></a>
        </div>
      </div>
    </div>
  </div>
</div>

Could anyone help me solve this problem?

Kind regards,

-Pierre.

Upvotes: 2

Views: 2328

Answers (3)

G-Cyrillus
G-Cyrillus

Reputation: 105873

You coumd try something with calc() and clamp() to give a minmax() value to your columns dependind on a set px value to init calc(clamp()) ; and the unknown value that is 100vw. Playing around with those, it allows you to set a min and max-width while the calc() function updates with the viewport's width. It can give a failing value (if calculation turns out to be less than 0).

Once you understood how it worked, you can use your own values to reset your breakpoints without a mediaquerie but auto-fit.

Example setting every items as direct child of the container and using nested grid with different calc(clamp()) setting :

* {box-sizing:border-box;}
.container {
  display:grid;
  grid-template-columns: repeat(auto-fit,minmax(clamp(calc(((200px + 50vw ) * 2 ) - 100vw ), 40vw, 100% )  ,1fr));
  gap:1em;
  width:100%;
}
.box.md {
 max-width:100%;
  border:solid; 
  color:red;
  justify-content:space-around;
}
.box.md.img {
  width: 100%;
  grid-template-columns: repeat(auto-fit,minmax(calc(((140px + 25vw) * 2) - 50vw) ,1fr));
 
}
.box.md.img img {
  width:100%;
}
 
<h1>Test: grid layout</h1>
<div class="container">
  <div class="box md">
    <p> Hello World </p>
  </div>
  <div class="box md">2</div>
  <div class="box md">3</div>
  <div class="box md img container">
    <div class="item1 box img ">
      <a><img src="https://dummyimage.com/200x100/&text=AI.jpg"></a>
    </div>
    <div class="item2 box img">
      <a><img src="https://dummyimage.com/200x100/&text=AI.jpg"></a>
    </div>
    <div class="item3  box img">
      <a><img src="https://dummyimage.com/200x100/&text=AI.jpg"></a>
    </div>
    <div class="item4 box img">
      <a><img src="https://dummyimage.com/200x100/&text=AI.jpg"></a>
    </div>
    <div class="item5 box img">
      <a><img src="https://dummyimage.com/200x100/&text=AI.jpg"></a>
    </div>
    <div class="item6 box img">
      <a><img src="https://dummyimage.com/200x100/&text=AI.jpg"></a>
    </div>
  </div>
</div>

Pen to play with : https://codepen.io/gc-nomade/pen/PopPNoJ

Upvotes: 1

julien.giband
julien.giband

Reputation: 2619

Using flex with wrap to layout your main "grid". Using grid with auto-fit columns to layout the pictures.

I did that because I suppose you are after a fluid layout. It would be much easier to adapt to any screen using media queries...

You should try the snippet in full-screen and test with various windows sizes. Pictures layout can be suited to your requirements by changing the pixel size in minmax(240px, 1fr) for .grid-container.

.container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.container > * {
  flex: 1;
  min-width: 300px;
  min-height: 250px;
}

.box {
  background: yellow;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 48px;
  font-weight: bold;
}

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  grid-auto-rows: minmax(120px, max-content);
  gap: .5rem;
  padding: .5rem;
}

.grid-container a {
  display: flex;
  align-items: center;
  justify-content: center;
  max-height: 100%;
  max-width: 100%;
}

.grid-container img {
  display: block;
  max-width: 100%;
  max-height: 100%;
}
<h1>Test:</h1>


<div class="container">
  <div class="box md">
    <p> Hello World </p>
  </div>
  <div class="box md">2</div>
</div>
<div class="container">
  <div class="box md">3</div>

  <div class="container">
    <div class="row">
      <div class="grid-container">
        <div class="item1">
          <a><img src="https://picsum.photos/seed/pic1/300/200"></a>
        </div>
        <div class="item2">
          <a><img src="https://picsum.photos/seed/pic2/300/200"></a>
        </div>
        <div class="item3">
          <a><img src="https://picsum.photos/seed/pic3/300/200"></a>
        </div>
        <div class="item4">
          <a><img src="https://picsum.photos/seed/pic4/300/200"></a>
        </div>
        <div class="item5">
          <a><img src="https://picsum.photos/seed/pic5/300/200"></a>
        </div>
        <div class="item6">
          <a><img src="https://picsum.photos/seed/pic6/300/200"></a>
        </div>
      </div>
    </div>
  </div>
</div>

Upvotes: 1

Aravind Prabash
Aravind Prabash

Reputation: 443

See if this helps with the images grid

.container {
  display: grid;
  grid: auto auto/ 1fr 1fr 1fr;
}

@media (max-width: 450px) {
  .container {
    grid: auto / auto;
    grid-auto-flow: row;
  }
}
<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>

}

Upvotes: 0

Related Questions