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:
Breakpoint Min width Typical device sm640px Large phones (landscape) md768px Tablets (portrait) lg1024px Tablets (landscape), small laptops xl1280px Laptops, desktops 2xl1536px Large 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:
Stack to row
Responsive grid
Adaptive spacing
< 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 >
< View className = "flex-row flex-wrap gap-4" >
< View className = "w-full sm:w-1/2 lg:w-1/3 bg-purple-500 p-4 rounded-lg" >
< Text className = "text-white" > Item 1 </ Text >
</ View >
< View className = "w-full sm:w-1/2 lg:w-1/3 bg-purple-500 p-4 rounded-lg" >
< Text className = "text-white" > Item 2 </ Text >
</ View >
< View className = "w-full sm:w-1/2 lg:w-1/3 bg-purple-500 p-4 rounded-lg" >
< Text className = "text-white" > Item 3 </ Text >
</ View >
</ View >
< View className = "px-4 sm:px-6 md:px-8 lg:px-12" >
< View className = "max-w-screen-lg mx-auto" >
< Text className = "text-xl md:text-2xl lg:text-3xl" >
Centered content with responsive spacing
</ 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:
show-on-large.tsx
show-on-mobile.tsx
breakpoint-specific.tsx
// 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:
Container Min 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 >
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:
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 >
);
}
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 >
);
}
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 >
);
}
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:
responsive-image.tsx
image-grid.tsx
hero-image.tsx
< 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
Mobile-first thinking : Design for the smallest screen first
Touch targets : Ensure buttons are at least 44x44 points on all screen sizes
Readable text : Maintain appropriate text sizes (minimum 16px body text)
Generous spacing : Provide adequate padding and margins, especially on mobile
Content priority : Most important content should be visible on small screens
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