cssreactjsmaterial-uijssmakestyles

Gradient border on MUI component


I did not manage to find the equivalent of border-image-source css

My goal is to render a border gradient on a button component


Solution

  • This is how you add a gradient border to the button component:

    V5

    const options = {
      shouldForwardProp: (prop) => prop !== 'gradientColors',
    };
    
    const GradientButton = styled(
      Button,
      options,
    )(({ theme, gradientColors }) => ({
      border: '5px solid',
      borderImageSlice: 1,
      borderImageSource: `linear-gradient(to left, ${gradientColors.join(',')})`,
    }));
    

    If you want a round button with gradient border, you can't use the code above since borderImage doesn't have a radius. A workaround is to create a gradient background in the child element :after because the background can be clipped using borderRadius:

    const borderRadius = 15;
    const RoundGradientButton = styled(
      Button,
      options,
    )(({ theme, gradientColors }) => ({
      position: 'relative',
      border: '5px solid transparent',
      backgroundClip: 'padding-box',
      borderRadius,
    
      '&:after': {
        position: 'absolute',
        top: -5,
        left: -5,
        right: -5,
        bottom: -5,
        background: `linear-gradient(to left, ${gradientColors.join(',')})`,
        content: '""',
        zIndex: -1,
        borderRadius,
      },
    }));
    

    Usage

    <GradientButton gradientColors={['red', 'yellow']} variant="contained">
      Default
    </GradientButton>
    <RoundGradientButton gradientColors={['red', 'yellow']} variant="contained">
      Default
    </RoundGradientButton>
    

    Live Demo

    Codesandbox Demo

    V4

    const useStyles = makeStyles((theme: Theme) => ({
      button: {
        border: "6px solid",
        borderImageSlice: 1,
        borderImageSource: "linear-gradient(to left, red, orange)"
      }
    }));
    
    export default function ContainedButtons() {
      const classes = useStyles();
    
      return (
        <Button className={classes.button} variant="contained">
          Default
        </Button>
      );
    }
    

    Live Demo

    Edit 66995679/gradient-border-on-component-material-ui

    Related Answer