0

Before anyone removes this question and says it is similar to this one please hear me out. I am trying to do almost exactly what is being done in that post. The issue is the person who responded just gave some CSS which does not answer the question at hand. I am trying to do this FULLY in MUI. I would preferably want to be able to style my component using the makeStyles hook.

How would one implement an underline animation below a typography component such as the ones on the navigation bar here? I am really new to JS and MUI so I would appreciate something which is well explained and implemented so I can learn the terminology as well as the frameworks themselves.

This is my code so far. It's just like the one in the first link.

const useStyles = makeStyles({
    link: {
        color: "white",
        position: "relative",

        "&:before": {
            content: "",
            position: "absolute",
            width: "0",
            height: "2px",
            bottom: "0",
            left: "0",
            backgroundColor: "#FFF",
            visibility: "hidden",
            transition: "all 0.3s ease-in-out",
        },
        "&:before:hover": {
            visibility: "visible",
            width: "100%"
        }
    }
});

function NavButton(props){

    const classes = useStyles();

    return (
        <a href={`/#${props.text}`}>
            <Link className={classes.link}>
                <Typography>{props.text}</Typography>
            </Link>
            {/*<p className={"hover-underline-animation"}*/}
            {/*    {props.text}*/}
            {/*</p>*/}
        </a>
    );
}

I am receptive to any other types of input. These questions are just as much a way for me to learn as a way to get an answer.

NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
Joshua Reisbord
  • 111
  • 2
  • 7

2 Answers2

1

Working code

const useStyles = makeStyles({
  link: {
    color: 'white',
    position: 'relative',

    '&:before': {
      content: "''",
      position: 'absolute',
      width: '0',
      height: '2px',
      bottom: '-3px',
      left: '50%',
      transform: 'translate(-50%,0%)',
      backgroundColor: 'red',
      visibility: 'hidden',
      transition: 'all 0.3s ease-in-out',
    },
    '&:hover:before': {
      visibility: 'visible',
      width: '100%',
    },
  },
});
<Link underline="never" className={classes.link}>
  <Typography component="span">link</Typography>
</Link>

Some explanation why your code didn't work:

  • Change content: "" to content: "''". Related answer.
  • Add underline="never" to Link to remove the built-in underline in the anchor element when hovering.
  • Change the Typography's root component to span or set its display to inline to make the container width and the underline width match the text content.
  • Change &:before:hover to &:hover:before: The former means hover the underline to run the animation, but its width is 0 so it can't be hovered, the latter means hover the link to run the line animation.
  • Add these 2 lines to make the underline expands from the middle:
left: '50%',
transform: 'translate(-50%,0%)',

Codesandbox Demo

NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
0

I have spent hours trying to find the right combination to use Link and override the webkit underline to prevent the links in my navigation from having an underline without explicitly adding text-decoration: none to my global CSS. I had to add 'textDecoration: 'none' to the makeStyles function in this example and of course change red to blue but this works beautifully for my nav bar.

const useStyles = makeStyles({
  link: {
    color: 'white',
    position: 'relative',
    textDecoration: 'none',

    '&:before': {
      content: "''",
      position: 'absolute',
      width: '0',
      height: '2px',
      bottom: '-3px',
      left: '50%',
      transform: 'translate(-50%,0%)',
      backgroundColor: 'blue',
      visibility: 'hidden',
      transition: 'all 0.3s ease-in-out',
    },
    '&:hover:before': {
      visibility: 'visible',
      width: '100%',
    },
  },
})