Components: feat(select): allow auto-width based on placeholder / value

Created on 8 Oct 2017  路  8Comments  路  Source: angular/components

fixed width on mat-form-field

I want my select to have the width of the selected item, fixed width on mat-form-field makes it impossible, you can override .mat-form-field to have width auto, along with overriding .mat-select-value to be width auto and max-width 100%, but then you have a problem, because placeholder is absolutely positioned, which means that the select without any value set yet will be zero width (actually 18px because of the arrow).

https://stackblitz.com/edit/material2-select-width-issues?file=styles.scss

Now I could also override placeholders not to be absolutely positioned, but that's not gonna work properly either, because the arrow is inside the md-select element, while the placeholder is outside

image

I'm not sure if that 200px width is something that's on material spec, but the DOM could perhaps be structured a bit differently, in a way that wouldn't prevent devs from achieving fluid width (which is a bit closer to how native selects work)

different height when selected vs. placeholder

image

cc @crisbeto

P3 materiaselect feature

Most helpful comment

The best workaround I found to fix both value and placeholder was to use ::ng-deep and set a different min-width on .mat-select-placeholder and setting width: fit-content on .mat-select-value and mat-select.

Since ng-deep will be deprecated soon this is not a permanent solution but one that works until this issue is resolved.

Full example:

mat-select {
    width: fit-content !important;
    min-width: 100%;
}

::ng-deep .mat-form-field-infix {
    min-width: 75px !important;
    width: fit-content !important;
}

::ng-deep mat-select .mat-select-value {
    width: fit-content;
    min-width: 2ch;
    max-width: 25ch;
}
::ng-deep mat-select .mat-select-placeholder {
    width: fit-content;
    min-width: 10ch;
}

All 8 comments

This seems to workaround the differences in heights

.mat-select {
  height: 1.125em;
}

also what's on current master has mat-form-field-infix fixed width to 180px

@crisbeto @mmalerba

I believe the height issue was caused by an   not rendering correctly. It was fixed with https://github.com/angular/material2/pull/7431 by updating Angular to a version that fixed the bug. The width was added so the select would have a correct initial width, but it should still resize to fit the form field. Here's a plunker demonstrating both behaviors working without any special CSS: http://plnkr.co/edit/xugYuUx3dY50lTnDu7HB?p=preview

@mmalerba it resizes to fit the form field, but form field doesn't fit its parent (which causes problems, see https://github.com/angular/material2/issues/7783).

Anyway, what I'm talking about in this issue (regarding the width) is having select to be only the width of its content (either selected value, or placeholder).. currently it's either fixed to whatever mat-form-field width is, or 100% of its parent (when you remove the fixed width of mat-form-field-infix - http://plnkr.co/edit/wwhnrq8fFbWWPfCDtySX?p=preview).

You can force it to be only the width of the selected value (https://stackblitz.com/edit/material2-select-width-issues-vedgpg?file=styles.scss) but it's not gonna work with placeholder (when there's no value selected yet), because it's absolutely positioned, and this is hard to override, because of where the placeholder is placed in dom, as I described in the initial post. I'm currently getting around it (since I don't need floating placeholders in this particular case) by using the first option without any value set as a placeholder.. not ideal.

Ok, I've changed the title of the issue to reflect just the width issue, since the height should be resolved

Something else that should be noted with those css overrides is that you lose the text truncating and ellipsis when you resize the screen

This is p3??

The best workaround I found to fix both value and placeholder was to use ::ng-deep and set a different min-width on .mat-select-placeholder and setting width: fit-content on .mat-select-value and mat-select.

Since ng-deep will be deprecated soon this is not a permanent solution but one that works until this issue is resolved.

Full example:

mat-select {
    width: fit-content !important;
    min-width: 100%;
}

::ng-deep .mat-form-field-infix {
    min-width: 75px !important;
    width: fit-content !important;
}

::ng-deep mat-select .mat-select-value {
    width: fit-content;
    min-width: 2ch;
    max-width: 25ch;
}
::ng-deep mat-select .mat-select-placeholder {
    width: fit-content;
    min-width: 10ch;
}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jelbourn picture jelbourn  路  94Comments

tyler2cr picture tyler2cr  路  57Comments

jelbourn picture jelbourn  路  132Comments

mmalerba picture mmalerba  路  77Comments

kara picture kara  路  94Comments