Take a look at this Codepen example I created. It showcases a hover effect where the gradient follows the mouse cursor.
In order to achieve this effect, I have defined two CSS variables - --x
and --y
, to keep track of the mouse position on the button. The --size
CSS variable is responsible for adjusting the dimensions of the gradient.
The gradient is generated using the rule
background: radial-gradient(circle closest-side, pink, transparent)
which ensures it appears correctly on the button.
To make this work, I used functions like Document.querySelector()
and EventTarget.addEventListener()
to handle the 'mousemove'
event. Additionally, Element.getBoundingClientRect()
and
CSSStyleDeclaration.setProperty()
are employed to update the values of --x
and --y
CSS variables dynamically.
Now, my next challenge is to recreate this effect as a styled component in React Typescript utilizing MUI Button. I attempted to declare the necessary CSS styles within my styled Button component, however, it seems they are not being applied properly.
Button.tsx
import React from 'react';
import { styled, Theme } from '@mui/material/styles';
import { Button, SxProps } from '@mui/material';
const HoverButton = styled(Button)(({ theme }) => ({
borderRadius: 100,
".mouse-cursor-gradient-tracking": {
position: "relative",
background: "#7983ff",
padding: "0.5rem 1rem",
fontSize: "1.2rem",
border: "none",
color: theme.palette.secondary.contrastText,
cursor: "pointer",
outline: "none",
overflow: "hidden",
},
".mouse-cursor-gradient-tracking span": {
position: "relative",
},
".mouse-cursor-gradient-tracking:before": {
--size: 0,
content: '',
position: "absolute",
left: "var(--x)",
top: "var(--y)",
width: "var(--size)",
height: "var(--size)",
background: "radial-gradient(circle closest-side, pink, transparent)",
transform: "translate(-50%, -50%)",
transition: "width 0.2s ease, height 0.2s ease",
},
".mouse-cursor-gradient-tracking:hover:before": {
"--size": "200px"
},
}));
export function SubmitButton(props: { children: React.ReactNode; sx?: SxProps<Theme> }) {
let button:<Element | null> = document.querySelector('.mouse-cursor-gradient-tracking');
button.addEventListener('mousemove', e => {
let rect = e.target.getBoundingClientRect();
let x = e.clientX - rect.left;
let y = e.clientY - rect.top;
button.style.setProperty('--x', x + 'px');
button.style.setProperty('--y', y + 'px');
});
return (
<HoverButton type="submit" variant="contained" sx={props.sx}>
{props.children}<span>Hover me</span>
</HoverButton>
);
}