React Native
TextInput
placeholder styling
CSS
mobile development

How to change styling of TextInput placeholder in React Native?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

The TextInput component in React Native displays placeholder text as a hint to users, but styling that placeholder text is not as straightforward as styling regular text. React Native provides the placeholderTextColor prop for color changes, but other styling properties like font size and weight require workaround techniques. This article covers the available approaches to customize placeholder appearance across both iOS and Android.

Using the placeholderTextColor Prop

The most direct way to change placeholder styling is through the built-in placeholderTextColor prop. This prop accepts any valid color value and applies it specifically to the placeholder text.

jsx
1import React from 'react';
2import { TextInput, View, StyleSheet } from 'react-native';
3
4const PlaceholderExample = () => {
5  return (
6    <View style={styles.container}>
7      <TextInput
8        style={styles.input}
9        placeholder="Enter your email"
10        placeholderTextColor="#999999"
11      />
12      <TextInput
13        style={styles.input}
14        placeholder="Enter your password"
15        placeholderTextColor="rgba(255, 0, 0, 0.5)"
16      />
17      <TextInput
18        style={styles.input}
19        placeholder="Search..."
20        placeholderTextColor="#3498db"
21      />
22    </View>
23  );
24};
25
26const styles = StyleSheet.create({
27  container: { padding: 20 },
28  input: {
29    height: 50,
30    borderWidth: 1,
31    borderColor: '#ccc',
32    borderRadius: 8,
33    paddingHorizontal: 15,
34    fontSize: 16,
35    marginBottom: 12,
36  },
37});
38
39export default PlaceholderExample;

The placeholder text inherits the fontSize, fontFamily, and fontWeight from the style prop applied to the TextInput itself. This means setting those properties on the input automatically affects the placeholder appearance.

Conditional Styling Based on Input State

Since the placeholder inherits the input's text styles, you can use conditional styling to apply different font properties when the input is empty (showing the placeholder) versus when it contains user text. This technique gives you full control over placeholder font size, weight, and style.

jsx
1import React, { useState } from 'react';
2import { TextInput, View, StyleSheet } from 'react-native';
3
4const ConditionalPlaceholder = () => {
5  const [value, setValue] = useState('');
6
7  return (
8    <View style={styles.container}>
9      <TextInput
10        style={[
11          styles.input,
12          value === '' ? styles.placeholder : styles.filled,
13        ]}
14        placeholder="Type something..."
15        placeholderTextColor="#aaa"
16        value={value}
17        onChangeText={setValue}
18      />
19    </View>
20  );
21};
22
23const styles = StyleSheet.create({
24  container: { padding: 20 },
25  input: {
26    height: 50,
27    borderWidth: 1,
28    borderColor: '#ccc',
29    borderRadius: 8,
30    paddingHorizontal: 15,
31  },
32  placeholder: {
33    fontSize: 14,
34    fontStyle: 'italic',
35    fontWeight: '300',
36    color: '#aaa',
37  },
38  filled: {
39    fontSize: 16,
40    fontStyle: 'normal',
41    fontWeight: '400',
42    color: '#333',
43  },
44});
45
46export default ConditionalPlaceholder;

This approach lets you make the placeholder italic and lighter weight while keeping the actual input text bold and larger.

Custom Placeholder with Overlay Text

For full control over placeholder appearance, including layout, multiple colors, or icons, you can render a custom Text component positioned over the TextInput and hide it when the user starts typing.

