Skip to main content

Overview

NativeWind brings Tailwind’s responsive design system to React Native, allowing you to create layouts that adapt to different screen sizes, orientations, and device types.

Breakpoint system

NativeWind uses Tailwind’s default breakpoint system, which applies styles at different screen widths:
BreakpointMin widthTypical device
sm640pxLarge phones (landscape)
md768pxTablets (portrait)
lg1024pxTablets (landscape), small laptops
xl1280pxLaptops, desktops
2xl1536pxLarge desktops

Mobile-first approach

NativeWind follows a mobile-first methodology. Styles without breakpoint prefixes apply to all screen sizes, while breakpoint prefixes apply styles at that breakpoint and above:
import { View, Text } from 'react-native';

export default function ResponsiveLayout() {
  return (
    <View className="p-4 md:p-6 lg:p-8">
      <Text className="text-lg md:text-xl lg:text-2xl">
        Text size adapts to screen width
      </Text>
    </View>
  );
}
In the example above, p-4 applies on all screens, md:p-6 applies at 768px and above, and lg:p-8 applies at 1024px and above.

Common responsive patterns

Responsive layouts

Create layouts that stack on mobile and display side-by-side on larger screens:
<View className="flex-col md:flex-row gap-4">
  <View className="flex-1 bg-blue-500 p-4 rounded-lg">
    <Text className="text-white">Panel 1</Text>
  </View>
  <View className="flex-1 bg-green-500 p-4 rounded-lg">
    <Text className="text-white">Panel 2</Text>
  </View>
</View>

Responsive typography

Adjust text sizes, weights, and spacing based on screen size:
<View className="p-4 md:p-8">
  <Text className="text-2xl md:text-3xl lg:text-4xl font-bold mb-2 md:mb-4">
    Responsive Heading
  </Text>
  <Text className="text-sm md:text-base lg:text-lg text-gray-600 leading-6 md:leading-7">
    Body text that scales appropriately for different screen sizes,
    maintaining readability across devices.
  </Text>
</View>

Hide and show elements

Show or hide elements at specific breakpoints:
// Hidden on mobile, visible on tablets and up
<View className="hidden md:flex">
  <Text>This appears only on tablets and larger</Text>
</View>

Container queries

NativeWind supports container queries, allowing components to respond to their parent container’s size rather than the viewport:

Setting up containers

Mark an element as a container using the @container directive:
<View className="@container">
  <View className="p-4 @lg:p-8">
    <Text className="text-base @lg:text-xl">
      This text size responds to the container, not the viewport
    </Text>
  </View>
</View>

Container query breakpoints

Container queries use the @ prefix:
ContainerMin width
@sm384px
@md448px
@lg512px
@xl576px
@2xl672px

Practical example

function ProductCard({ featured }) {
  return (
    <View className="@container bg-white dark:bg-gray-800 rounded-xl p-4">
      <View className="flex-col @md:flex-row gap-4">
        <View className="w-full @md:w-1/3">
          <Image
            source={{ uri: 'https://via.placeholder.com/300' }}
            className="w-full h-48 @md:h-full rounded-lg"
          />
        </View>
        <View className="flex-1">
          <Text className="text-lg @md:text-xl font-bold text-gray-900 dark:text-white">
            Product Title
          </Text>
          <Text className="text-sm @md:text-base text-gray-600 dark:text-gray-300 mt-2">
            Product description that adapts to container size
          </Text>
        </View>
      </View>
    </View>
  );
}
Container type queries (container-type) and style-based container queries are not supported in React Native.

Orientation queries

Respond to device orientation changes:
<View className="p-4 portrait:flex-col landscape:flex-row gap-4">
  <View className="flex-1 bg-blue-500 p-6 rounded-lg">
    <Text className="text-white text-center">Panel 1</Text>
  </View>
  <View className="flex-1 bg-green-500 p-6 rounded-lg">
    <Text className="text-white text-center">Panel 2</Text>
  </View>
</View>

Platform-aware responsive design

Combine breakpoints with platform variants for precise control:
<View className="p-4 md:p-8 native:max-w-full web:max-w-screen-lg web:mx-auto">
  <Text className="text-xl md:text-2xl ios:font-['System'] android:font-['SystemAndroid']">
    Platform and size-aware styling
  </Text>
</View>

Building responsive components

Create reusable components that adapt to different contexts:
1

Define mobile-first base styles

Start with styles that work well on the smallest screens:
function Card({ children, title }) {
  return (
    <View className="bg-white rounded-lg p-4 shadow-md">
      <Text className="text-lg font-bold mb-2">
        {title}
      </Text>
      <View>{children}</View>
    </View>
  );
}
2

Add breakpoint-specific enhancements

Layer on responsive styles for larger screens:
function Card({ children, title }) {
  return (
    <View className="bg-white rounded-lg p-4 md:p-6 lg:p-8 shadow-md md:shadow-lg">
      <Text className="text-lg md:text-xl lg:text-2xl font-bold mb-2 md:mb-4">
        {title}
      </Text>
      <View>{children}</View>
    </View>
  );
}
3

Consider container queries for flexibility

Make components truly reusable with container queries:
function Card({ children, title }) {
  return (
    <View className="@container bg-white rounded-lg p-4 @md:p-6 @lg:p-8 shadow-md">
      <Text className="text-lg @md:text-xl @lg:text-2xl font-bold mb-2 @md:mb-4">
        {title}
      </Text>
      <View>{children}</View>
    </View>
  );
}
4

