react-native icon indicating copy to clipboard operation
react-native copied to clipboard

Elevation and border radius do not work well with opacity from Android 9

Open d4rky-pl opened this issue 5 years ago • 28 comments

The way elevation works is that it creates a border around the element that is then shifted to the bottom. The background color of the element then hides the inside part of the border.

When we apply border radius to the same element, the border gets thicker to accommodate for the increased radius. So far so good.

Unfortunately if we then apply the opacity to the parent, the background color of the element gets semitransparent, making the border visible and creating an ugly effect.

Screenshot_2019-05-30-17-03-34-477_host exp exponent

React Native version: 0.57 Expo SDK 32 Android version: 9.0

Steps To Reproduce

Create an element and apply, elevation, border radius and background color. Then apply opacity on its parent.

Describe what you expected to happen:

The border underneath the element should not leak out

Snack, code example, or link to a repository:

https://snack.expo.io/SJDAlu6TV

d4rky-pl avatar May 30 '19 15:05 d4rky-pl

I think this is related to https://github.com/facebook/react-native/issues/23090 and https://github.com/react-navigation/react-navigation/issues/5535.

ferrannp avatar May 30 '19 15:05 ferrannp

Seems like the issue is reproducible only on Android version 9.0 (I was testing that bug also on Android version 7.0 and 8.1 where it looks properly).

lukewalczak avatar May 30 '19 15:05 lukewalczak

Facing this issue with RN 0.59.8 as well.

seriiix avatar Jun 01 '19 18:06 seriiix

Tested on 0.59.9 and got the same problem as well. That makes the app really ugly on Android 9

PierreCapo avatar Jun 16 '19 22:06 PierreCapo

Still facing the issue on RN 0.60.4

NicholasBertazzonAga avatar Aug 08 '19 08:08 NicholasBertazzonAga

Still happening for me too, and have not found a workaround yet either.

ivosousaa avatar Aug 20 '19 10:08 ivosousaa

Still an issue.

sergchernata avatar Sep 18 '19 17:09 sergchernata

Using backgroundColor: '#fff' sets it right and works as expected.

WickedBrat avatar Sep 22 '19 12:09 WickedBrat

Still not work well.

yunjeongloper avatar Oct 18 '19 02:10 yunjeongloper

I'm having the same issue with RN 0.61.4 ... no possible fix or workaround?

PS: I got the issue on Android 7.1.1 as well as Android 9

Sofianio avatar Dec 05 '19 09:12 Sofianio

Having the same problem, when fading out with opacity, the back shadow looks unaceptable. Any updates on this?

toro705 avatar Dec 05 '19 14:12 toro705

Hi there! Same issue, look at this: elev_error It looks good on a 5.5" display with Android Pie. Instead on a 6.67" display with Android Q it looks like in the image.

Style props:

{
        width: 70, height: 70,
        flexDirection: "row", justifyContent: "center", alignItems: "center",
        backgroundColor: "#10aaae",
        borderStyle: "solid",
        borderRadius: 50,
        borderWidth: 7,
        borderColor: "rgba(16, 170, 174, 0.2)",
        elevation: 10,
        shadowColor: "#10aaae",
        shadowRadius: 7,
        shadowOpacity: .5,
        shadowOffset : { width: 0, height: 10 }
}

Hope it could help in resolving! 🤞🏻

se09deluca avatar Jan 22 '20 10:01 se09deluca

@ferrannp hello sir, is there anyways to make this bug more priority. I am waiting for this too long sir.

Theng avatar Feb 06 '20 03:02 Theng

Using backgroundColor: '#fff' sets it right and works as expected.

worked for me, what happened was my component was transparent hence i can see whats happening in the back, setting a background color makes it work as intended

BlueFits avatar Mar 20 '20 19:03 BlueFits

Using backgroundColor: '#fff' sets it right and works as expected.

worked for me, what happened was my component was transparent hence i can see whats happening in the back, setting a background color makes it work as intended

The problem is that if you lower or animate the opacity of this element, fading it out, the background color doesn't help. You can still see the shadow being rendered underneath, like a thick border.

sergchernata avatar Mar 20 '20 20:03 sergchernata