jsx
1import React, { useState } from 'react';
2import { TextInput, Text, View, StyleSheet } from 'react-native';
3
4const CustomPlaceholder = () => {
5  const [value, setValue] = useState('');
6
7  return (
8    <View style={styles.container}>
9      <View style={styles.inputWrapper}>
10        <TextInput
11          style={styles.input}
12          value={value}
13          onChangeText={setValue}
14        />
15        {value === '' && (
16          <Text style={styles.customPlaceholder} pointerEvents="none">
17            Search for products...
18          </Text>
19        )}
20      </View>
21    </View>
22  );
23};
24
25const styles = StyleSheet.create({
26  container: { padding: 20 },
27  inputWrapper: { position: 'relative' },
28  input: {
29    height: 50,
30    borderWidth: 1,
31    borderColor: '#ccc',
32    borderRadius: 8,
33    paddingHorizontal: 15,
34    fontSize: 16,
35    color: '#333',
36  },
37  customPlaceholder: {
38    position: 'absolute',
39    left: 15,
40    top: 14,
41    fontSize: 15,
42    color: '#b0b0b0',
43    fontFamily: 'Georgia',
44    letterSpacing: 0.5,
45  },
46});
47
48export default CustomPlaceholder;

The pointerEvents="none" prop on the Text component ensures that tapping the placeholder area still focuses the TextInput underneath.

Platform-Specific Considerations

iOS and Android render placeholder text slightly differently. Android tends to add extra padding around the TextInput, and placeholder vertical alignment can vary. Use Platform.select or platform-specific files to handle these differences.

jsx
1import { Platform, StyleSheet } from 'react-native';
2
3const styles = StyleSheet.create({
4  input: {
5    height: 50,
6    borderWidth: 1,
7    borderColor: '#ccc',
8    borderRadius: 8,
9    paddingHorizontal: 15,
10    fontSize: 16,
11    ...Platform.select({
12      ios: {
13        paddingVertical: 12,
14      },
15      android: {
16        paddingVertical: 8,
17        textAlignVertical: 'center',
18      },
19    }),
20  },
21});

On Android, the textAlignVertical property controls vertical text placement within the input. Setting it to 'center' ensures both placeholder and input text are vertically centered.

Integration with styled-components

If your project uses styled-components, you can encapsulate placeholder styling in a reusable styled component. The attrs method is useful for setting default props like placeholderTextColor.

jsx
1import styled from 'styled-components/native';
2
3const StyledInput = styled.TextInput.attrs(props => ({
4  placeholderTextColor: props.placeholderColor || '#999',
5}))`
6  height: 50px;
7  border-width: 1px;
8  border-color: ${props => props.error ? '#e74c3c' : '#ccc'};
9  border-radius: 8px;
10  padding: 0 15px;
11  font-size: 16px;
12  color: #333;
13  background-color: ${props => props.disabled ? '#f5f5f5' : '#fff'};
14`;
15
16// Usage
17const FormScreen = () => (
18  <View>
19    <StyledInput placeholder="Username" />
20    <StyledInput
21      placeholder="Required field"
22      placeholderColor="#e74c3c"
23      error
24    />
25  </View>
26);

This approach keeps placeholder configuration close to the rest of the component's styling and makes it easy to apply consistent placeholder colors across your entire application.

Common Pitfalls

  • Forgetting placeholderTextColor on Android: On Android, the default placeholder color may be very faint or inconsistent across devices. Always set placeholderTextColor explicitly for a predictable result.
  • Applying color style expecting it to affect the placeholder: The color style property on TextInput only affects the typed text, not the placeholder. Use placeholderTextColor for placeholder color and conditional styles for other properties.
  • Using opacity to style the placeholder: Setting opacity on the entire TextInput dims both the placeholder and the typed text. Use placeholderTextColor with an alpha channel instead.
  • Ignoring textAlignVertical on Android: Without textAlignVertical: 'center', placeholder text on Android may appear shifted toward the top of the input, creating a visual mismatch with iOS.
  • Not testing on both platforms: Placeholder rendering differs between iOS and Android simulators and physical devices. Always verify styling on both platforms before shipping.

Summary

  • Use the placeholderTextColor prop for straightforward placeholder color changes on both iOS and Android.
  • Apply conditional styles based on whether the input is empty to control font size, weight, and style of the placeholder.
  • For advanced placeholder layouts, overlay a custom Text component with pointerEvents="none" on top of the TextInput.
  • Handle platform differences with Platform.select and use textAlignVertical on Android for consistent vertical alignment.
  • With styled-components, use the attrs method to set default placeholderTextColor values in reusable styled inputs.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.