Angular Material Dropdown with Multi-Column Support

I'm working on customizing the selection panel layout to display items in multiple columns. However, I'm facing an issue where the last item in each column appears off-center and split, causing overflow into the next column instead of a vertical scroll. With over 30 items in the list and allowing multiple selections, the aim is to show as many options as possible without excessive scrolling.

Check out the full StackBlitz example here: https://stackblitz.com/edit/angular-bt3gs6

https://i.sstatic.net/nlJYD.png

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'];
}

Answer №1

One issue arises with the columns, as they tend to become off-center and split due to the height of the .mat-select-panel.

The current set max-height:256px; in the Angular Material code allows for a scrollbar (approximately 17px in height on Windows - Chrome), leaving only 239px of remaining space.

With each mat-option having a height of 48px, accommodating 5 options in a column will require 240px.

An immediate fix could involve increasing the height of the .mat-select-panel to 257px:

Check out the demo here: https://stackblitz.com/edit/angular-bt3gs6-wxwkgg

However, this solution may not display correctly on MacOS, where scrollbars behave differently due to additional available space:

View macOS example image here: https://i.sstatic.net/wlBff.png


A cross-platform alternative involves ditching columns (challenging to implement universally) and opting for a display: flex strategy for the .mat-select-panel element:

Horizontal scrolling method:

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

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

Explore the horizontal scrolling demo here: https://stackblitz.com/edit/angular-bt3gs6-lwvwav

Vertical scrolling availability:

If vertical scrolling is preferred, simply remove flex-direction: column; from the above code segment and adjust the max-height to determine the default visible rows:

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

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

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

Find the vertical scrolling demo here: https://stackblitz.com/edit/angular-bt3gs6-iykn4w

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I find that ChangeDetectionStrategy.OnPush does not function as anticipated

Exploring the performance boost of ChangeDetectionStrategy.OnPush in Angular 2 (detailed here) has been my recent focus. However, I've encountered an interesting scenario. In my code, I have the parent component AppComponent: @Component({ selector ...

I am looking to invoke the Token API from Microsoft Graph during an Angular 7+ HTTP request

My goal is to make an API call from my Angular application to retrieve an access token from . With this token, I then aim to access the https://graph.microsoft.com/v1.0/users/##UserId##​​​​​​​​​​​​​/getMemberGroups endpoint withou ...

Simple steps to transform the "inputs" syntax into the "@Input" property decorator

There's this code snippet that I need to modify: @Component({ selector: 'control-messages', inputs: ['controlName: control'], template: `<div *ngIf="errorMessage !== null">{{errorMessage}}</div>` }) Is the ...

What is the process for determining the area of the section?

Take a look at this page as an example - scrolling down on responsive devices reveals related navigation areas which I aim to change with scrollspy (affix fixed navigation). Having a bootstrap navbar, when on the corresponding section of the navbar while u ...

What impact does setting everything to position:relative have on a webpage?

I stumbled upon some CSS / HTML examples and came across this interesting snippet: *, *:before, *:after { position: relative; } It appears that implementing this rule can have a notable impact on the layout. What might be the rationale behind this ...

Click event for jQuery horizontal accordion

I'm attempting to create a simple horizontal accordion-style element. My setup includes three 'banner' divs and three 'area' divs. Ideally, when I click on a banner, the corresponding area should animate - expanding in width to au ...

Developing a databound listview in Ionic: A step-by-step guide

In the world of programming, each platform has its own way of handling lists. For example, Android uses RecyclerView, WPF uses ListView, and in Ionic, we have ion-list. If you have a list of strings like this: Animals:string[] = ["Dog", "Cat", "Human", "C ...

Angular component: Placing icons on the right side of a mat-chip element

My mat-chip contains content and a cancel icon, but I am having trouble getting the cancel icon to float to the right consistently. Despite setting a fixed width for the mat-chip, the cancel icon is not aligning properly no matter what CSS techniques I t ...

Is there a way to adjust the background color of the clicked tab with divs and revert the others back to their original color?

<span class="row top-bar-left align-items-center" style="width: 80%; float:left"> <div tabindex="1" class="link tab" routerLink="details" routerLinkActive="active" [qu ...

What is the CSS code to extend the width or length of a form field?

I am working with a form field box that has the class CCPPDisplayTD. I am attempting to increase its length using CSS styling. What is the best way to achieve this using CSS? ...

Adjusting Spacing Between Characters

I've been looking for a way to convert regular characters (ABC) to full-width characters (ABC), but I haven't had any luck so far. That's why I'm turning to you guys for help. Currently, I don't have any JavaScript code writt ...

The ngAfterContentInit lifecycle hook is not triggered when the parent component updates the child component

I am trying to understand the functionality of the ngOnChanges callback in Angular. I have implemented it to observe changes in a property annotated with the Input decorator as shown below: @Input() postsToAddToList: Post[] = []; However, after compiling ...

Tips for enhancing functionality with dependencies in Angular 2

I am working with a ParentService that has dependencies like: @Injectable() export class ParentService{ constructor(private http:Http, private customService:CustomService){} } Now, I want to create a ChildService that extends the ParentService: @Injec ...

Aligning variable width numbers within a div container

Currently experimenting with CSS to create a calendar design that mimics the look of a traditional paper calendar. One issue I've encountered is the alignment of numbers within boxes, especially when dealing with double digits. When displaying a sing ...

To reveal more options, simply click on the button to open up a dropdown

I am currently utilizing the Bootstrap 5 CDN and I am looking for a way to automatically open the dropdown menu without having to physically click on it. Within the navbar, I want to display the "Dropdown Link": <nav class="navbar navbar-expand-sm ...

Step-by-step tutorial on designing an input slider to dynamically adjust the CSS :before linear-gradient values

Is there a way to achieve a gradient effect using pseudo-element :before on an image that can be customized by adjusting a slider input? I've been trying to implement this feature with the following code, but have not been successful so far. var ...

Creating a HTTP Post request in Angular with DocRaptor to receive the download URL in the response

Struggling to integrate Angular5 with DocRaptor has led me to hit a roadblock. Surprisingly, the DocRaptor website lacks any documentation on how to combine it with Angular, only offering a beginner's guide for 'other'. I've scoured thr ...

Exploring the jungle. Cursor acting strange while dragging

I am currently working on implementing drag-and-drop functionality in my project, utilizing slip.js from slip.js. To enhance the cursor during dragging, I have assigned class="draggable" to each draggable <tr>. The CSS code for this class is: .drag ...

Only displaying sub items upon clicking the parent item in VueJS

I'm in the process of designing a navigation sidebar with main items and corresponding sub-items. I want the sub-item to be visible only when its parent item is clicked, and when a sub-item is clicked, I aim for it to stand out with a different color. ...

generate a fresh array with matching keys

Here is an example array: subjectWithTopics = [ {subjectName:"maths", topicName : "topic1 of maths " }, {subjectName:"maths", topicName : "topic2 of maths " }, {subjectName:"English", topicName : &quo ...