Anna
Anna

Reputation: 2845

Table-like alignment of different-width columns with flexbox

Can this table behaviour be achieved using flexboxes or other CSS techniques? I'm trying to align the second-column cells. In my actual code, each cell would be a div.

enter image description here

I'm aware of display:table, unfortunately I've run into several issues using this, so I'm trying to find a flexbox solution. Ideally, I'd like the second-column cells to have different widths.

<table>
  <tr>
    <td>Column 1</td>
    <td>Column 2</td>
  </tr>
  <tr>
    <td>Row 2 is longer</td>
    <td>This column is aligned either way</td>
  </tr>
</table>

Here is my non-table HTML, that I'd like to appear identically as above. The content and width of the cells can vary as it comes from backend, but the first column should always be "as small as possible", just like an HTML table makes it with default styling.

<div class="lines">
  <div class="line">
    <div class="title">Column 1</div>
    <div class="description">Column 2</div>
  </div>
  <div class="line">
    <div class="title">Row 2 is longer</div>
    <div class="description">This column is aligned either way</div>
  </div>
</div>

Upvotes: 2

Views: 2246

Answers (4)

bron
bron

Reputation: 1548

The html <table> and its children can be used in a flex way.

I added some examples how to use the column width classes and some styling examples. Each row can have the same or a different amount of columns then the other rows. Things as colspan are very simple to create.

And it is responsive for smartphone, tablet and large screens.

table, tr {
    display: flex;
    flex-flow: row nowrap;
    width: 100%;
    text-align: left;
    box-sizing: border-box;
}
tbody, thead, tfoot, th, td {
    display: block;
    flex: 0 0 100%;
    width: 100%;
    box-sizing: border-box;
}
th, td {
    vertical-align: top;
    text-align: inherit;
    text-align: -webkit-match-parent;
}

/* table small screen */

@media (max-width: 576px) {
    table {
        min-width: 576px;
    }
    .f-table {
        width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* === example column width === */

th.th-25, td.td-25, .th-25 th, .td-25 td { max-width: 25%; }
th.th-33, td.td-33, .th-33 th, .td-33 td { max-width: 33.3333%; }
th.th-50, td.td-50, .th-50 th, .td-50 td { max-width: 50%; }
th.th-66, td.td-66, .th-66 th, .td-66 td { max-width: 66.6666%; }
th.th-75, td.td-75, .th-75 th, .td-75 td { max-width: 75%; }
th.th-100, td.td-100, .th-100 th, .td-100 td { max-width: 100%; }

/* === example styling === */

table {
  border-top: 1px solid silver;
  border-left: 1px solid silver;
}
th, td {
  border-right: 1px solid silver;
  border-bottom: 1px solid silver;
  font: normal 14px/1.3 "Segoe UI", "Helvetica Neue", "Noto Sans", sans-serif;
  padding: 2px 5px 4px 5px;
}
th {
  background-color: #33a;
  color: #fff;
  font-weight: 600;
}
<div class="f-table">
    <table class="td-33">
        <tbody>
            <tr class="th-33">
                <th>Lorem ipsum dolor</th>
                <th>Lorem ipsum dolor</th>
                <th>Lorem ipsum dolor</th>
            </tr>
            <tr>
                <td class="td-66">Lorem ipsum dolor sit amet.</td>
                <td class="td-33">Lorem ipsum dolor sit amet consectetur.</td>
            </tr>
            <tr>
                <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</td>
                <td>Lorem ipsum dolor sit amet, consectetur adipiscing.</td>
                <td>Lorem ipsum dolor sit amet,.</td>
            </tr>
            <tr class="th-100">
                <th>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi arcu ipsum.</th>
            </tr>
            <tr class="td-50">
                <td>Lorem ipsum dolor sit amet, consectetur.</td>
                <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi arcu ipsum, suscipit non placerat non.</td>
            </tr>
            <tr class="td-100">
                <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi arcu ipsum, suscipit non placerat non, egestas et diam.</td>
            </tr>
        </tbody>
    </table>
</div>

Upvotes: 0

Paulie_D
Paulie_D

Reputation: 114991

With your current HTML you will need to use display:contents to "unwrap" the child containers then CSS-Grid can do the rest.

.lines {
  display: inline-grid;
  grid-template-columns: auto auto;
  gap: 0 1em;
}

div {
  border:1px solid grey;
}

.line {
  display:contents;
}
.title {
  grid-column: 1;
}

.description {
  grid-column: 2;
}
<div class="lines">
  <div class="line">
    <div class="title">Column 1</div>
    <div class="description">Column 2</div>
  </div>
  <div class="line">
    <div class="title">Row 2 is longer</div>
    <div class="description">This column is aligned either way</div>
  </div>
</div>

Upvotes: 5

avia
avia

Reputation: 1568

You can use various flexbox properties to achieve this desired result, example below.

.wrapper {
display:flex;
width:90vw;
margin-left:5vw;
}

.container {
display:flex;
flex-direction:column;
width:50%;
}
<div class="wrapper">
  <div class="container">
    <span>Column 1</span>
    <span>Row 2 is longer</span>
    <span>Row 2 is much much longr longer much much longr longermuch much longr longer much much longr longer much much longr longer much much longr longer much much longr longer much much longr longermuch much longr longer much much longr longer much much longr longer much much longr longe much much longr longer much much longr longermuch much longr longer much much longr longer much much longr longer much much longr longe</span>
    <span>I am short</span>
     <span>Row 2 is much much longr longer much much longr longermuch much longr longer much much longr longer much much longr longer much much longr longer much much longr longer much much longr longermuch much longr longer much much longr longer much much longr longer much much longr longe much much longr longer much much longr longermuch much longr longer much much longr longer much much longr longer much much longr longe</span>
  </div>
  <div class="container">
    <span>Column 2</span>
    <span>This column is aligned either way</span>
  </div>
</div>

Upvotes: 0

Azu
Azu

Reputation: 1550

You could use grid:

.grid {
    display: grid;
    grid-template-columns: 1fr 1fr; 
}
<div class="grid">
    <div>Column 1</div>
    <div>Column 2</div>
    <div>Row 2 is longer</div>
    <div>This column is aligned either way</div>
</div>

Upvotes: -1

Related Questions