Material UI - Outlined select label is not rendering properly
Asked Answered
M

7

56

As per the demo, the label for a Material UI outlined select input should sit on top of the top border of the select box.

enter image description here

However, in my application, the z-index of the label seems to be placing it behind the top border and thus it looks like a line is cutting through the label.

enter image description here

I have pretty much taken the code exactly from the documentation, and as far as I know, do not have any styles conflicting with this input element. I have compared the styles in the debugger to what I have and what is present in the documentation, and I do not see any of my first party CSS files causing a different style to be set on the element.

Any idea what might be going wrong here?

Here is the source code:

<FormControl variant='outlined' style={{ width: '100%' }} margin={'1'}>
  <InputLabel id='test-select-label'>Label</InputLabel>
  <Select
    labelId='test-select-label'
    id='test-select'
    value={'test1'}
    onChange={e => setTest(e.target.value)}
    size='small'
  >
    <MenuItem key={1} value={'test'} >Test 1</MenuItem>
    <MenuItem key={2} value={'test2'} >Test 2</MenuItem>
  </Select>
</FormControl>
Mabellemable answered 12/4, 2021 at 19:39 Comment(0)
P
124

Solution 1: Use TextField

This is what TextField is for. It uses FormControl and InputLabel internally and make sure they work well together. You can tell TextField to render select instead input by overriding the select props:

<TextField
  value={value}
  onChange={(e) => setValue(e.target.value)}
  select // tell TextField to render select
  label="Label"
>
  <MenuItem key={1} value="test">
    Test 1
  </MenuItem>
  <MenuItem key={2} value="test2">
    Test 2
  </MenuItem>
</TextField>

For more detail about how TextField works, see this answer.

Solution 2: Use Select

If you decide to use Select, you need to write more code to do the same amount of work:

Pass the label text as InputLabel children

<InputLabel id="test-select-label">Label</InputLabel>

This label text will be rendered on the screen as the Select label when put inside FormControl and next to the Select component.

Pass the label text to the label props of the Select component

This label text is hidden and used to override and remove the part of the border-top where the real label is occupied when the Select label is shrinked.

<Select labelId="test-select-label" label="Label">

Putting it together we'll have something like below, note that with this approach we need to set the label in 2 different places which is not very DRY, so I'd prefer the first approach.

<FormControl>
  <InputLabel id="test-select-label">Label</InputLabel>
  <Select
    value={value}
    onChange={(e) => setValue(e.target.value)}
    labelId="test-select-label"
    label="Label"
  >
    <MenuItem key={1} value="test">
      Test 1
    </MenuItem>
    <MenuItem key={2} value="test2">
      Test 2
    </MenuItem>
  </Select>
</FormControl>

Live Demo

Codesandbox Demo

Pseudohermaphroditism answered 13/4, 2021 at 4:49 Comment(4)
Sure Solution 2 not very DRY, but if you make a custom component that delegates to the code you propose, the ugliness gets encapsulatedBreathy
Yeah, I got this working using Solution 2 (since that's what the docs mui.com/material-ui/react-select led me to). The key/unintuitive issue is that we have to specify the label text twice (both in the InputLabel and the Select component, and also specify the labelId in both theInputLabel and the Select component.Haifa
Solution 2 worked well for me, while solution 1 is DRYer out of the box I also needed multiple select and with that in play things start to become a hassle, mismatched types onChange for a start: github.com/mui/material-ui/issues/34816. Note the comment: github.com/mui/material-ui/issues/34816#issuecomment-1291748229 which indicates the possibility of (in future) removing the select prop from TextField.Poodle
Note that the above still doesn't work if the sx prop has been used to set a custom font size in the select component that is larger than the default font size - the end of the label will run over the box slightly.Backbend
S
18

If you add the label property to your select component your problem should disappear.

<FormControl>
  <InputLabel id="test-select-label">Label</InputLabel>
  <Select
    value={value}
    onChange={(e) => setValue(e.target.value)}
    label="Label" // add this
  >
    <MenuItem key={1} value="test">
      Test 1
    </MenuItem>
    <MenuItem key={2} value="test2">
      Test 2
    </MenuItem>
  </Select>
</FormControl>

Here is a live demo where you can see the difference:

Edit material-ui-outlined-select-label-is-not-rendering-properly

Salba answered 12/4, 2021 at 22:40 Comment(4)
Your label is still cut by the top border if you change it to a longer string.Pseudohermaphroditism
This is not true if your label property and the input label have the same length. +1 Your first approach seems much nicer though.Salba
If CodeSandbox is down, people will only copy this part of your code without knowing that they need to change the label in 2 places. The other place is in InputLabel which is omitted in your answer.Pseudohermaphroditism
Note that the above still doesn't work if the sx prop has been used to set a custom font size in the select component that is larger than the default font size - the end of the label will run over the box slightly.Backbend
K
3

Refer to the highlighted text

Please include the label props in the Select and make sure it matches the value you specify in InputLabel

Kaftan answered 8/3, 2023 at 8:52 Comment(1)
Do not post images of text.Berner
T
2

As per documentation here, we have to mention label at 2 places.

Note that when using FormControl with the outlined variant of the Select, you need to provide a label in two places: in the InputLabel component and in the label prop of the Select component.

<FormControl sx={{ m: 1, width: 300 }} focused>
        <InputLabel id="demo-multiple-name-label">Name</InputLabel>
        <Select
          labelId="demo-multiple-name-label"
          id="demo-multiple-name"
          multiple
          value={personName}
          onChange={handleChange}
          input={<OutlinedInput label="Name" />}
          MenuProps={MenuProps}
        >
          {names.map((name) => (
            <MenuItem
              key={name}
              value={name}
              style={getStyles(name, personName, theme)}
            >
              {name}
            </MenuItem>
          ))}
        </Select>
      </FormControl
Tendance answered 27/10, 2023 at 8:13 Comment(0)
A
1

you can try this:

<FormControl >
  <InputLabel
    color="primary"
    id="demo-multiple-checkbox-label"
  >
    Equip
  </InputLabel>

  <Select
    labelId="demo-multiple-checkbox-label"
    id="demo-multiple-checkbox"
    onChange={handleCloseGangsters}
    input={<OutlinedInput label="Equip" />}
  >
    <MenuItem key="key1" value={'value1'}>
      <ListItemText primary={`Equip name1`} />
    </MenuItem>
    <MenuItem key="key2" value={'value2'}>
      <ListItemText primary={`Equip name2`} />
    </MenuItem>
  </Select>
</FormControl>

Artamas answered 26/3, 2023 at 14:1 Comment(0)
M
0

I had a similar issue when I tried to set padding on the FormControl component. I had the proper id and label, but it was still an issue. CSS is not my strong suit, but I noticed that if I could replicate the layout I wanted using margin on the FormControl component, the label aligned appropriately. See image with padding instead of margin:

FormControl with padding

Millpond answered 5/8, 2022 at 17:2 Comment(0)
L
0

I will just leave here solution that helped me, as top rated answer was not fully helpful. The trick was in adding input prop into Select assigned to OutlinedInput with actual label value :

<FormControl>
  <InputLabel>
    {"label-text"}
  </InputLabel>
  <Select
    multiple
    value={groupPlanWeekdays}
    onChange={onChange}
    input={
      <OutlinedInput
        label={"label-text"}
      />
    }
    renderValue={(selected) => selected.join(', ')}
  >
    <MenuItem />
  </Select>
</FormControl>
Lumpfish answered 12/11, 2023 at 18:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.