Styling the placeholder in a TextField
Asked Answered
A

11

68

The TextField API doesn't mention anything about how one could style the pseudo placeholder element of the input element.

Basically, I would like to change the default styling of the placeholder text, and the normal bag of tricks doesn't work, as I cannot access the element.

Is there a way I can get to it? And if so, what is the JSS/React/DOM equivalent way of writing ::-webkit-input-placeholder?

Artemisia answered 14/12, 2017 at 0:55 Comment(4)
css-tricks.com/almanac/selectors/p/placeholderGuillaume
Why can you not access the element? Even if the element is generated dynamically, your CSS styles that target it will still apply.Batwing
@CasperSL That's just being lazy. That link was already part of my question.Artemisia
@ObsidianAge That means I would have to write my CSS outside of the JS, wouldn't it? And further, it would also probably be tightly linked to the inner internals of the component, right?Artemisia
S
62

Case 1

Put the desired placeholder text in the label property of the TextField component, and use the labelClassName property of the TextField to customize it. You could also pass InputLabelProps with a className, classes or style attribute.

Case 2

Refrain from using the label property of TextField and put the placeholder text on its placeholder property instead. Leverage InputProps to override the generated HTML input element's class.

Code

The code below covers both aforementioned cases. CodeSandbox snippet.

import React from 'react';
import TextField from 'material-ui/TextField';
import { withStyles } from 'material-ui/styles';
import withRoot from '../components/withRoot';

const styles = {
  'input-label': {
    textOverflow: 'ellipsis',
    whiteSpace: 'nowrap',
    overflow: 'hidden',
    width: '100%',
    color: 'red'
  },

  'input': {
    '&::placeholder': {
      textOverflow: 'ellipsis !important',
      color: 'blue'
    }
  }
};

class Index extends React.Component {
  render() {
    return <div style={ {width: 150, margin: '0 auto'} }>
      {/* Uses "label" and "labelClassName". */}
      <TextField
        fullWidth
        label='I am a really really long red TextField label'
        labelClassName={ this.props.classes['input-label'] } />

      {/* Uses "label" and "InputLabelProps" with inline styles. */}
      <TextField
        fullWidth
        label='I am a really really long green TextField label'
        InputLabelProps={{
          style: {
            textOverflow: 'ellipsis',
            whiteSpace: 'nowrap',
            overflow: 'hidden',
            width: '100%',
            color: 'green'
          } }} />

      {/* Uses "placeholder" and "InputProps" with "classes". */}
      <TextField
        fullWidth
        margin='normal'
        placeholder='I am a really really long glue TextField label'
        InputProps={{ classes: {input: this.props.classes['input']} }} />
    </div>;
  }
}

export default withStyles(styles)(Index);

EDIT

The previous solutions are good if you'd like to personalize a specific component instance. To change the placeholder globally, see ninjaPixel's answer.

Stroy answered 31/1, 2018 at 15:19 Comment(0)
R
22

You can style the input at the top-level of your app, which will save you from having to create a custom input component with your styles applied to it (as suggested in other answers).

import { ThemeProvider } from "@material-ui/styles";
import { createMuiTheme } from "@material-ui/core/styles";

