Skip to main content

Overview

Uniwind provides built-in platform selectors that allow you to apply styles conditionally based on the platform your app is running on. This is essential for creating platform-specific user experiences in React Native.
Platform selectors are resolved at runtime and automatically apply the correct styles for the current platform.

Basic Usage

Use platform selectors directly in your className prop with the syntax platform:utility:
import { View, Text } from 'react-native'

export const PlatformExample = () => (
  <View className="ios:bg-red-500 android:bg-blue-500 web:bg-green-500">
    <Text className="ios:text-white android:text-white web:text-black">
      This component has different styles on each platform
    </Text>
  </View>
)

Why Use Platform Selectors?

Platform selectors are superior to React Native’s Platform.select() API for several reasons:
import { Platform } from 'react-native'
import { View } from 'react-native'

<View
  className={Platform.select({
    ios: 'bg-red-500',
    android: 'bg-blue-500',
  })}
/>
Downsides:
  • Requires importing Platform API
  • More verbose syntax
  • Cannot combine with other utilities easily
  • Less readable when multiple platform conditions are needed
import { View } from 'react-native'

<View className="ios:bg-red-500 android:bg-blue-500" />
Benefits:
  • Clean, declarative syntax
  • No extra imports needed
  • Easy to combine with other Tailwind utilities
  • Better readability and maintainability
  • Works seamlessly with theme variants

Supported Platforms

ios
selector
Targets iOS devices (iPhone, iPad). Styles are applied only when running on iOS.
android
selector
Targets Android devices. Styles are applied only when running on Android.
web
selector
Targets web browsers. Styles are applied only when running in a web environment (e.g., React Native Web).
native
selector
Targets both iOS and Android platforms. Styles are applied on mobile platforms but not on web. This is a convenient shorthand when you want to apply the same styles to both iOS and Android.
tv
selector
Targets all TV platforms (Apple TV and Android TV). Styles are applied only when running on a TV device. Requires isTV: true in your metro.config.js.
apple-tv
selector
Targets Apple TV only. Styles are applied only when running on tvOS. Requires isTV: true in your metro.config.js.
android-tv
selector
Targets Android TV only. Styles are applied only when running on Android TV. Requires isTV: true in your metro.config.js.

Native Selector

The native: selector is a convenient shorthand for targeting both iOS and Android platforms simultaneously. Instead of writing duplicate styles for both platforms, you can use native: to apply styles to all mobile platforms at once.

❌ Verbose: Duplicate platform styles

import { View, Text } from 'react-native'

<View className="ios:bg-blue-500 android:bg-blue-500 web:bg-gray-500">
  <Text className="ios:text-white android:text-white web:text-black">
    Mobile vs Web styling
  </Text>
</View>

✅ Concise: Using native: selector

import { View, Text } from 'react-native'

<View className="native:bg-blue-500 web:bg-gray-500">
  <Text className="native:text-white web:text-black">
    Mobile vs Web styling
  </Text>
</View>
Use native: when your iOS and Android styles are identical, and only web differs. This reduces duplication and improves maintainability.

TV Selectors

Available in Uniwind 1.5.0+ Uniwind supports TV platforms with dedicated selectors. To enable TV support, set isTV: true in your metro.config.js.
import { View, Text } from 'react-native'

// Target all TV platforms
<View className="p-4 tv:p-8">
  <Text className="text-base tv:text-xl">
    Larger text and spacing on TV
  </Text>
</View>

// Target specific TV platforms
<View className="android-tv:bg-black apple-tv:bg-gray-900">
  <Text className="text-white">Platform-specific TV styling</Text>
</View>
The tv: selector targets both Apple TV and Android TV, similar to how native: targets both iOS and Android. Use apple-tv: or android-tv: when you need platform-specific TV styles.
On TV platforms, navigation is focus-based rather than touch-based. Use the focus: state selector on Pressable, TouchableOpacity, and TouchableHighlight to style the currently focused element.

Examples

Platform-Specific Colors

import { View, Text } from 'react-native'

export const PlatformColors = () => (
  <View className="ios:bg-blue-500 android:bg-green-500 web:bg-purple-500 p-4">
    <Text className="ios:text-white android:text-white web:text-white">
      Different background color on each platform
    </Text>
  </View>
)

