Search code examples
htmlcssflexboxcss-grid

Equal width columns (fit-content)


I'm not sure if I'm overseeing something obvious, but I need a layout where each row has equal width columns but automatically fit to content with a min width of the widest vertical column as shown on the below image:

enter image description here

In reference to this question

Sample 1: Using flex-direction column and flex direction row with width fit to content will result in this:

ul {
display: flex;
flex-direction: column;
border: 1px solid #000;
padding: 2px;
}
ul li {
display: flex;
width: fit-content;
flex-direction: row;
}
ul li div {
border: 1px solid #000;
padding: 2px;
margin: 2px;
}
<ul>
    <li>
        <div>First column</div>
        <div>Second column</div>
        <div>Third column</div>
    </li>
    <li>
        <div>Data with length.......</div>
        <div>Data with length..</div>
        <div>Data with length....</div>
    </li>
    <li>
        <div>Data with length...</div>
        <div>Data with length...</div>
        <div>Data with length....</div>
    </li>
    <li>
        <div>Data with length..</div>
        <div>Data with length.......</div>
        <div>Data with length.....</div>
    </li>
</ul>

Thats almost right expect the columns each has their own length

Sample 2: Using grid-template-columns with minmax column and flex direction row with width fit to content will result in this:

ul {
display: grid;
border: 1px solid #000;
padding: 2px;
}
ul li {
display: grid;
grid-gap: 2px;
grid-template-columns:
    minmax(5%, 30%)
    minmax(6%, 30%)
    minmax(7%, 30%);
}
ul li div {
border: 1px solid #000;
padding: 2px;
margin: 2px;
}
<ul>
    <li>
        <div>First column</div>
        <div>Second column</div>
        <div>Third column</div>
    </li>
    <li>
        <div>Data dynamic length.......</div>
        <div>Data dynamic length..</div>
        <div>Data dynamic length....</div>
    </li>
    <li>
        <div>Data dynamic length...</div>
        <div>Data dynamic length...</div>
        <div>Data dynamic length....</div>
    </li>
    <li>
        <div>Data dynamic length..</div>
        <div>Data dynamic length.......</div>
        <div>Data dynamic length.....</div>
    </li>
</ul>

Second sample kind of does the trick except that it by default uses the 30% in the minmax, and if put auto in the second argument in minmax the columns will fill out remaining space and still not solve the problem

Is there any neat technique to do this?


Solution

    1. Don't use a lsit for this task. IMHO compeltely wrong sue for a list.
    2. grid-template-columns: repeat(3, min-content) will create 3 columns with minimal row-size.
    3. You will have an unintend wordwrap. That can be countered with: white-space: nowrap;

    Your grid doesnt work as you create sub-grids. They render independently from each other. You must only use one grid to achieve what you want.

    .grid {
      display: grid;
      border: 1px solid #000;
      grid-template-columns: repeat(3, min-content);
      white-space: nowrap;
      padding: 2px;
    }
    
    .grid > div {
      border: 1px solid #000;
      padding: 2px;
      margin: 2px;
    }
    <div class="grid">
    
      <!-- first row -->
      <div>First column</div>
      <div>Second column</div>
      <div>Third column</div>
      
      <!-- second row -->
      <div>Data dynamic length.......</div>
      <div>Data dynamic length..</div>
      <div>Data dynamic length....</div>
      
      <!-- third row -->
      <div>Data dynamic length...</div>
      <div>Data dynamic length...</div>
      <div>Data dynamic length....</div>
      
      <!-- fourth row -->
      <div>Data dynamic length..</div>
      <div>Data dynamic length.......</div>
      <div>Data dynamic length.....</div>
      
    </div>