React-native: Setting borderStyle on <View> to dashed or dotted for a single side does not render correctly on both iOS and Android

Created on 1 Apr 2019  路  38Comments  路  Source: facebook/react-native

馃悰 Bug Report

Setting the CSS property borderStyle to dashed or dotted for a single side on a View component does not work on both iOS and Android.

The docs show available values: https://facebook.github.io/react-native/docs/view-style-props#borderstyle

Android renders solid line for both dashed/dotted

Screen Shot 2019-04-01 at 12 20 02 PM

iOS does not render anything for dashed/dotted

Screen Shot 2019-04-01 at 12 18 50 PM

To Reproduce

Set a borderStyle css property on a View for a single side like this:

borderLeftWidth: 3,
borderLeftColor: 'red',
borderStyle: 'dashed',

Expected Behavior

A dashed border is rendered correctly on iOS and Android

Code Example

Snack: https://snack.expo.io/@mido/react-native-borderstyle-dashed-and-dotted-broken

Environment

  React Native Environment Info:
    System:
      OS: macOS 10.14.4
      CPU: (8) x64 Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
      Memory: 977.25 MB / 16.00 GB
      Shell: 5.3 - /bin/zsh
    Binaries:
      Node: 8.12.0 - ~/.nvm/versions/node/v8.12.0/bin/node
      Yarn: 1.6.0 - /usr/local/bin/yarn
      npm: 6.4.1 - ~/.nvm/versions/node/v8.12.0/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: iOS 12.2, macOS 10.14, tvOS 12.2, watchOS 5.2
      Android SDK:
        API Levels: 21, 22, 23, 24, 25, 26, 27
        Build Tools: 26.0.3, 27.0.3, 28.0.2, 28.0.3
        System Images: android-24 | Google APIs Intel x86 Atom, android-27 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom
    IDEs:
      Android Studio: 3.1 AI-173.4907809
      Xcode: 10.2/10E125 - /usr/bin/xcodebuild
    npmPackages:
      react: 16.8.3 => 16.8.3
      react-native: 0.59.2 => 0.59.2
    npmGlobalPackages:
      react-native-log-ios: 1.0.1
Bug Low-Pri Android iOS

Most helpful comment

Still an issue on rn 0.63

All 38 comments

It looks like you are using an older version of React Native. Please update to the latest release, v0.59 and verify if the issue still exists.

The "Resolution: Old Version" label will be removed automatically once you edit your original post with the results of running react-native info on a project using the latest release.

Tested on 0.59.2 as well and it's still broken.

@retyui thanks for the link. This bug is specifically talking about <View> borderStyle prop which should be supported according to the docs.

I was able to reproduce the issue with the latest release (0.59.5)

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

Heya, this is still an issue with latest 0.60.4.

Still an issue. +1

Still an issue. +2 with 0.60.4

still have the same issue with rn 0.60.5

still have the issue

Wow. this issue still exist. How about that. Any fix for this? Thanks!

still have the issue

react-native: "0.61.3"
still have this issue

Same problem,
for now, this hack work for me

style={{ borderWidth: 1, borderStyle: 'dotted', borderColor: '#fff', borderBottomColor: 'red' }}

This works for me for vertical dashed line. Both Android and iOS. But gives double width.
"react-native": "0.59.10",

style={{
    width: 0,
    height: 45,
    borderStyle: 'dashed',
    borderWidth: 1,
    borderColor: '#ddd',
    borderRadius : 1,
}}

Update: (31-Mar-2020)

I finally ended up using react-native-dash - https://github.com/obipawan/react-native-dash for consistent results in both iOS and android

