Angular Material Mat-Select Width Based on Longest Option Width
Asked Answered
F

7

27

I have a mat-select with options, I am looking to set this inline to text and have the drop down only be as long as the longest option. I can probably do some hackery with js / css vanilla style, but looking for a better solution. any thoughts?

<mat-select
  [ngClass]="{'missing-selection': !SelectedOption}"
    [(value)]="SelectedOption"
    id="select"
    (selectionChange)="optionChange($event)"
  >
    <mat-option
      *ngFor="let option of data.Options"
      [value]="option.Value"
      >{{ option.Label}}</mat-option
    >
  </mat-select>
Furman answered 4/2, 2019 at 14:16 Comment(3)
That's where you're wrong : selects in Angular material aren't real select, they're components that are dynamically placed by the CDK through an overlay service. If you want to adapt your input size to your list size, you will have to create the exact same component, and measure it. This means that you have to either make hard calculations before displaying it, or change the size of the input after the list is displayed.Tinney
Yea, I kind of figured that, was hoping there was an out of box or already made solution I was missing. I'll post what I come up with after I try a few more things out.Furman
github.com/angular/components/issues/… is a good workaroundZiegfeld
E
12

Please, try this (for selected option)...

.auto-width{
    .mat-form-field {
        width: auto !important;
    }
    .mat-select-value {
        max-width: 100%;
        width: auto;
    }  
}

<div class="auto-width">
    <mat-form-field>
      <mat-select>
        <mat-option value="long">Long description</mat-option>
        <mat-option value="foo">Foo</mat-option>      
      </mat-select>
    </mat-form-field>
</div>
Exocarp answered 10/6, 2019 at 15:12 Comment(3)
@nicolas.leblanc i got it working by adding ::ng-deep to the outer selectorBellybutton
It does not look great though... the dropdown arrow is all the on the left when no value is selected, and just to the right of the text when one is selected (not in the far right). When a long description is selected, all the text is visible, but the line along the bottom of the control does not extend to match it.Ziegfeld
May be I'm late to the party, but, it might help someone, replace width:auto with min-width: 100%, that moves the dropdown arrow to the right side. .mat-select-value { max-width: 100%; min-width: 100%; }Hinch
E
5

For Angular 16 or higher you can use panelWidth="" see docs. https://material.angular.io/components/select/api

Edmundoedmunds answered 15/3, 2024 at 20:36 Comment(1)
the correct, non hacky solution for angular >=16Horehound
S
1

For "@angular/material": "13.3.2" this works for me

  ::ng-deep .mat-select-value {
    max-width: 100%;
    min-width: 100%;
    width: auto;
  }
  ::ng-deep .mat-form-field-infix {
    width: auto !important;
    min-width: 180px !important;
    padding-right: 13px !important;
  }
Stearic answered 21/3, 2023 at 23:47 Comment(0)
M
0

A solution for Angular Material v17 using panelClass.

   <mat-select panelClass="custom-class">

To match the width of the mat-select, angular-material sets the width in the style attribute of the .cdk-overlay-panel element. Angular-material also puts the panel class on the child element of .cdk-overlay-panel, so both a :has(>...) and a !important are required to override the panel width.

.cdk-overlay-pane:has(>.custom-class){
   width: initial !impontant;
}

My specific use case just needed the sizing to get bigger, so I used:

.cdk-overlay-pane:has(>.custom-class){
   min-width: fit-content;
}
Mourning answered 8/2, 2024 at 23:15 Comment(0)
A
0

I fixed it using:

::ng-deep .mat-autocomplete-panel {
  min-width: fit-content !important;
}
Aeneus answered 29/3, 2024 at 19:44 Comment(0)
G
0

In Angular 15, this works:

.mat-mdc-select-panel {
    min-width: min-content; 
}

And to prevent wrapping of the items in the list, you might also want this:

.mdc-list-item__primary-text {
    white-space: nowrap;
}
Godbeare answered 1/8, 2024 at 15:31 Comment(0)
K
-4

Try this code, it works but it is not dynamic.

::ng-deep .mat-form-field {
  width: 50px !important;
}
::ng-deep .mat-label {
    width: 50px !important;
}
::ng-deep .mat-select {
    width: 50px !important;
}

::ng-deep .mat-option {
    width: 50px !important;
}
Kolnos answered 11/9, 2019 at 16:46 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.