Co je tento nástroj?
V React Native nejsou stíny ve výchozím stavu multiplatformní. iOS používá čtyři samostatné vlastnosti stylu (shadowColor, shadowOffset s width/height, shadowOpacity od 0 do 1 a shadowRadius pro rozostření), které se mapují na stejný podkladový stín CoreAnimation, jaký na webu využívá box-shadow. Nativní systém View v Androidu vůbec nepodporuje libovolné tvary stínů — podporuje pouze elevation, jediné číslo, které vytváří pevně daný stín ve stylu Material Design podle toho, jak vysoko prvek „vznáší“ nad povrchem.
To znamená, že stín, který na iOS vypadá správně díky shadowRadius/shadowOpacity, se na Androidu vůbec nezobrazí, pokud zároveň nenastavíte elevation, a obě platformy nikdy nebudou vypadat pixelově identicky, protože tvar stínu u elevation nelze přizpůsobit tak jako u iOS. Od React Native 0.74 se zapnutou New Architecture je navíc k dispozici multiplatformní vlastnost stylu boxShadow, která používá stejnou syntaxi jako CSS.
Proč ho používat?
- Sledujte živý vizuální náhled při úpravě posunu, rozostření, průhlednosti a barvy — místo hádání hodnot a opětovného sestavování aplikace kvůli ověření.
- Získejte vlastnosti stínu pro iOS, elevation pro Android a novější multiplatformní řetězec boxShadow najednou, takže nemusíte hledat ve třech různých API.
- Elevation je samostatný ovládací prvek (není automaticky počítán z rozostření/průhlednosti), protože mapování elevation na vzhled stínu v Androidu není přímým převodem z vlastností stínu iOS — je třeba jej vyladit vizuálně, což tento nástroj umožňuje dělat vedle sebe.
- Zdarma, okamžitě a připraveno ke zkopírování jako jediný objekt stylu.
Jak se používá
- Upravte posun X/Y, poloměr rozostření, průhlednost a barvu stínu — náhledový box se aktualizuje živě.
- Samostatně vylaďte číslo elevation pro Android, dokud vizuálně neodpovídá zamýšlené síle stínu.
- Klikněte na „Kopírovat“ a zkopírujte celý objekt stylu, včetně vlastností pro iOS, elevation pro Android a řetězce boxShadow.
- Vložte objekt do StyleSheet vaší komponenty — spojte ho (spread) nebo sloučte s existujícími styly view.
Příklad
Vstup
Posun (0, 4), rozostření 8, průhlednost 0,25, černá, elevation 5Výstup
shadowColor: '#000000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.25, shadowRadius: 4, elevation: 5, boxShadow: '0px 4px 8px rgba(0, 0, 0, 0.25)'shadowRadius je nastaven na polovinu hodnoty rozostření zobrazené v náhledu, což odpovídá tomu, jak se poloměr rozostření v CSS v praxi vztahuje k shadowRadius v iOS.
Časté dotazy
Proč se mi stín nezobrazuje na Androidu?
Vlastnosti shadowColor/shadowOffset/shadowOpacity/shadowRadius jsou určeny pouze pro iOS — nativní vykreslování Androidu je jednoduše ignoruje. Aby se stín na Androidu vůbec zobrazil, musíte nastavit také vlastnost elevation (kladné číslo).
Mohu docílit, aby stín na Androidu vypadal identicky jako na iOS?
Ne úplně — elevation vytváří vestavěný tvar stínu Material Design v Androidu, který nelze samostatně nastavit co do barvy, směru posunu nebo rozostření tak jako stín na iOS. Číslo elevation můžete vyladit tak, aby síla vypadala vizuálně podobně, ale pixelová shoda mezi platformami není u klasických API shadow/elevation možná.
Co je vlastnost boxShadow a mohu ji použít místo toho?
boxShadow je novější, skutečně multiplatformní vlastnost stylu (přidaná v React Native 0.74, dostupná na New Architecture), která používá stejnou řetězcovou syntaxi jako CSS box-shadow a funguje shodně na iOS i Androidu. Pokud to verze React Native a architektura vaší aplikace podporují, můžete použít pouze tuto jednu vlastnost místo čtyř samostatných vlastností pro iOS plus elevation — před nasazením do produkce si ověřte verzi RN a stav New Architecture.
Proč je shadowRadius poloviční oproti hodnotě rozostření, kterou jsem nastavil?
Živý náhled používá CSS box-shadow, kde se hodnota rozostření šíří přibližně dvakrát dále než odpovídající hodnota shadowRadius na iOS. Vygenerovaný kód nastaví shadowRadius na polovinu hodnoty rozostření, aby stín, který vidíte v náhledu, odpovídal tomu, co iOS skutečně vykreslí — kdybyste hodnotu rozostření zkopírovali přímo, stín na iOS by vypadal znatelně měkčí a větší než v náhledu.
Potřebuji Platform.select k použití těchto stylů?
Ne — je bezpečné umístit vlastnosti shadow* pro iOS a elevation pro Android do jednoho objektu stylu, přesně jako to dělá vygenerovaný kód: každá platforma jednoduše ignoruje vlastnosti té druhé. Platform.select má smysl přidat pouze tehdy, pokud chcete pro jednotlivé platformy skutečně odlišný návrh stínu, nikoli kvůli vyhnutí se varováním (žádná nejsou).
Nastavil jsem elevation, ale stín na Androidu se stále nezobrazuje — proč?
Dvě nejčastější příčiny: view nemá nastavenou backgroundColor (stín z elevation v Androidu vychází z neprůhledného pozadí view, takže průhledný view nevrhá žádný stín), nebo má rodič nastaveno overflow: 'hidden' a stín oříznává. Než usoudíte, že je hodnota elevation špatná, nastavte view plnou barvu pozadí a zkontrolujte nastavení overflow u předků.