same issue, the border is not rendered at all (react-native": "^0.60.5")

const styles = StyleSheet.create({
  item: {
    borderBottomColor: colors.light,
    borderBottomWidth: 1,
    borderStyle: "dashed"
  }
});

export const ProfileHealth = () => (
    <View style={styles.item}>
      <Text>Text</Text>
    </View>
);

Same thing, I am trying to use border to show breadcumbs-like line on left side of view without using another view for this:

container: {
    marginLeft: 24,
    paddingLeft: 8,
    borderLeftWidth: 1,
    borderStyle: 'dashed',
    borderLeftColor: 'black',
  }

This style isn't applying to view. Tried to vanish other borders - line become solid

container: {
    marginLeft: 24,
    paddingLeft: 8,
    borderWidth: 1,
    borderRadius: 1,
    borderStyle: 'dashed',
    borderLeftColor: 'black',
  }

Doesn't work on Android, iOS still not supports 'dashed' or 'dotted' style

Same issue. Are we resolving this anytime soon?

Here's how I got it to work (RN version 59.10)

          <View style={{ overflow: 'hidden' }}>
            <View
              style={{
                borderWidth: 1,
                borderStyle: 'dashed',
                borderColor: '#000000',
                marginTop: -1,
                marginLeft: -1,
                marginRight: -1,
              }}
            >
              Content
            </View>
          </View>

Same issue

Can confirm that borderStyle: dashed works only when you add borderRadius to the style.
I am using react-native v0.61.2

This works for me for vertical dashed line. Both Android and iOS. But gives double width.
"react-native": "0.59.10",

style={{
    width: 0,
    height: 45,
    borderStyle: 'dashed',
    borderWidth: 1,
    borderColor: '#ddd',
    borderRadius : 1,
}}

Update: (31-Mar-2020)

I finally ended up using react-native-dash - https://github.com/obipawan/react-native-dash for consistent results in both iOS and android

I think this is the easiest consistent workaround. Thanks for the library.

For some reason, it only works when used in conjunction with borderRadius. With borderRadius: 1, rounding the border is almost imperceptible.

Heya, this is still an issue with latest 0.62.2. unbelievable!! this issue has appear for a long time and have not resolve it

not a priority

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container} />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    marginTop: 100,
    marginLeft: 100,
    height: 100,
    width: 200,
    backgroundColor: 'yellow',
    borderWidth: 2,
    borderStyle: 'dotted',
    borderRadius: 0.0000001,
  },
});

not a priority

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container} />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    marginTop: 100,
    marginLeft: 100,
    height: 100,
    width: 200,
    backgroundColor: 'yellow',
    borderWidth: 2,
    borderStyle: 'dotted',
    borderRadius: 0.0000001,
  },
});


not four side, just add a single side(left/right/top/bottom), it will render to solid line, no matter change a side borderColor or borderWidth, the dashed or dotted will render to solid line

You are right

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container} />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    marginTop: 100,
    marginLeft: 100,
    height: 100,
    width: 200,
    backgroundColor: 'yellow',
    borderLeftWidth: 2,
    borderStyle: 'dotted',
    borderTopLeftRadius: 1,
    borderTopEndRadius: 1,
    borderTopRightRadius: 1,
    borderTopRightRadius: 1,
    borderBottomRightRadius: 1,
    borderBottomEndRadius: 1,
    borderBottomLeftRadius: 1,
  },
});

This are multiple issues that should be solved with multiple pull requests

ReactViewBackgroundDrawable handles different scenarios with a series of if statements:

  • rounded borders
  • non rounded borders
  • settings one border at the time (borderLeftWidth and borderLeftRadius)
  @Override
  public void draw(Canvas canvas) {
    updatePathEffect();
    if (!hasRoundedBorders()) {
      drawRectangularBackgroundWithBorders(canvas);
    } else {
      drawRoundedBackgroundWithBorders(canvas);
    }
  }

This does not work with dotted style both on:

1) With rectangular shape (no rounded borders) with drawRectangularBackgroundWithBorders
2) When setting only one side of the rectangular (with rounded borders) for ex. with borderLeftWidth: 2 (method drawRoundedBackgroundWithBorders).

Issue 2) is connected to the drawing done with drawQuadrilateral.
There must be a reason we are using lineTo instead of drawRect, but I ignore it.

The fact is seems that the logic to include special border style was not implemented here and I was able to add it. The style dotted or solid depend on the variable mPaint.

    mPaint.setStyle(Paint.Style.STROKE);
    DashPathEffect dash = new DashPathEffect(
      new float[] {9, 9}, 0);
    mPaint.setPathEffect(dash);
    mPaint.setStrokeWidth(70);

https://github.com/facebook/react-native/blob/7e300db7035c98537e0719c88a7c1a451e59e250/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java#L1208-L1215

Seems to me that the logic for drawing rounded corners rectangles is included in updatePath

https://github.com/facebook/react-native/blob/7e300db7035c98537e0719c88a7c1a451e59e250/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java#L615-L691

and then applied by clipping the canvas (cropping the rectangle so it looks like has rounded borders)

https://github.com/facebook/react-native/blob/7e300db7035c98537e0719c88a7c1a451e59e250/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java#L375-L376

This is important in case you are using rounded corners rectangle and setting each border side width and style....

If you draw a rectangle with dotted borders, then clip it with roundRect, the corners will not have borders..

This issue is real headache.. :cry:

