Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material Select w/ Columns

I am trying to style the selection panel such that the items display in several columns, but the last item of each column seems to become off-center and split, with the overflow starting at the top of the next column. Ideally the scroll would be vertical, but instead it seems to scroll horizontal to cover the overflow. My list has 30+ items and multiple selections are allowed. The goal is to display as many options as possible to the user at once so they don't have to scroll too much.

Full StackBlitz: https://stackblitz.com/edit/angular-bt3gs6

Panel Screenshot

select-multiple-example.scss

.toppings-panel.mat-select-panel {
  column-count: 2;
  column-width: 200px;
  width: 400px;
  max-width: 400px;
}

select-multiple-example.html

  <mat-select [formControl]="toppings" panelClass="toppings-panel" multiple>
    <mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping}}</mat-option>
  </mat-select>

select-multiple-example.ts

export class SelectMultipleExample {
  toppings = new FormControl();
  toppingList: string[] = ['Pepperoni', 'Sausage', 'Ham', 'Bacon', 'Chicken', 
                           'Mushroom', 'Red onion', 'White onion', 'Tomato', 'Olives', 
                           'Green bell peppers', 'Pineapple', 'Artichoke', 'Spinach', 
                           'Basil', 'Hot pepper flakes', 
                           'Parmesan', 'Shredded cheddar', 'Extra mozzarella'];
}
like image 277
Danielle Avatar asked Oct 18 '25 14:10

Danielle


1 Answers

The problem with the columns that become off-center and split, is the height of the .mat-select-panel.

It has max-height:256px; (setted in Angular Material code). But, since it has a horizontal scrollbar (which has a height of 17px, in Windows - Chrome), the available remaining space will be: 256 - 17 = 239px.

The height of the mat-option is 48px, so 5 options in a column will take 240px.

A quick solution would be to increase the height of the .mat-select-panel to 257px:

Demo: https://stackblitz.com/edit/angular-bt3gs6-wxwkgg

But, the example above will not display correctly on MacOS; which displays scrollbars like an absolute positioned content, and it has more space available:

enter image description here


I've found a cross platform solution by removing columns (which are kind of difficult to implement cross-browser and cross-platform) and taking an approach with display: flex for the .mat-select-panel element:

Horizontal scrolling:

.toppings-panel.mat-select-panel {
  width: 400px;
  max-width: 400px;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  min-height: 257px;   // min-height needed for windows browsers
}

 .toppings-panel.mat-select-panel .mat-option {
   min-width: 50%;  // 50% to have 2 columns visible
  }

Demo: https://stackblitz.com/edit/angular-bt3gs6-lwvwav

Vertical scrolling:

If you prefer vertical scrolling, just remove flex-direction: column; from the code above and play with the max-height in order to set the default visible rows:

.toppings-panel.mat-select-panel {
  width: 400px;
  max-width: 400px;
  display: flex;
  flex-wrap: wrap;

  max-height: 240px; /* 240px - for 5 items / column */
}

.toppings-panel.mat-select-panel .mat-option {
  min-width: 50%;
}

Demo: https://stackblitz.com/edit/angular-bt3gs6-iykn4w

like image 72
andreivictor Avatar answered Oct 21 '25 02:10

andreivictor