When the parent view (overflow: 'hidden') has borderRadius
set, the child view is not clipped to the shape of the parent.
demo reproducing the issue: https://rnplay.org/apps/69TRrw
Thanks for the report. Unfortunately overflow: hidden is not respected on android (see https://facebook.github.io/react-native/docs/known-issues.html#the-overflow-style-property-defaults-to-hidden-and-cannot-be-changed-on-android). I think @kmagiera has previously posted about the clipping issue for rounded corners and can chime in here.
Nothing more to add here. Unfortunately this is a known problem and is not being worked on as mentioned in the docs. Closing this as it's already on the list. If you guys have any proposal on how this could be implemented without causing significant perf issue in rendering pipeline feel free to reopen and post your ideas here
We're using imgix, so I think we'll be able to add ?fm=png&mask=ellipse
and be on our way. Dodged a bullet there but will encounter moderate problems elsewhere.
I'll submit a PR to note that in addition to hidden always being true, it doesn't obey borderRadius, which is not currently noted in the docs. (I assumed that if hidden were true, it would be clipped by the borderRadius just fine.)
@kmagiera May I ask where to find the comment or discussion about clipping issue with rounded corners that you posted before?
@Kudo: I was referring to the link posted by Andy just above my comment: https://facebook.github.io/react-native/docs/known-issues.html#the-overflow-style-property-defaults-to-hidden-and-cannot-be-changed-on-android
@kmagiera I see.
The feature is really useful for some cornered UI construction.
Would like to know more detail of your mentioned significant perf drops and see if we can make this feature happens.
More info:
this demo (https://rnplay.org/apps/WlY9aA) shows if the outer control is an image, the borderRadius property will totally not working.
We're working on an alternative UI implementation on Android that will fix this -- it's still in testing internally so don't expect it for a few more months, but do know we are working on getting a fix.
Any updates on this issue ?
I have a fairly cringe-worthy fix using styles that works for me in the meantime. This is a UI for creating group avatars out of user avatars. Similar to Facebook Messengers group avatars.
@bsinc that's a great solution! thx.
just clarifying what you did:
<View style={styles.circle}>
<Image style={styles.image} />
<View style={styles.fixCircleClipping}/>
</View>
circle: {
width: circleSize,
height: circleSize,
borderRadius: circleSize / 2,
overflow: 'hidden',
},
fixCircleClipping: {
position: 'absolute',
top: -circleFixBorder,
bottom: -circleFixBorder,
right: -circleFixBorder,
left: -circleFixBorder,
borderRadius: circleSize / 2 + circleFixBorder / 2,
borderWidth: circleFixBorder,
borderColor: bgColor
},
@bsinc That's brilliant, thank you!
@astreet Is there any updates?
Thanks
Is this still a known issue? I can't find the known issues page anymore.
@astreet this will be fixed in 0.32? When 0.32 comes out?
@Duelsik Was this hinted to being fixed in 0.32 or are you just asking? The release notes for 0.32 do not mention it anywhere.
Hey all, sorry you are being hit by this -- a couple engineers at FB are actively working on open sourcing our internal fix for this, but it's not a simple change so unfortunately it'll take a while longer. Tentatively, they are hoping to have it open sourced by the end of the year.
@astreet Thanks for the info! I eagerly await the fix!
I wonder if there is some temporary hack I can do with css to imitate this? The fix mentioned by @yonatanmn doesn't cover all cases.
@bsinc Thank you!
I would also be interested in a temporary hack to fix this problem.
Try bsinc's hack. It worked for me.
It doesn't work for me because I basically have a grid of circles. So if I use that hack, I get a bunch of circles with the views used to cover the overflow portion over my circles.
Added a product pain: https://productpains.com/post/react-native/add-overflow-support-to-android
Everyone upvote so FB knows how much we want it :)
@astreet any timeline on open sourcing the fix?
Many thanks!
No timeline right now but work is still in progress. I reopened this issue because there were some dupes with less info and it's less spam to just have this issue open.
I solved this by setting zIndex: 100
on the component, now overflow: hidden works for me on android!
@saberking That seems unlikely? What version of RN are you running?
@saberking @julienvincent Yeah not sure how that works.
Isn't this going to be fixed in Android: Nodes in RN 0.41? @lacker
@madjam002 My guess is that nodes won't immediately fix it, but it's probably the start
@julienvincent 0.40.0. I still have not managed to get borderRadius to work at all, but being able to use overflow hidden for other stuff is still really useful. And yes, I was amazed when that solved the problem. If you like i can make an example
@saberking This issue is specific to border-radius
+ overflow: hidden
. The overflow: hidden
property without any border-radius
was never broken.
@julienvincent OK maybe it is not broken but nowhere in the docs does it mention that you have to set zIndex
in order to use overflow: hidden
. Should I raise this as a separate issue?
That also sounds rather unlikely. It's more likely you are not using overflow: hidden as intended.
<Animated.View style={{
top: this.state.currentOuterTopOffset,
overflow: 'hidden',
...this.props.style
}}
onStartShouldSetResponder={() => true}
onMoveShouldSetResponder={() => true}
onResponderGrant={this.responderGrant.bind(this)}
onResponderMove={this.responderMove.bind(this)}
onResponderRelease={this.responderRelease.bind(this)}>
<Animated.View style={{ top: this.state.currentInnerTopOffset }}>
{this.props.children}
</Animated.View>
</Animated.View>
zIndex
must be also be set for overflow: 'hidden'
to work here. It definitely seems like a bug to me
I would suggest making a vanilla reproduce repo to demonstrate the problem you are experiencing and then opening an issue.
On RN 0.41.2 you can try to add
import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.flat.FlatUIImplementationProvider;
and
@Override
protected UIImplementationProvider getUIImplementationProvider() {
return new FlatUIImplementationProvider();
}
in ReactNativeHost class.
Since the view is not clipping the child image, I apply a border-radius to my image as well:
<View style={styles.imageContainer}>
<TouchableOpacity onPress={props.onChangeProfilePhoto}>
<View style={styles.changeProfileButton}>
{profile.photo
? <Image
style={styles.image}
source={{ uri: profile.photo }} />
: <Icon
name='person'
style={{ fontSize: 60 }} />
}
</View>
</TouchableOpacity>
</View>
const styles = StyleSheet.create({
...,
imageContainer: {
alignItems: 'center',
justifyContent: 'center',
backgroundColor: ColorDefaults.background.darkerGrey,
flex: 0.25,
},
image: {
width: 98,
height: 98,
borderRadius: 50,
},
changeProfileButton: {
width: 100,
height: 100,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 50,
borderWidth: 2,
},
...,
};
@ryanhomer it is not a solution.
Please read https://facebook.github.io/react-native/releases/0.26/docs/known-issues.html#the-overflow-style-property-defaults-to-hidden-and-cannot-be-changed-on-android before comming with workaround and solutions to that it is related to the problem itself.
Here is my reproduction of the problem: https://snack.expo.io/BkHBr6Vpx
If just want to clip overflow sub views, you can set removeclippedsubviews to true with overflow: 'hidden'
and it would work.
@desmond1121 Can you modify my snack above and show how you can do it with removeclippedsubviews
?
@henrikra Sorry for my misunderstood, removeClippedSubviews would remove out bound sub views but not clip in bound views.. so definitely it's not work with your problem.
@bsinc it's so smart . Just wanted to add a little advice , never use borderRadius as props (i repeat props , not style) in Image , like
<Image source={some source} borderRadius={50} /> .
Just Never !!
Using in scrollview will crash the app on repeated scrolling , and you will ruin the day finding where the bug is , even debugger won't tell you whats wrong . Its may be a out of memory problem . If its not within ScrollView or ListView (not sure), its fine . I almost ruined 4 hours finding the bug . Use the @bsinc trick instead .
+1 for this to have on android
+1
Please upvote on product pains (https://react-native.canny.io/feature-requests/p/add-overflow-support-to-android) or upvote this issue rather than spamming "+1" comments.
@mica16 @diegorodriguesvieira
I'd just like to throw in another data point for setting zIndex
as a workaround (from @saberking's post). I'm working with sprite sheets and ran into the issue where the entire sprite sheet was being shown on Android (worked fine for iOS).
render() {
return (
<View style={styles.container}>
<View style={styles.imageWrapper}>
<Image
style={styles.image}
source={{uri: [...]}}
/>
</View>
<Text style={styles.text}>Without zIndex: 1</Text>
<View style={styles.imageWrapper2}>
<Image
style={styles.image}
source={{uri: [...]}}
/>
</View>
<Text style={styles.text}>With zIndex: 1</Text>
</View>
);
}
var styles = StyleSheet.create({
container: {
backgroundColor: '#f9f8f5',
flex: 1,
padding: 20,
alignItems: 'center'
},
imageWrapper: {
overflow: 'hidden',
width: 86,
height: 86
},
imageWrapper2: {
overflow: 'hidden',
width: 86,
height: 86,
zIndex: 1
},
image: {
width: 196,
height: 86
},
text: {
paddingTop: 10,
paddingBottom: 30
}
});
This will render:
Verified on a Nexus 5 with Android 7.0. Note that you don't need to specify as high a value as 100. Specifying a zIndex of 1 was sufficient to solve the issue for me.
Any update?
This is a must have. Much of UI nowadays is based on rounded corners with subclipping.
Temporary workaround is positioning multiple "absolute" views with a solid border color on top of the image (using z-index) to fill in the gaps. Works if your background is a solid color.
<View style={{height:215, alignItems:'center', flex:1}}>
<View style={{position:'absolute', height:215, width:deviceWidth*0.95, borderWidth:10, borderRadius: 5, borderColor:'white'}}></View>
<View style={{position:'absolute', height:215, width:deviceWidth*0.95, borderWidth:10, borderRadius: 20, borderColor:'white'}}></View>
<Image
resizeMode="cover"
style={{height:215, width:deviceWidth*0.9, zIndex:-1}}
source={this.props.image}
/>
</View>
Yesterday I suddenly discoveree a simple solution . Just added backgroundColor in Image style and added borderRadius and it worked liked magic. Tried it on android . May be works on IOS too
@yonatanmn if borderRadius is 5?
@PARAGJYOTI this is not a solution. look at https://github.com/facebook/react-native/issues/3198#issuecomment-286122690 you are refering to the same workaround.
There isn't much more to be said in regard to this issue. Could we please lock conversations on this thread until further development?
@wollld - what about it? should work as far as I see
+1
+1
Please....
Stop +1 ... Upvote it here: https://react-native.canny.io/feature-requests instead.
Stop spaming workarounds, they dont solve the issue, feel free to create a PR to fix it instead.
Could we please lock the conversation until the issue is solved or there exists a PR to solve it?
@astreet @hramos
Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!
If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:
If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.
This is fixed with D5917111.
Most helpful comment
Added a product pain: https://productpains.com/post/react-native/add-overflow-support-to-android
Everyone upvote so FB knows how much we want it :)