class Side < Path
  def init(x, y, z, w)
    super()
    moveTo(x,y)
    side.lineTo(z,w)
  end
end

class Border
  def init(leftBorder, topBorder, rightBorder, bottomBorder)
     # intersect 4 Paths for borders
     # intersect also the other 4 Paths for corners 
  end  
end

class Corner < Path
  # def init()
  #    super()
  #    arcTo()  
  # end
end

leftBorder = new Side(10,10, 10, 50)
corner = new Corner()
border = new Border(leftBorder, topBorder, rightBorder, bottomBorder)
canvas.drawPath(border, mPaint)

This fixes the issue:

          if (borderLeft > 0) {
            int leftInset = left + borderLeft;
            mPaint.setStyle(Paint.Style.STROKE);
            DashPathEffect dash = new DashPathEffect(
              new float[] {9, 9}, 0);
            mPaint.setPathEffect(dash);
            mPaint.setStrokeWidth(10);
            Path side = new Path();
            side.moveTo(left, top);
            side.lineTo(leftInset, bottom - borderBottom);
            canvas.drawPath(side, mPaint);
            // canvas.drawRect(left, top, leftInset, bottom - borderBottom, mPaint);
          }

https://github.com/facebook/react-native/blob/7e300db7035c98537e0719c88a7c1a451e59e250/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java#L1102-L1105

I'll write a pull request with a quick fix.

You can set like below for only bottom border:
borderWidth: 1,
borderLeftWidth: 0,
borderRightWidth: 0,
borderTopWidth: 0,
borderStyle: 'dashed'

This is still an issue

Same issue

@Gazizbek @amiratak88 @DenisDovganiuc there is a pr https://github.com/facebook/react-native/pull/29099 that fixes this. Please test that PR and support. Thanks. Fabrizio

I wrote pull request https://github.com/facebook/react-native/pull/29099 that fixes this issue

After a quick reserach I noticed that we have 25 issues in react-native for this bug https://github.com/facebook/react-native/issues/24224 https://github.com/facebook/react-native/issues/28695 https://github.com/facebook/react-native/issues/23651 https://github.com/facebook/react-native/issues/23475 https://github.com/facebook/react-native/issues/22256 https://github.com/facebook/react-native/issues/22226 https://github.com/facebook/react-native/issues/19234 https://github.com/facebook/react-native/issues/18285 https://github.com/facebook/react-native/issues/17344 https://github.com/facebook/react-native/issues/17343 https://github.com/facebook/react-native/issues/17251 https://github.com/facebook/react-native/issues/12817 https://github.com/facebook/react-native/issues/12403 https://github.com/facebook/react-native/issues/11042 https://github.com/facebook/react-native/issues/9343 https://github.com/facebook/react-native/issues/8236 https://github.com/facebook/react-native/issues/8105 https://github.com/facebook/react-native/issues/7838 https://github.com/facebook/react-native/issues/6721 https://github.com/facebook/react-native/issues/5411 https://github.com/facebook/react-native/issues/3159 https://github.com/facebook/react-native/issues/2335 https://github.com/facebook/react-native/issues/840 https://github.com/facebook/react-native/issues/27133 https://github.com/facebook/react-native/issues/28695

I decided to post this message and trigger linking between all this issues.

Nice job @fabriziobertoglio1987! Hopefully this gets merged in for the next release.

For the record:

@Gazizbek
You can set like below for only bottom border:
borderWidth: 1,
borderLeftWidth: 0,
borderRightWidth: 0,
borderTopWidth: 0,
borderStyle: 'dashed'

This doesn't work. Changes the remaining border styles to a solid line.

@sirajalam049
Same problem,
for now, this hack work for me

style={{ borderWidth: 1, borderStyle: 'dotted', borderColor: '#fff', borderBottomColor: 'red' }}

This also doesn't work. It uses the borderColor and ignores the specific side's color.

Still an issue on rn 0.63

<View> <Text style={{ marginRight: 10, color: '#006087' }}>Routing Numbers</Text> <View style={{ marginRight: 10, flexDirection: 'row', alignItems: 'center', justifyContent: 'space-evenly', marginTop: -10 }}> <Text>-</Text> <Text>-</Text> <Text>-</Text> <Text>-</Text> <Text>-</Text> <Text>-</Text> <Text>-</Text> <Text>-</Text> <Text>-</Text> <Text>-</Text> <Text>-</Text> <Text>-</Text> <Text>-</Text> <Text>-</Text> <Text>-</Text> </View> </View>

Was this page helpful?
0 / 5 - 0 ratings