How to shrink column to max width of that column in all rows, like td width in a table?

Viewed 497

I want to replace a table with flexbox elements.

Basically from this:

<table>
  <tr>
    <td>row_1.col_1</td>
    <td>row_1.col_2</td>
  </tr>
  <tr>
    <td>row_2.col_1.with_longer_content</td>
    <td>row_2.col_2</td>
  </tr>
</table>

To this:

<div>
  <div>
    <div>row_1.col_1</div>
    <div>row_1.col_2</div>
  </div>
  <div>
    <div>row_2.col_1.with_longer_content</div>
    <div>row_2.col_2</div>
  </div>
</div>

In the case of the table, the first row's first cell will expand in width so that the second cell row_1.col_2 will align properly with the cell beneath it row_2.col_2

-------------------------------------------------
| row_1.col_1                     | row_1.col_2 |
| row_2.col_1.with_longer_content | row_2.col_2 |
-------------------------------------------------

How can I do the same with divs, using flexbox, so that the first column consumes the least amount of width, but the second column is still aligned?

Is this even possible?

The reason why I want to do this is because I want each row to be a Quasar q-card, but the elements in there should align with the cards above and below, yet still consume the least amount of space and not be width-controlled through the "12-column"-grid-system.

Basically like this, where I need the badges and inputs to be aligned as if it were a table (I cannot use a q-table, and -- due to the use of UMD -- also not a q-markup-table):

<q-card>
  <q-card v-for='element in elements'>
    <q-badge>{{element.badge}}</q-badge>
    <q-input v-model='element.text'></q-input>
  </div>
</div>
3 Answers

Instead of flex, it would probably be better to use display:table

div {
  display: table;
}

div>div {
  display: table-row;
}

div>div>div {
  display: table-cell;
}
<div>
  <div>
    <div>row_1.col_1</div>
    <div>row_1.col_2</div>
  </div>
  <div>
    <div>row_2.col_1.with_longer_content</div>
    <div>row_2.col_2</div>
  </div>
</div>

Using display: flexbox you can do this by organizing the data by column instead of by row. Using display: table you can maintain the structure of the table. Examples:

.flex-table {
  display: flex;
}

.column {
  padding: 4px;
}

.table {
  display: table;
}

.table-row {
  display: table-row;
}

.table-cell {
  display: table-cell;
  padding: 0 4px;
}
<h3>table</h3>

<table>
  <tr>
    <td>row_1.col_1</td>
    <td>row_1.col_2</td>
  </tr>
  <tr>
    <td>row_2.col_1.with_longer_content</td>
    <td>row_2.col_2</td>
  </tr>
</table>

<h3>flexbox table</h3>

<div class="flex-table">
  <div class="column">
    <div>row_1.col_1</div>
    <div>row_2.col_1.with_longer_content</div>
  </div>
  <div class="column">
    <div>row_1.col_2</div>
    <div>row_2.col_2</div>
  </div>
</div>

<h3>display table</h3>

<div class="table">
  <div class="table-row">
    <div class="table-cell">row_1.col_1</div>
    <div class="table-cell">row_1.col_2</div>
    
  </div>
  <div class="table-row">
    <div class="table-cell">row_2.col_1.with_longer_content</div>
    <div class="table-cell">row_2.col_2</div>
  </div>
</div>

<style>
    .row {
        display: -ms-flexbox;
        display: flex;
        -ms-flex-wrap: wrap;
        flex-wrap: wrap;
        margin-right: -15px;
        margin-left: -15px;
    }

    .col {
        -ms-flex-preferred-size: 0;
        flex-basis: 0;
        -ms-flex-positive: 1;
        flex-grow: 1;
        max-width: 100%;
        position: relative;
        width: 100%;
        padding-right: 15px;
        padding-left: 15px;
    }

    .text-wrap {
        white-space: normal !important;
    }
</style>

<div>
    <div class="row">
        <div class="col text-wrap">row_1.col_1</div>
        <div class="col text-wrap">row_1.col_2</div>
    </div>
    <div class="row">
        <div class="col text-wrap">row_2.col_1.with_longer_content</div>
        <div class="col text-wrap">row_2.col_2</div>
    </div>
</div>

Try writing like this & if you don't want to use the above styles use the bootstrap css link instead.

Related