skip to Main Content

I have this layout:

the layouts to follow

I have a div where elements are added and removed dynamically. Is there a way to make them fit into the pattern shown in the image? There will never be more than 5 elements in the div at one time.

2

Answers


  1. If you have a known maximum number of child elements you can specify positioning in a CSS-Grid based on the number of each specific child and how many it is from the end.

    For instance 2nd of 3 is .child:is(:nth-child(2)):is(:nth-last-child(2))

    ..and so on. This does lead to a number of selectors for each child, for example in a 5 child box – item 2 needs 4 rules, items 3 needs 3, 4 needs 2 and 5 only one.

    Here I have stuck to a 4 child example but the pattern remains the same.

    body {
      display: flex;
      gap: .25em;
    }
    
    .container {
      height: 55vh;
      flex: 1;
      margin-right: .25em;
      outline: 2px solid red;
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      grid-template-rows: repeat(4, 1fr);
      padding: .25em;
      gap: .25em;
    }
    
    .child {
      outline: 1px solid green;
      background: lightblue;
    }
    
    .child:first-child {
      grid-row: 1 / span 4;
      grid-column: 1 / span 4;
    }
    
    
    /* 1st child */
    
    .child:nth-child(1):is(:nth-last-child(2)) {
      grid-row: 1 / span 4;
      grid-column: 1 / span 2;
    }
    
    .child:nth-child(1):is(:nth-last-child(4)),
    .child:nth-child(1):is(:nth-last-child(3)) {
      grid-row: 1 / span 4;
      grid-column: 1 / span 2;
    }
    
    
    /* 2nd child */
    
    .child:is(:nth-child(2)):is(:nth-last-child(1)) {
      grid-row: 1 / span 4;
      grid-column: 3 / span 4;
    }
    
    .child:is(:nth-child(2)):is(:nth-last-child(2)) {
      grid-row: 1 / span 2;
      grid-column: 3 / span 4;
    }
    
    .child:is(:nth-child(2)):is(:nth-last-child(3)) {
      grid-row: 1 / span 2;
      grid-column: 3 / span 2;
    }
    
    
    /* 3rd child */
    
    .child:is(:nth-child(3)):is(:nth-last-child(1)) {
      grid-row: 3 / span 2;
      grid-column: 3 / span 4;
    }
    
    .child:is(:nth-child(3)):is(:nth-last-child(2)) {
      grid-row: 3 / span 2;
      grid-column: 3 / span 1;
    }
    
    
    /* 4th child */
    
    .child:is(:nth-child(4)):is(:nth-last-child(1)) {
      grid-row: 3 / span 2;
      grid-column: 4 / span 1;
    }
    
    
    /* 5th child */
    <div class="container">
      <div class="child">1</div>
    </div>
    <div class="container">
      <div class="child">1</div>
      <div class="child">2</div>
    </div>
    <div class="container">
      <div class="child">1</div>
      <div class="child">2</div>
      <div class="child">3</div>
    </div>
    <div class="container">
      <div class="child">1</div>
      <div class="child">2</div>
      <div class="child">3</div>
      <div class="child">4</div>
    </div>
    Login or Signup to reply.
  2. Actually you don’t need too much code

    .container {
      width: 200px;
      height: 150px;
      margin: 5px;
      display: inline-grid; /* OR grid if you want*/
      grid-auto-flow: column; /* column flow */
      /* equal rows and columns */
      grid-auto-columns: 1fr;
      grid-auto-rows: 1fr;
      /**/
      gap: 5px;
    }
    
    .child {
      outline: 1px solid green;
      background: lightblue;
    }
    
    .container :nth-child(1):nth-last-child(n + 3) {
      grid-row: span 2;
    }
    .container :nth-child(2):nth-last-child(3),
    .container :nth-child(1):nth-last-child(n + 4){
      grid-column: span 2;
    }
    <div class="container">
      <div class="child">1</div>
    </div>
    <div class="container">
      <div class="child">1</div>
      <div class="child">2</div>
    </div>
    <div class="container">
      <div class="child">1</div>
      <div class="child">2</div>
      <div class="child">3</div>
    </div>
    <div class="container">
      <div class="child">1</div>
      <div class="child">2</div>
      <div class="child">3</div>
      <div class="child">4</div>
    </div>
    <div class="container">
      <div class="child">1</div>
      <div class="child">2</div>
      <div class="child">3</div>
      <div class="child">4</div>
      <div class="child">5</div>
    </div>

    Related article to get more detail about the technique I am using above: https://css-tricks.com/exploring-css-grids-implicit-grid-and-auto-placement-powers/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search