Working with Styling and Layout
1. Using StyleSheet API
| Property | Values | Description |
|---|---|---|
| StyleSheet.create() | object |
Creates a StyleSheet object from a style dictionary |
| StyleSheet.flatten() | object |
Flattens nested style objects into a single style object |
Example: Creating a StyleSheet
import { StyleSheet } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff'
},
text: {
fontSize: 18,
color: '#333'
}
});
Example: Using StyleSheet in Component
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const MyComponent = () => {
return (
<View style={styles.container}>
<Text style={styles.text}>Hello World</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
text: {
fontSize: 18,
color: '#333'
}
});
Note: StyleSheet.create() is optimized for performance by pre-processing styles into a native object.
2. Implementing Inline Styles
| Property | Values | Description |
|---|---|---|
| style | object | array |
Accepts a style object or an array of style objects for inline styling |
Example: Basic inline style object
{'backgroundColor': '#ff0000', 'padding': 10}
Example: Using style arrays for cascading styles
[
{'backgroundColor': '#ff0000'},
{'padding': 10},
{'borderRadius': 5}
]
Note: Inline styles in Expo are processed by the React Native StyleSheet module and may not support all CSS properties.
3. Using Flexbox Layout
| Property | Values | Description |
|---|---|---|
| flexDirection | 'row', 'row-reverse', 'column', 'column-reverse' |
Defines the direction of the flex container's main axis |
| flexWrap | 'nowrap', 'wrap', 'wrap-reverse' |
Controls whether flex items wrap to new lines |
| justifyContent | 'flex-start', 'flex-end', 'center', 'space-between', 'space-around' |
Aligns items along the main axis |
| alignItems | 'flex-start', 'flex-end', 'center', 'stretch', 'baseline' |
Aligns items along the cross axis |
| alignContent | 'flex-start', 'flex-end', 'center', 'space-between', 'space-around', 'stretch' |
Aligns flex lines when wrapping is enabled |
Example: Basic Flexbox Layout
{'import { View } from "react-native";\n\nconst FlexContainer = () => (\n <View style={{\n flexDirection: "row",\n justifyContent: "space-between",\n alignItems: "center",\n height: 200\n }}>\n <View style={{ flex: 1, backgroundColor: "red" }} />\n <View style={{ flex: 2, backgroundColor: "blue" }} />\n <View style={{ flex: 1, backgroundColor: "green" }} />\n </View>\n);'}
Example: Flex Wrap and Align Content
{'import { View } from "react-native";\n\nconst FlexWrapExample = () => (\n <View style={{\n flexDirection: "row",\n flexWrap: "wrap",\n alignContent: "flex-start",\n height: 300\n }}>\n <View style={{ width: 100, height: 100, backgroundColor: "lightblue" }} />\n <View style={{ width: 100, height: 100, backgroundColor: "lightgreen" }} />\n <View style={{ width: 100, height: 100, backgroundColor: "lightcoral" }} />\n </View>\n);'}
4. Setting Dimensions
| Property | Values | Description |
|---|---|---|
| width | number, 'auto' |
Sets the width of the component. Can be a number (pixels) or 'auto'. |
| height | number, 'auto' |
Sets the height of the component. Can be a number (pixels) or 'auto'. |
| minWidth | number |
Sets the minimum width of the component. |
| maxWidth | number |
Sets the maximum width of the component. |
| minHeight | number |
Sets the minimum height of the component. |
| maxHeight | number |
Sets the maximum height of the component. |
Example: Setting Dimensions
{'import React from "react";\nimport { View } from "react-native";\n\nconst MyComponent = () => {\n return (\n <View style={{ width: 200, height: 100 }}>\n <View style={{ width: "50%", height: 50 }}></View>\n </View>\n );\n};\n\nexport default MyComponent;'}
5. Using Positioning
| Property | Values | Description |
|---|---|---|
| position | absolute, relative, fixed |
Sets the positioning method of the element |
| top | number, percentage |
Offsets the element from the top of its container |
| left | number, percentage |
Offsets the element from the left of its container |
| right | number, percentage |
Offsets the element from the right of its container |
| bottom | number, percentage |
Offsets the element from the bottom of its container |
Note: When using
absolute positioning, the element is removed from the normal document flow and positioned relative to its nearest positioned ancestor.
6. Implementing Margins and Padding
| Property | Values | Description |
|---|---|---|
| margin | 0, 10, 'auto' |
Sets space around the component |
| padding | 0, 10 |
Sets space inside the component |
7. Using Platform-Specific Styles
Expo provides several ways to apply platform-specific styles to components, allowing you to customize the appearance and behavior of your app based on the target platform (iOS, Android, Web).
| Approach | Description | Usage Example |
|---|---|---|
| Platform.select() | Selects styles based on the platform using a function that returns different style objects for each platform. | import { Platform } from 'react-native';\n\nconst styles = StyleSheet.create({\n container: {\n padding: Platform.select({\n ios: 20,\n android: 15,\n web: 10\n })\n }\n}); |
| Platform.OS | Allows conditional rendering or styling based on the current platform using a string comparison. | import { Platform } from 'react-native';\n\nconst padding = Platform.OS === 'ios' ? 20 : 15; |
| Platform.isIOS / Platform.isAndroid | Boolean flags indicating whether the app is running on iOS or Android. | import { Platform } from 'react-native';\n\nif (Platform.isIOS) {\n // iOS-specific logic\n}\n\nif (Platform.isAndroid) {\n // Android-specific logic\n} |
Example: Conditional Style Application
import React from 'react';\nimport { View, Text, StyleSheet, Platform } from 'react-native';\n\nconst MyComponent = () => {\n return (\n <View style={styles.container}>\n <Text style={styles.text}>Hello World</Text>\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {\n padding: Platform.select({\n ios: 20,\n android: 15,\n web: 10\n }),\n backgroundColor: Platform.select({\n ios: '#f0f0f0',\n android: '#e0e0e0',\n web: '#d0d0d0'\n })\n },\n text: {\n fontSize: Platform.select({\n ios: 18,\n android: 16,\n web: 14\n })\n }\n});
Note: Platform-specific styles are particularly useful for handling differences in UI components like navigation bars, status bar heights, and touch targets between platforms.
8. Creating Responsive Layouts
| Property | Description | Values |
|---|---|---|
| flex | Defines the flexibility of a view | number |
| flexDirection | Defines the direction of flex items | 'row' | 'row-reverse' | 'column' | 'column-reverse' |
| justifyContent | Defines how flex items are aligned along the main axis | 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly' |
| alignItems | Defines how flex items are aligned along the cross axis | 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline' |
| alignSelf | Defines how a single flex item is aligned along the cross axis | 'auto' | 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline' |
| flexWrap | Defines whether flex items are forced onto one line or can wrap onto multiple lines | 'nowrap' | 'wrap' | 'wrap-reverse' |
Example: Basic Flexbox Layout
{'import React from "react";\nimport { View, Text } from "react-native";\n\nconst FlexboxExample = () => {\n return (\n <View style={{ flex: 1, flexDirection: "row", justifyContent: "space-between" }}>\n <View style={{ flex: 1, backgroundColor: "red" }}>\n <Text>Left</Text>\n </View>\n <View style={{ flex: 1, backgroundColor: "blue" }}>\n <Text>Right</Text>\n </View>\n </View>\n );\n};\n\nexport default FlexboxExample;'}
Example: Responsive Grid
{'import React from "react";\nimport { View, Text } from "react-native";\n\nconst ResponsiveGrid = () => {\n return (\n <View style={{ flex: 1, flexDirection: "column" }}>\n <View style={{ flex: 1, flexDirection: "row" }}>\n <View style={{ flex: 1, backgroundColor: "lightblue" }}>\n <Text>Item 1</Text>\n </View>\n <View style={{ flex: 1, backgroundColor: "lightgreen" }}>\n <Text>Item 2</Text>\n </View>\n </View>\n <View style={{ flex: 1, backgroundColor: "lightyellow" }}>\n <Text>Item 3</Text>\n </View>\n </View>\n );\n};\n\nexport default ResponsiveGrid;'}
Note: Use
flex to control how views expand or shrink within a container.
Warning: Avoid using fixed dimensions in responsive layouts. Use
flex properties for better adaptability.
Responsive Layout Tips
- Use
flexDirectionto define the layout direction. - Apply
justifyContentandalignItemsto control alignment. - Use
flexWrapfor wrapping elements on smaller screens. - Combine
flexwithwidthandheightfor more complex layouts.
9. Using Styled Components
Styled Components is a CSS-in-JS library that allows you to write actual CSS code in your JavaScript files. It provides a way to style React components with scoped styles and dynamic styling capabilities.
| Feature | Description | Usage |
|---|---|---|
| styled() | Creates a styled component with specific CSS rules | const StyledButton = styled(Button)` color: red; `; |
| Theming | Supports theming through ThemeProvider |
<ThemeProvider theme={theme}>...</ThemeProvider> |
| Dynamic Styles | Allows dynamic styling based on props or state | const StyledDiv = styled.div` color: ${props => props.color}; `; |
Example: Basic Styled Component
import styled from 'styled-components';
const StyledButton = styled.button`
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: #0056b3;
}
`;
export default function App() {
return <StyledButton>Click me</StyledButton>;
}
Example: Dynamic Styling with Props
import styled from 'styled-components';
const DynamicText = styled.p`
font-size: ${props => props.size || '16px'};
color: ${props => props.color || '#000'};
margin: ${props => props.margin || '0'};
`;
export default function App() {
return (
<div>
<DynamicText size="20px" color="blue">Large Blue Text</DynamicText>
<DynamicText size="12px" color="red">Small Red Text</DynamicText>
</div>
);
}
Note: Styled Components is compatible with Expo and can be used in both React Native and Web environments.
10. Implementing Custom Fonts
| Property | Description | Example |
|---|---|---|
| fontFamily | Specifies the font family to use for text elements. | fontFamily: 'MyCustomFont' |
| fontStyle | Defines the font style (e.g., normal, italic). | fontStyle: 'italic' |
| fontWeight | Specifies the font weight (e.g., normal, bold). | fontWeight: 'bold' |
Example: Using Custom Font in Text Component
<Text style={{ fontFamily: 'MyCustomFont', fontSize: 18 }}>
This text uses a custom font.
</Text>
Example: Loading Custom Font from Assets
import { useFonts } from 'expo-font';
import { Text, View } from 'react-native';
export default function App() {
const [fontsLoaded] = useFonts({
'MyCustomFont': require('./assets/fonts/MyCustomFont.ttf'),
});
if (!fontsLoaded) {
return <View></View>;
}
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ fontFamily: 'MyCustomFont' }}>Loaded Custom Font</Text>
</View>
);
}
Note: Ensure that the font file is included in your project's assets and correctly referenced.
11. Using Design Tokens
Design tokens are abstract values used to maintain consistency across an application's UI. In Expo, design tokens can be implemented using JavaScript objects or JSON files to define colors, spacing, typography, and other UI properties.
| Token Type | Example Value | Description |
|---|---|---|
| colors.primary | "#007AFF" |
Primary brand color |
| spacing.small | 8 |
Small spacing unit (in pixels) |
| typography.fontSize.base | 16 |
Base font size in pixels |
Example: Using Design Tokens in a Component
import { StyleSheet } from 'react-native';\n\nconst tokens = {\n colors: {\n primary: '#007AFF',\n secondary: '#FF9500',\n },\n spacing: {\n small: 8,\n medium: 16,\n },\n};\n\nconst styles = StyleSheet.create({\n container: {\n backgroundColor: tokens.colors.primary,\n padding: tokens.spacing.medium,\n },\n});
Note: Design tokens should be centralized in a single file or module to ensure consistency across components.
Best Practices for Design Tokens
- Define tokens at the project level to ensure reuse across components.
- Use semantic names for tokens (e.g.,
primary,secondary) rather than hardcoded values. - Support light and dark mode by defining token variations for each theme.
12. Creating Style Abstractions
Example: Using StyleSheet.create
import { StyleSheet, Text, View } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
fontSize: 18,
color: '#333',
},
});
export default function MyComponent() {
return (
<View style={styles.container}>
<Text style={styles.text}>Hello, Expo!</Text>
</View>
);
}
| Property | Description | Usage |
|---|---|---|
| StyleSheet.create() | Creates an optimized stylesheet | Used to define styles that are cached and reused |
| flex | Controls how views expand to fill available space | Accepts integer values (0 or more) |
| justifyContent | Aligns items along the main axis | Values: 'flex-start', 'flex-end', 'center', 'space-between', 'space-around' |
| alignItems | Aligns items along the cross axis | Values: 'flex-start', 'flex-end', 'center', 'stretch' |
Note: StyleSheet.create() helps optimize performance by caching styles and avoiding unnecessary re-renders.
Example: Using Custom Theme
import { StyleSheet } from 'react-native';
const theme = {
colors: {
primary: '#007AFF',
secondary: '#8E8E93',
},
fonts: {
large: 24,
medium: 18,
small: 14,
},
};
const styles = StyleSheet.create({
header: {
backgroundColor: theme.colors.primary,
padding: 16,
fontSize: theme.fonts.large,
},
text: {
color: theme.colors.secondary,
fontSize: theme.fonts.medium,
},
});
export default function ThemedComponent() {
return (
<View style={styles.container}>
<Text style={styles.header}>Themed Header</Text>
<Text style={styles.text}>Themed Text</Text>
</View>
);
}