Test across devices and orientations

Verify your component works well in all contexts:
// Test in different container sizes
<View className="w-full">          {/* Mobile */}
  <Card title="Full Width">Content</Card>
</View>

<View className="w-96">           {/* Tablet */}
  <Card title="Medium Width">Content</Card>
</View>

<View className="w-full max-w-4xl"> {/* Desktop */}
  <Card title="Large Width">Content</Card>
</View>

Responsive images

Handle images responsively with aspect ratios and sizing:
<View className="w-full aspect-video md:aspect-[4/3] lg:aspect-square">
  <Image
    source={{ uri: 'https://via.placeholder.com/800x600' }}
    className="w-full h-full rounded-lg"
    resizeMode="cover"
  />
</View>

Testing responsive designs

Test your responsive layouts thoroughly:
Test on actual devices in both orientations:
  • Small phones (iPhone SE, small Android phones)
  • Standard phones (iPhone 14, Pixel 6)
  • Large phones (iPhone 14 Pro Max, Pixel 6 Pro)
  • Tablets (iPad, Android tablets)
  • Foldable devices (Galaxy Z Fold)
Use device simulators with various configurations:
# iOS Simulator - different devices
npx expo start --ios
# Select different device types from simulator menu

# Android Emulator - various screen sizes
npx expo start --android
When testing web builds, use browser dev tools:
npx expo start --web
# Open browser dev tools
# Toggle device toolbar (Cmd+Shift+M / Ctrl+Shift+M)
# Test different viewport sizes
Test dynamic scenarios:
  • Rotating devices between portrait and landscape
  • Split-screen multitasking (iPad, Android)
  • Resizing windows (web)
  • Different text size settings (accessibility)

Best practices

Start with a mobile design and progressively enhance for larger screens. This ensures your app works well on the most common device types.

Design principles

  1. Mobile-first thinking: Design for the smallest screen first
  2. Touch targets: Ensure buttons are at least 44x44 points on all screen sizes
  3. Readable text: Maintain appropriate text sizes (minimum 16px body text)
  4. Generous spacing: Provide adequate padding and margins, especially on mobile
  5. Content priority: Most important content should be visible on small screens

Performance considerations

Avoid excessive breakpoint variants that could bloat your stylesheet. Use them strategically where layout changes are necessary.
// Good: Strategic use of breakpoints
<View className="p-4 md:p-8 flex-col md:flex-row">
  <Text className="text-lg md:text-xl">Content</Text>
</View>

// Avoid: Excessive breakpoint variants
<View className="p-4 sm:p-5 md:p-6 lg:p-7 xl:p-8 2xl:p-9">
  <Text className="text-base sm:text-lg md:text-xl lg:text-2xl xl:text-3xl">Content</Text>
</View>

Accessibility in responsive design

Ensure your responsive layouts remain accessible:
  • Maintain focus order that makes sense on all screen sizes
  • Ensure interactive elements remain easily tappable
  • Test with screen readers on different devices
  • Respect user font size preferences
  • Provide sufficient color contrast at all sizes

Common responsive patterns

<View className="flex-col lg:flex-row">
  {/* Sidebar - full width on mobile, fixed width on desktop */}
  <View className="w-full lg:w-64 bg-gray-100 dark:bg-gray-800 p-4">
    <Text className="font-bold mb-4">Navigation</Text>
    {/* Navigation items */}
  </View>
  
  {/* Main content */}
  <View className="flex-1 p-4 md:p-8">
    <Text className="text-2xl md:text-3xl font-bold mb-4">
      Main Content
    </Text>
    {/* Content */}
  </View>
</View>

Card grid

<View className="flex-row flex-wrap gap-4">
  {items.map((item) => (
    <View
      key={item.id}
      className="w-full sm:w-[calc(50%-0.5rem)] lg:w-[calc(33.333%-0.667rem)] bg-white rounded-xl p-4 shadow-md"
    >
      <Text className="text-lg font-bold">{item.title}</Text>
      <Text className="text-gray-600 mt-2">{item.description}</Text>
    </View>
  ))}
</View>

Dashboard layout

<View className="flex-1 p-4 md:p-8">
  {/* Header */}
  <View className="mb-6 md:mb-8">
    <Text className="text-2xl md:text-3xl lg:text-4xl font-bold">
      Dashboard
    </Text>
  </View>
  
  {/* Stats grid */}
  <View className="flex-row flex-wrap gap-4 mb-6">
    <View className="w-full sm:w-[calc(50%-0.5rem)] lg:w-[calc(25%-0.75rem)] bg-white rounded-xl p-6">
      <Text className="text-4xl font-bold text-blue-500">1,234</Text>
      <Text className="text-gray-600 mt-2">Total Users</Text>
    </View>
    {/* More stat cards */}
  </View>
  
  {/* Main content */}
  <View className="flex-col lg:flex-row gap-4">
    <View className="flex-1 bg-white rounded-xl p-6">
      <Text className="text-xl font-bold mb-4">Recent Activity</Text>
      {/* Activity list */}
    </View>
    <View className="w-full lg:w-80 bg-white rounded-xl p-6">
      <Text className="text-xl font-bold mb-4">Quick Actions</Text>
      {/* Action buttons */}
    </View>
  </View>
</View>

Next steps

Styling

Learn the fundamentals of styling with NativeWind

Theming

Create consistent themes across screen sizes

Custom styles

Build custom utilities for responsive design

Animations

Add responsive animations to your layouts