skip to Main Content

I have the following html structure.

<div class="grandparent">
  <div class="parent">
    <div class="achild2">Child 2</div>
    <div class="achild2">Child 2</div>
    <div class="achild2">Child 2</div>
    <div class="achild2">Child 2</div>
    <div class="achild2">Child 2</div>
    <div class="achild2">Child 2</div>
  </div>
  <div class="achild1">Child 1</div>
</div>
.parent {
  display: grid;
  grid-template-columns: subgrid;
  grid-column: span 6; /* <-- span is not known prior to runtime. crux of the QUESTION */
  background-color: lightblue;
  padding: 10px;
}

.grandparent {
  display: grid;
  grid-template-columns: repeat(12, 1fr); /* 12 columns */
  gap: 10px;
  background-color: lightgreen;
  padding: 20px;
}

.achild1 {
  background-color: lightpink;
  height: 50px;
  padding: 20px;
}

.achild2 {
  background-color: lightyellow;
  height: 50px;
  border: 2px solid red;
  padding: 10px;
}

to achieve the following effect

Intended Effect

The problem is that the number of achild2 is dynamic and each of these may span variable number of columns. So a parent SPAN cannot be specified.

I can use display: contents on the parent and it works well. I was wondering how to achieve the same effect using SUBGRID

A codepen link to experiment with:
https://codepen.io/rsun2100/pen/GRebbvJ

2

Answers


  1. You can use a combination of CSS Grid and Flexbox.

    .grandparent {
      display: grid;
      grid-template-columns: repeat(12, 1fr);
      gap: 10px;
      background-color: lightgreen;
      padding: 20px;
    }
    
    .parent {
      display: flex;
      flex-wrap: wrap;
      background-color: lightblue;
      padding: 10px;
    }
    
    .achild1 {
      background-color: lightpink;
      height: 50px;
      padding: 20px;
      margin-bottom: 10px;
      /* Dynamically set the width of child1 */
      width: calc(50% - 5px); /* Subtracting margin and gap */
    }
    
    .achild2 {
      background-color: lightyellow;
      height: 50px;
      border: 2px solid red;
      padding: 10px;
      margin-right: 10px;
      margin-bottom: 10px;
      flex-grow: 1;
    }
    

    HTML:

    <div class="grandparent">
      <div class="parent">
        <div class="achild1">Child 1</div>
        <!-- Dynamic generation of achild2 elements -->
      </div>
      <!-- Separate .achild1 outside of .parent -->
      <div class="achild1">Child 1</div>
      <div class="achild2">Child 2</div>
      <div class="achild2">Child 2</div>
      <div class="achild2">Child 2</div>
      <div class="achild2">Child 2</div>
      <div class="achild2">Child 2</div>
      <div class="achild2">Child 2</div>
    </div>
    
    Login or Signup to reply.
  2. One posibility is to use the new :has selector, to target .parent based on how many children it has.

    You will need to set as many styles as posible number of elements. In the snippet, only the styles for 4 and 6 children are present:

    .parent {
      display: grid;
      grid-template-columns: subgrid;
      grid-column: span 1; 
      padding: 10px;
    }
    
    .parent:has(div:nth-child(4)) {
        grid-column: span 4; 
    }
    
    .parent:has(div:nth-child(6)) {
        grid-column: span 6; 
    }
    
    .grandparent {
      display: grid;
      grid-template-columns: repeat(12, 1fr); /* 12 columns */
      gap: 10px;
      background-color: lightgreen;
      padding: 20px;
    }
    
    .achild1 {
      background-color: lightpink;
      height: 50px;
      padding: 20px;
    }
    
    .achild2 {
      background-color: #41974e;
      height: 50px;
      border: 2px solid red;
      padding: 1px;
    }
    <div class="grandparent">
      <div class="parent">
        <div class="achild2">Child 2</div>
        <div class="achild2">Child 2</div>
        <div class="achild2">Child 2</div>
        <div class="achild2">Child 2</div>
        <div class="achild2">Child 2</div>
        <div class="achild2">Child 2</div>
      </div>
      <div class="achild1">Child 1</div>
    </div>
    <div class="grandparent">
      <div class="parent">
        <div class="achild2">Child 2</div>
        <div class="achild2">Child 2</div>
        <div class="achild2">Child 2</div>
        <div class="achild2">Child 2</div>
      </div>
      <div class="achild1">Child 1</div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search