Material-ui: [TextField] Long labels break layout

Created on 23 Jul 2018  路  12Comments  路  Source: mui-org/material-ui


The textfield layout is not responsive when there are long labels.

  • [x] This is a v1.3.1 issue.
  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior

According to Material Design, long labels should be correctly positioned within the available input space:
2018-07-23 13 49 06

Current Behavior

  • Two or more line labels are overlapping the underline line.

Steps to Reproduce

https://codesandbox.io/s/6xjr79vx3w

import React from 'react';
import TextField from '@material-ui/core/TextField';

class TextFields extends React.Component {
  render() {
    return (
      <form noValidate autoComplete="off">
        <TextField
          id="name"
          label="This is a long label because things"
        />
      </form>
    );
  }
}

export default TextFields;

Context

  • All content is usually content managed, which means that the content editors could enter in label that may break the layout.
  • If the enter in a label that is longer than the available space, example: _"Do you have any association with a government entity?"_, and the user is loading the page in an iPhone 5, there is no enough space to render the label in only one line.

Your Environment

| Tech | Version |
|--------------|---------|
| Material-UI | v1.3.1 |
| React | v16.4.1 |
| browser | Chrome |

TextField

Most helpful comment

I found a workaround to trim label with ellipsis

.label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    right: 22px; //do not overlap icon
    bottom: 0px; //maximize container height so label wont be cut horizontaly
}

.label-shrinked {
    right: unset; //show complete label if shrinked
}

and in my component

...
<InputLabel
    classes={{
        root: styles.label,
        shrink: styles["label-shrinked"]
    }}
    id="label">

    {this.props.text}
</InputLabel>
...

result looks like this:

image

image

All 12 comments

@csantos1113 We can try to solve the issue by inverting the positioning strategy. We should be able to use bottom: 0 over top: 0.
https://github.com/mui-org/material-ui/blob/d2c16fc3e36691cd7dfdd6e4c1ed46147305f4cb/packages/material-ui/src/InputLabel/InputLabel.js#L18
Do you want to work on it?

@csantos1113 @oliviertassinari
From specs:
image
Labels should be short in other case use helper text instead

@kybarg It should, but we have the opportunity to make the implementation more flexible without extra cost. Well, in the case of the outlined text field, it's a dead-end, the text won't stay within the parent background boundaries.

Alright, we can forget about the bottom positioning strategy. It won't work with multiline text fields

capture d ecran 2018-07-29 a 18 32 59

Let's not support this use case for simplicity.

@oliviertassinari Just wondering what the resolution to the issue was, and how I should handle multiline labels (specifically as long labels condense on mobile devices). Thanks!

The resolution is: we don't support it, we don't want to support it. I would encourage you to increase the width of your input, or to reduce the width of your label or to use the helper text under the input.

Any workaround on this issue ? My labels are dynamic with diferent lenghts. At least, is there a way to disable wrapping and set text overflow to ellipsis ?

I would recommend that you implement a hard ellipses logic: if .length > x then cut and add ....

Sorry this wont work with respinsive design and various label texts. Ill give it a try if there wont be another solution. If i only could determine if label overflows, i could use helper text sa you recommended instead.

Yes, you could also use layout measurements.

I found a workaround to trim label with ellipsis

.label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    right: 22px; //do not overlap icon
    bottom: 0px; //maximize container height so label wont be cut horizontaly
}

.label-shrinked {
    right: unset; //show complete label if shrinked
}

and in my component

...
<InputLabel
    classes={{
        root: styles.label,
        shrink: styles["label-shrinked"]
    }}
    id="label">

    {this.props.text}
</InputLabel>
...

result looks like this:

image

image

Thanks for sharing.

Was this page helpful?
0 / 5 - 0 ratings