> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uniwind.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Platform Selectors

> Apply platform-specific styles with built-in selectors for iOS, Android, Web, and TV platforms

## 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.

<Info>
  Platform selectors are resolved at runtime and automatically apply the correct styles for the current platform.
</Info>

## Basic Usage

Use platform selectors directly in your `className` prop with the syntax `platform:utility`:

```tsx theme={null}
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:

### ❌ Not Recommended: Platform.select()

```tsx theme={null}
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

### ✅ Recommended: Platform Selectors

```tsx theme={null}
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

<ParamField path="ios" type="selector">
  Targets iOS devices (iPhone, iPad). Styles are applied only when running on iOS.
</ParamField>

<ParamField path="android" type="selector">
  Targets Android devices. Styles are applied only when running on Android.
</ParamField>

<ParamField path="web" type="selector">
  Targets web browsers. Styles are applied only when running in a web environment (e.g., React Native Web).
</ParamField>

<ParamField path="native" type="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.
</ParamField>

<ParamField path="tv" type="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](/api/metro-config).
</ParamField>

<ParamField path="apple-tv" type="selector">
  Targets Apple TV only. Styles are applied only when running on tvOS. Requires `isTV: true` in your [metro.config.js](/api/metro-config).
</ParamField>

<ParamField path="android-tv" type="selector">
  Targets Android TV only. Styles are applied only when running on Android TV. Requires `isTV: true` in your [metro.config.js](/api/metro-config).
</ParamField>

## 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

```tsx theme={null}
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

```tsx theme={null}
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>
```

<Tip>
  Use `native:` when your iOS and Android styles are identical, and only web differs. This reduces duplication and improves maintainability.
</Tip>

## TV Selectors

<Badge>Available in Uniwind 1.5.0+</Badge>

Uniwind supports TV platforms with dedicated selectors. To enable TV support, set `isTV: true` in your [metro.config.js](/api/metro-config).

```tsx theme={null}
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.

<Tip>
  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.
</Tip>

## Examples

### Platform-Specific Colors

```tsx theme={null}
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

```tsx theme={null}
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.

<Info>
  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.
</Info>

### Theme Configuration

Use `@media` queries inside `@theme` to define platform-specific CSS variables in your `global.css`:

```css theme={null}
@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:

<AccordionGroup>
  <Accordion title="Platform Selectors (ios:, android:, native:, web:)" icon="code">
    **Use for component-specific styling**

    ```tsx theme={null}
    <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
  </Accordion>

  <Accordion title="Platform Variants in @layer theme" icon="palette">
    **Use for global theme configuration**

    ```css theme={null}
    @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
  </Accordion>
</AccordionGroup>

### Platform-Specific Typography

One of the most common use cases is defining platform-appropriate font families:

```css theme={null}
@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:

```tsx theme={null}
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:

```css theme={null}
@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`:

```css theme={null}
@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";
        }
    }
}
```

```tsx theme={null}
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>
)
```

<Warning>
  Platform `@variant` directives can only be used inside `@layer theme` in your `global.css` file. They define global theme values, not component-specific styles.
</Warning>

## Related

<CardGroup cols={2}>
  <Card title="Supported Class Names" icon="table" href="/class-names">
    Learn about all supported Tailwind classes in Uniwind
  </Card>

  <Card title="Theming" icon="palette" href="/theming/basics">
    Combine platform selectors with theme variants
  </Card>
</CardGroup>