Platform-Specific Spacing

import { View, Text } from 'react-native'

export const PlatformSpacing = () => (
  <View className="ios:pt-12 android:pt-6 web:pt-4">
    <Text>Platform-specific top padding</Text>
  </View>
)

Platform Variants in @layer theme

While platform selectors like ios:, android:, native:, and web: are great for component-level styling, Uniwind also supports platform-specific @variant directives within @layer theme. This allows you to define platform-specific design tokens and CSS variables that affect your entire theme.
Platform @variant directives in @layer theme are processed at build time and define global theme values, while platform selectors are resolved at runtime for component-specific styles.

Theme Configuration

Use @media queries inside @theme to define platform-specific CSS variables in your global.css:
@import 'tailwindcss';
@import 'uniwind';

@layer theme {
    :root {
        /* Base configuration applies to all platforms */
        --font-sans: "Inter";
        --spacing-4: 16px;

        /* iOS-specific overrides */
        @variant ios {
            --font-sans: "system-ui";
            --spacing-4: 20px;
        }

        /* Android-specific overrides */
        @variant android {
            --font-sans: "sans-serif";
            --spacing-4: 18px;
        }

        /* Web-specific overrides */
        @variant web {
            --font-sans: "Inter";
            --spacing-4: 16px;
        }
    }
}

When to Use Each Approach

Understanding when to use platform selectors vs platform @variant directives helps you build better cross-platform apps:
Use for component-specific styling
<View className="ios:pt-12 android:pt-6 web:pt-4" />
<View className="native:pt-10 web:pt-4" />
  • High flexibility - mix and match on any component
  • Best for: Different padding, colors, or layouts for specific UI elements
  • Use native: for shared mobile styles
Use for global theme configuration
@layer theme {
    :root {
        --font-sans: "Inter";

        @variant ios {
            --font-sans: "system-ui";
        }
    }
}
  • Affects entire design system
  • Best for: Platform-specific fonts, spacing scales, or brand colors

Platform-Specific Typography

One of the most common use cases is defining platform-appropriate font families:
@layer theme {
    :root {
        --font-sans: "Inter";
        --text-base: 16px;

        @variant ios {
            --font-sans: "-apple-system", "SF Pro Text";
            --text-base: 17px; /* iOS prefers slightly larger text */
        }

        @variant android {
            --font-sans: "Roboto";
            --text-base: 14px; /* Material Design standard */
        }

        @variant web {
            --font-sans: "Inter", "system-ui", sans-serif;
            --text-base: 16px;
        }
    }
}
Then use the font variables in your components:
import { Text } from 'react-native'

export const PlatformText = () => (
  <Text className="font-sans text-base">
    This text automatically uses the platform-appropriate font
  </Text>
)

Platform-Specific Spacing

Adjust spacing scales to match platform design guidelines:
@layer theme {
    :root {
        @variant ios {
            /* iOS prefers more generous spacing */
            --spacing-4: 20px;
            --spacing-6: 28px;
        }

        @variant android {
            /* Material Design spacing */
            --spacing-4: 16px;
            --spacing-6: 24px;
        }
    }
}

Combining with Theme Variants

Platform @variant directives work seamlessly with theme variants like dark:
@layer theme {
    :root {
        --font-sans: "Inter";

        @variant dark {
            --color-background: #000000;
            --color-foreground: #ffffff;
        }

        @variant light {
            --color-background: #ffffff;
            --color-foreground: #000000;
        }

        @variant ios {
            --font-sans: "SF Pro Text";
        }

        @variant android {
            --font-sans: "Roboto";
        }
    }
}
import { View, Text } from 'react-native'

export const ThemedText = () => (
  <View className="bg-background">
    <Text className="font-sans text-foreground">
      Platform and theme-aware text
    </Text>
  </View>
)
Platform @variant directives can only be used inside @layer theme in your global.css file. They define global theme values, not component-specific styles.

Supported Class Names

Learn about all supported Tailwind classes in Uniwind

Theming

Combine platform selectors with theme variants