const customTheme = createMuiTheme({
overrides: {
  MuiInput: {
    input: {
      "&::placeholder": {
        color: "gray"
      },
      color: "white", // if you also want to change the color of the input, this is the prop you'd use
    }
  }
});

// Render it like this
<ThemeProvider theme={customTheme}>
  <App />
</ThemeProvider>


Rivero answered 18/9, 2019 at 15:11 Comment(2)
It didn't work for me. Instead styling MuiInput you would add: MuiFormLabel: { root: { color: 'grey' }},Corrugate
Also I'd like to point out something this answer fails to mention and would spare me some time if I knew about it before: you have to pay attention to the variant of your TextField. E.g. if it variant='filled' you have to use MuiFilledInput instead of MuiInput. Apart from that this answer is great and exactly what I was looking forVioletteviolin
G
19

You can use the following code to apply the placeholder style.

const styles = (theme: any) => createStyles({
input: {
    '&::placeholder': {
      fontStyle: 'italic',
    },
  },
});

<TextField
  margin="normal"
  variant="outlined"
  placeholder="Filter..."
  InputProps={{
    classes: { input: classes.input}
  }}
/>
Giselle answered 21/8, 2019 at 10:18 Comment(0)
P
15

Use InputLabelProps on TextField

<TextField
   InputLabelProps={{
      style: { color: '#fff', some other Styles }, 
   }}
/>
Prevenient answered 27/10, 2020 at 15:21 Comment(2)
I tried the other solutions to change the placeholder color and they didn't work, this works for meSquirmy
After trying so many solutions, this alone worked for me. Thanks!Gills
L
6

Nothing worked for me except this solution (with MUI 5 and sx-props instead of makestyles etc) :

import React, { FC } from 'react';
import { TextField } from '@mui/material';

const searchStyle = {
  // some other styles
};


const searchField: FC < Props > = () => {
 return ( 
 < TextField 
    sx = {
      searchStyle
    }
    placeholder = {
      "Search"
    }
    inputProps = {
      {
        sx: {
          '&::placeholder': {
            color: 'red',
            opacity: 1, // otherwise firefox shows a lighter color
          },
        },
      }
    }
  />
  );
};

(From https://mcmap.net/q/282172/-how-to-show-both-label-and-placeholder-in-material-ui-textfield)

Lucrece answered 7/4, 2023 at 12:16 Comment(0)
A
4

I haven't found a proper answer to how I can access the inner input element, but as to how one could target the placeholder element using JSS, I found the answer in the source of the Input element, of which TextField is composed.

Basically, it's using the straight css names, just enclosed in quotes: '&::-webkit-input-placeholder': { color: 'blue' }

Artemisia answered 14/12, 2017 at 1:30 Comment(0)
M
4

you can add styling to your input using ::placeholder selector in css it'll work

::-webkit-input-placeholder { /* Chrome/Opera/Safari */
  color: pink;
}
::-moz-placeholder { /* Firefox 19+ */
  color: pink;
}
:-ms-input-placeholder { /* IE 10+ */
  color: pink;
}
:-moz-placeholder { /* Firefox 18- */
  color: pink;
}
Motorboat answered 14/12, 2017 at 7:37 Comment(3)
I wasn't asking generally. The question is tagged material-ui, so it's specifically using JavaScript and JSS. I added a JSS tag now to further emphasize it, but it should be pretty clear from my last paragraph.Artemisia
above css selector is global property for placeholder color change u can use it for material-ui alsoMotorboat
I don't want to change it globally, that's sloppy. otherwise I wouldn't be asking this specific question. I already knew the proper CSS props, as is apparent from the question. It's targetting the specific pseudo element contained inside a TextField that is hard.Artemisia
I
4

To style only the placeholder without the label on top when focused - do the following:

const useStyles = makeStyles(theme => ({
    label: {
         color: 'rgba(0, 0, 0, 0.26)'
    }
}));

const LoginForm = () => {
    const classes = useStyles();

    return (
         <TextField
              ...
              InputLabelProps={{
                   classes: {
                       root: classes.label,
                   }
              }}
         />
    )
}
Ilk answered 18/1, 2021 at 20:42 Comment(2)
What is this an answer to?Artemisia
This is my way to style a placeholder in a TextFieldIlk
A
3

Whether you are using the outlined, filled, or standard variants, the placeholder you might be referring to is actually the label and not the ::placeholder. You can use sx in newest MUI versions.

<TextField
    label="Username"
    variant="standard"
    sx={{ input: { color: "yellow" }, "label": {color: "blue"} }} 
/>
Amon answered 26/2, 2022 at 15:28 Comment(0)
G
2
<TextField
        placeholder='Search...'
        inputProps={{
            style: {color: 'white'}
        }}
/>
Geest answered 13/3, 2023 at 9:43 Comment(0)
E
-4

With styled components I just use:

const StyledTextField = styled(TextField)`
    label {
        font-style: italic;
    }
`;
Eleonoreeleoptene answered 1/6, 2020 at 16:28 Comment(1)
Hi, Eric. That answer is not related to the question. I suggest deleting it to avoid downvotes.Artemisia

© 2022 - 2024 — McMap. All rights reserved.