如何在React Native中实现类似box-shadow: inset的内阴影效果?
React Native(Expo)实现内阴影效果方案
针对你需要的类似CSS box-shadow: inset 1px -3px 6px #63A1DE47, 0px 3px 33px #FFFFFF9C 的内阴影+外阴影效果,以下是几个在Expo环境下可行的方案:
方案一:用expo-linear-gradient模拟渐变内阴影(适合简单场景)
如果你的内阴影是沿边缘的渐变暗化效果,可通过线性渐变叠加在容器内部模拟,配合圆角实现弧度感。
步骤:
- 安装依赖:
npx expo install expo-linear-gradient
- 代码示例:
import { View, StyleSheet } from 'react-native'; import { LinearGradient } from 'expo-linear-gradient'; const ShadowNavbar = () => { return ( <View style={styles.wrapper}> {/* 外阴影通过原生shadow属性实现 */} <View style={styles.navbarContainer}> {/* 内阴影渐变层 */} <LinearGradient colors={['#63A1DE47', 'transparent']} start={{ x: 0, y: 0 }} end={{ x: 0, y: 1 }} style={styles.innerShadow} /> {/* 导航栏内容 */} <View style={styles.navbarContent}> {/* 这里放置标题、按钮等内容 */} </View> </View> </View> ); }; const styles = StyleSheet.create({ wrapper: { paddingHorizontal: 16, paddingTop: 20, }, navbarContainer: { position: 'relative', height: 60, borderRadius: 16, backgroundColor: '#fff', shadowColor: '#FFFFFF9C', shadowOffset: { width: 0, height: 3 }, shadowOpacity: 1, shadowRadius: 33, elevation: 5, // Android外阴影 overflow: 'hidden', // 限制渐变不超出圆角 }, innerShadow: { position: 'absolute', top: 0, left: 0, right: 0, height: 8, borderTopLeftRadius: 16, borderTopRightRadius: 16, }, navbarContent: { width: '100%', height: '100%', justifyContent: 'center', alignItems: 'center', }, }); export default ShadowNavbar;
调整渐变的颜色、方向和高度,就能匹配你需要的内阴影强度。
方案二:用react-native-svg滤镜实现真实内阴影
如果需要精准还原CSS inset阴影的效果,可通过SVG滤镜实现,之前未成功可能是滤镜配置有误。
步骤:
- 安装依赖:
npx expo install react-native-svg
- 代码示例:
import { View, StyleSheet } from 'react-native'; import { Svg, Defs, Filter, FeGaussianBlur, FeOffset, FeComposite, FeFlood } from 'react-native-svg'; const InsetShadowContainer = () => { return ( <View style={styles.wrapper}> <View style={styles.container}> {/* SVG滤镜层 */} <Svg style={styles.svgFilter}> <Defs> <Filter id="insetShadow"> <FeFlood floodColor="#63A1DE47" result="flood" /> <FeOffset dx={1} dy={-3} result="offset" /> <FeGaussianBlur stdDeviation={6} result="blur" /> {/* 将阴影限制在容器内部 */} <FeComposite operator="in" in="blur" in2="SourceAlpha" result="shadow" /> <FeComposite operator="over" in="SourceGraphic" in2="shadow" /> </Filter> </Defs> <Rect width="100%" height="100%" fill="transparent" filter="url(#insetShadow)" /> </Svg> {/* 容器内容 */} <View style={styles.content}> {/* 放置你的内容 */} </View> </View> </View> ); }; const styles = StyleSheet.create({ wrapper: { padding: 20, }, container: { position: 'relative', height: 60, borderRadius: 16, backgroundColor: '#fff', shadowColor: '#FFFFFF9C', shadowOffset: { width: 0, height: 3 }, shadowOpacity: 1, shadowRadius: 33, elevation: 5, overflow: 'hidden', }, svgFilter: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, }, content: { width: '100%', height: '100%', justifyContent: 'center', alignItems: 'center', }, }); export default InsetShadowContainer;
修改dx、dy、stdDeviation参数,可完全对应CSS内阴影的数值。
方案三:用react-native-skia实现原生级内阴影
Expo支持react-native-skia,它的阴影API直接支持inset属性,能精准还原CSS内阴影效果,是最接近预期的方案。
步骤:
- 安装依赖:
npx expo install @shopify/react-native-skia
- 代码示例:
import { View, StyleSheet } from 'react-native'; import { Canvas, Rect, Shadow } from '@shopify/react-native-skia'; const SkiaNavbar = () => { return ( <View style={styles.wrapper}> <View style={styles.navbarWrapper}> <Canvas style={styles.canvas}> {/* 内阴影 */} <Shadow dx={1} dy={-3} blur={6} color="#63A1DE47" inset={true} /> {/* 外阴影 */} <Shadow dx={0} dy={3} blur={33} color="#FFFFFF9C" inset={false} /> {/* 导航栏背景矩形 */} <Rect x={0} y={0} width="100%" height="100%" rx={16} fill="#fff" /> </Canvas> {/* 导航栏内容 */} <View style={styles.navbarContent}> {/* 放置标题、按钮等内容 */} </View> </View> </View> ); }; const styles = StyleSheet.create({ wrapper: { paddingHorizontal: 16, paddingTop: 20, }, navbarWrapper: { position: 'relative', width: '100%', height: 60, }, canvas: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, }, navbarContent: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, justifyContent: 'center', alignItems: 'center', }, }); export default SkiaNavbar;
Skia的阴影参数和CSS完全对应,无需额外适配,效果最接近网页端的实现。
注意事项
- 若之前使用
react-native-shadow-2未成功,可尝试开启inset配置,并确保容器设置overflow: hidden,避免阴影溢出圆角。 - Android和iOS的原生阴影表现有差异,测试时需兼顾两端:iOS用
shadow系列属性,Android用elevation配合外阴影。
内容的提问来源于stack exchange,提问作者Najeem Fasil
相关产品推荐
相关产品推荐