I found that this problem occur when changing opacity on a wrapping element that contain child elements using elevation for shadow. What fixed this bug for me temporarily was to set flag needsOffscreenAlphaCompositing on the wrapping element that i animated opacity style prop for. (For best practice usage check: https://reactnative.dev/docs/view#needsoffscreenalphacompositing) Otherwise setting opacity on each of the child elements should also work, instead of only the parent wrapper.

This was mentioned here: https://github.com/facebook/react-native/issues/23090#issuecomment-669157170

simongoot avatar Sep 17 '20 14:09 simongoot

I have a function that resizes px size based on a device's width. In my cases it rounded 21.09 to 21.090909... Passing 21 to wrapping element fixed issue with shadow

kesha-antonov avatar Jan 12 '21 16:01 kesha-antonov

What helped me when I wanted a wrapping element to have opacity and its children to have shadow and elevation while removing the buggy effect of seeing the border is that instead of applying the opacity through the opacity key (e.g., opacity: 0.7), I applied it through backgroundColor (e.g., '#FFFFFFB2'). This got rid of the effect for me.

stevenelkhaldi avatar Feb 16 '21 22:02 stevenelkhaldi

Using @simongoot solution, needsOffscreenAlphaCompositing worked great. In case someone else has the problem with a TouchableOpacity, where needsOffscreenAlphaCompositing did not work for me. You can replace the TouchableOpacity with an Animated Presseable and then animate the opacity via onPressIn and onPressOut.

import { Pressable, Animated } from 'react-native';
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);

const Button = ({children}) => {
  const animatedButtonOpacity = useRef(new Animated.Value(1));
  
  const buttonOpacity = {
    opacity: animatedButtonOpacity.current
  };
  return (
    <>
      {properties.map((property, index) => (
        <AnimatedPressable
          onPressIn={() => animatedButtonOpacity.current.setValue(0.5)}
          onPressOut={() => animatedButtonOpacity.current.setValue(1)}
          onPres={...}
          style={buttonOpacity}
          needsOffscreenAlphaCompositing
        >
          {children}
        </AnimatedPressable>
      ))}
    </>
  );
};

ccfz avatar Mar 03 '21 07:03 ccfz

Seems like needsOffscreenAlphaCompositing isn't working for me. Anyone else encountered and sorted this?

danielolamide avatar Apr 15 '21 16:04 danielolamide

Seems like needsOffscreenAlphaCompositing isn't working for me. Anyone else encountered and sorted this?

Encountered, yes. Sorted, no. This is still a thing. Basically, I have an Animated.View with shadows (elevation in Android and shadows in iOS, that is) in a sort-of card component that I re-use a lot in my app. On iOS it works just fine, but on android, the view with elevation doesn't like opacity at all. That is, TouchableOpacity (touchables with a shadow) or animations regarding opacity.

So my guess is, this issue is still going on. Currently running the latest RN version, I might add.

fellenabmb avatar Sep 20 '21 19:09 fellenabmb

I discovered a simple way to fix the problem, which is adding an opacity property to the child component to overide the effect done by the parent element, such as opacity: 0.99;, see if it works for you.

louielyl avatar Oct 01 '21 09:10 louielyl

I discovered a simple way to fix the problem, which is adding an opacity property to the child component to overide the effect done by the parent element, such as opacity: 0.99;, see if it works for you.

This does not work for me, is there already another fix? (Expect from using two View components (one for shadow and one for the background color with opacity))

LarsDepuydt avatar Nov 19 '21 22:11 LarsDepuydt

Setting backgroundColor: '#fff' works.

aprilmintacpineda avatar Feb 25 '22 10:02 aprilmintacpineda

Any updates? I'm facing the same issue, and either backgroundColor: #fff or opacity: 0.99 worked for me.

mmkhmk avatar May 12 '23 06:05 mmkhmk

Still buggy...

mathbalduino avatar Dec 06 '23 13:12 mathbalduino

Workaround was published here. Do you believe it worth fixing this issue in react-native?

fabOnReact avatar Feb 02 '24 06:02 fabOnReact

still facing issue

fazal26 avatar Apr 02 '24 19:04 fazal26