React Native course ยท Module 2: Lists and styles

Responsiveness and Dimensions

3 min read ยท
In this lesson3

Mobile applications need to work on different screen sizes. Let's learn responsiveness techniques!

Dimensions API

import { View, Text, StyleSheet, Dimensions, useWindowDimensions } from 'react-native';

// Static dimensions (at app startup)
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window');

export default function DimensionsExample() {
  // Hook - updates on screen rotation
  const { width, height } = useWindowDimensions();

  const isLandscape = width > height;
  const isTablet = width >= 768;

  return (
    <View style={styles.container}>
      <Text style={styles.text}>Width: {width}px</Text>
      <Text style={styles.text}>Height: {height}px</Text>
      <Text style={styles.text}>
        Orientation: {isLandscape ? 'Landscape' : 'Portrait'}
      </Text>
      <Text style={styles.text}>
        Device: {isTablet ? 'Tablet' : 'Phone'}
      </Text>

      {/* Responsive cards */}
      <View style={[
        styles.cardContainer,
        isLandscape && styles.cardContainerLandscape
      ]}>
        <View style={[styles.card, { width: width * 0.4 }]}>
          <Text style={styles.cardText}>Card 1</Text>
        </View>
        <View style={[styles.card, { width: width * 0.4 }]}>
          <Text style={styles.cardText}>Card 2</Text>
        </View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
    backgroundColor: '#1a5276',
  },
  text: {
    fontSize: 16,
    color: '#fff',
    marginBottom: 8,
  },
  cardContainer: {
    flexDirection: 'column',
    gap: 16,
    marginTop: 20,
  },
  cardContainerLandscape: {
    flexDirection: 'row',
  },
  card: {
    backgroundColor: '#2c3e50',
    padding: 20,
    borderRadius: 12,
    minWidth: 150,
  },
  cardText: {
    color: '#fff',
    textAlign: 'center',
  },
});

Percentage Dimensions

import { View, StyleSheet } from 'react-native';

export default function PercentageExample() {
  return (
    <View style={styles.container}>
      {/* Percentages work! */}
      <View style={styles.halfWidth} />
      <View style={styles.thirdWidth} />
      <View style={styles.fullWidth} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    gap: 10,
    backgroundColor: '#1a5276',
  },
  halfWidth: {
    width: '50%',
    height: 60,
    backgroundColor: '#e74c3c',
    borderRadius: 8,
  },
  thirdWidth: {
    width: '33.33%',
    height: 60,
    backgroundColor: '#2ecc71',
    borderRadius: 8,
  },
  fullWidth: {
    width: '100%',
    height: 60,
    backgroundColor: '#3498db',
    borderRadius: 8,
  },
});

Responsive Grid

import { View, Text, StyleSheet, useWindowDimensions } from 'react-native';

export default function ResponsiveGrid() {
  const { width } = useWindowDimensions();

  // Calculate number of columns based on width
  const numColumns = width >= 768 ? 4 : width >= 480 ? 3 : 2;
  const itemWidth = (width - 40 - (numColumns - 1) * 10) / numColumns;

  const items = Array.from({ length: 12 }, (_, i) => i + 1);

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Grid: {numColumns} columns</Text>
      <View style={styles.grid}>
        {items.map((item) => (
          <View
            key={item}
            style={[styles.gridItem, { width: itemWidth, height: itemWidth }]}
          >
            <Text style={styles.itemText}>{item}</Text>
          </View>
        ))}
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#1a5276',
  },
  title: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#fff',
    marginBottom: 16,
  },
  grid: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 10,
  },
  gridItem: {
    backgroundColor: '#2c3e50',
    borderRadius: 12,
    justifyContent: 'center',
    alignItems: 'center',
  },
  itemText: {
    color: '#fff',
    fontSize: 20,
    fontWeight: 'bold',
  },
});
Code for this lesson: App.tsx
import React from 'react';
import { View, Text, StyleSheet, useWindowDimensions } from 'react-native';

export default function App() {
  const { width } = useWindowDimensions();

  // TODO: calculate the number of columns based on the screen width.
  //   If width >= 768, set numColumns to 4, otherwise to 2.
  //   Example: const numColumns = width >= 768 ? 4 : 2;
  const numColumns = 2;

  const itemWidth = (width - 40 - (numColumns - 1) * 10) / numColumns;
  const items = Array.from({ length: 8 }, (_, i) => i + 1);

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Treasures of Atlantis: {numColumns} columns</Text>
      <View style={styles.grid}>
        {items.map((item) => (
          <View
            key={item}
            style={[styles.gridItem, { width: itemWidth, height: itemWidth }]}
          >
            <Text style={styles.itemText}>{item}</Text>
          </View>
        ))}
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#1a5276',
  },
  title: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#fff',
    marginBottom: 16,
  },
  grid: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 10,
  },
  gridItem: {
    backgroundColor: '#2c3e50',
    borderRadius: 12,
    justifyContent: 'center',
    alignItems: 'center',
  },
  itemText: {
    color: '#fff',
    fontSize: 20,
    fontWeight: 'bold',
  },
});

Docs entries used in this lesson

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. How do you get the screen width using the Dimensions API?

  2. 2. Does React Native support percentage values in styles?

Hands-on tasks in the game

  • Horizontal ordering

    Arrange the correct usage of the useWindowDimensions hook:

  • Code editor

    Complete the responsive grid code.

Useful articles