8
votes

I have a list of fruits with 10 entries. I want to make it so that the fruit name text (next to a mat-chip) are displayed in two columns with 5 in each column. The chips I am using are here: https://material.angular.io/components/chips/api

My CSS:

.flexp {
    display: flex;
    flex-wrap:wrap;
}

.flexc {
    flex-grow: 1;
    display: inline-block;
}

HTML

       <div class="flexp" *ngFor="let fruit of fruits">
              <div class="flexc">
                <mat-chip>
                  {{fruit.typeOfFruit}}
                </mat-chip>
                {{fruit.name}}
              </div>
          </div>

How can I do this? Right now my flexbox is going from top to bottom.

I want to make to so that it looks like a table, but without having to create the structure. If there was a way for the ngFor to be smart enough to make it display in this way... that is what I am looking for:

<table>
<tr>
<td>Fruit 1</td><td>Fruit 6</td>
<td>Fruit 2</td><td>Fruit 7</td>
<td>Fruit 3</td><td>Fruit 8</td>
<td>Fruit 4</td><td>Fruit 9</td>
<td>Fruit 5</td><td>Fruit 10</td></tr>
</table>

If it is not possible, please state.

5
Let's assume one of your clients repeats a row 12 times. And each row contains 1 column. And each column contains the item they actually want to repeat. What would you tell your client?tao
I don't get what you mean, I want it to look like a table without coding a table.Rolando
flexbox is supposed to make multiple children of one flex parent follow some alignment and distribution rules. Instead of having 12 children inside one parent, you have 12 parents, each with 1 children. You either apply flex to the parent of the parents or you apply your *ngFor to .flexc. I'd personally throw .flexc away (if you coded it for this case only) and simply repeat <mat-chip>s.tao
So the problem with my question is the mat-chip I want to display side by side with the fruit.name... when putting *ngFor on the mat-chip it looks funnyRolando
I believe style="display: inline-block;" is overriding display: flex; in .flexp. So you think you are using flexbox but you are not.G. Tranter

5 Answers

5
votes

I am assuming that the table code you gave as an example is wrong, since you mentionned that you want 2 columns with 5 rows, which is equivalent to this. The answer below is to have a display similar to the table here

<table>
<tr><td>Fruit 1</td><td>Fruit 6</td></tr>
<tr><td>Fruit 2</td><td>Fruit 7</td></tr>
<tr><td>Fruit 3</td><td>Fruit 8</td></tr>
<tr><td>Fruit 4</td><td>Fruit 9</td></tr>
<tr><td>Fruit 5</td><td>Fruit 10</td></tr>
</table>

If you want to use flex, you need to set flow-direction to column and have a max-height on the container, equal to 5 times the height of a row

scss

$rowHeight: 40px;
.flexp {
    display: flex;
    flex-wrap:wrap;
    flex-direction: column;
    max-height: calc(5 * #{$rowHeight});
}

.flexc {
    height: $rowHeight;
    flex-grow: 1;
    display: inline-block;
}

html

<mat-chip-list>
    <div class="flexp">
     <div class="flexc" *ngFor="let fruit of fruits">

        <mat-chip>
          {{fruit.typeOfFruit}}
        </mat-chip>
        {{fruit.name}}
      </div>
    </div>
</mat-chip-list>

Other solution not using flex

You can use the column-count property

scss

$rowHeight: 40px;
.fruitContainer {
    column-count: 2;
    max-height: calc(5 * #{$rowHeight});
}

.fruit {
    height: $rowHeight;
}

html

<mat-chip-list>
    <div class="fruitContainer">
     <div class="fruit" *ngFor="let fruit of fruits">
        <mat-chip>
            {{fruit.typeOfFruit}}
                    </mat-chip>
                    {{fruit.name}}
    </div>

</div>
</mat-chip-list>

Stackblitz demo

Below is the result

illustration

3
votes

MatGridList is provided for this very reason.

<mat-grid-list cols="2" rowHeight="48px">
    <mat-grid-tile *ngFor="let fruit of fruits">
        <div class="flexc">
            <mat-chip>
                {{fruit.typeOfFruit}}
            </mat-chip>
            {{fruit.name}}
        </div>
    </mat-grid-tile>
</mat-grid-list>

See stackblitz example.

1
votes

You can use CSS columns to define adaptive column layouts within a containing element. For example...

#container {
    -webkit-columns: 2 200px;
    -moz-columns: 2 200px;
    columns: 2 200px;
}

The first value (2) declares the number of columns and the second value (200px) declares their minimum width, such that the browser will collapse the columns if the container isn't wide enough. Vendor prefixing might not be strictly necessary but is still recommended.

See this CSS-Tricks post, which also deals with column gutters etc, for more info.

:)

1
votes

Changing your CSS to this will wrap it as you like, but not in that order. The direction is ltr.

.flexp {
    display: flex;
    flex-wrap: wrap;
    flex-direction: row;
}

.flexc {
    width: 50%;
}
0
votes

You can try in this way also..

CSS

  .flexp {
   column-count: 2;
   column-gap: 200px;
   width: 300px;
   }

  .flexc {
   display: inline-block;
   width: 160px;
   text-align: left;
   border: 1px solid white;
   }

HTML:

 <div class="flexp">
   <div class="flexc" *ngFor="let fruit of fruits">
      <mat-chip>
        {{fruit}}
      </mat-chip>
   </div>
 </div>