0

I wanted to achieve a button with effect like this https://codepen.io/electerious/pen/rroqdL and wanted it to make it a React component.

The original example is using css variable so I thought it would be easier to implement it using CSS-in-JS, in my case I chose to use Emotion(https://emotion.sh).

First, this is my current code

import React from "react";
import { css } from "@emotion/core";

const style = css`
  a {
    position: relative;
    display: inline-block;
    padding: 1.2em 2em;
    text-decoration: none;
    text-align: center;
    cursor: pointer;
    user-select: none;
    color: white;

    &::before {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
      background: linear-gradient(135deg, #6e8efb, #a777e3);
      border-radius: 4px;
      transition: box-shadow 0.5s ease, transform 0.2s ease;
      will-change: transform;
      box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
      transform: translateY(var(--ty, 0)) rotateX(var(--rx, 0))
        rotateY(var(--ry, 0)) translateZ(var(--tz, -12px));
    }

    &:hover::before {
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
    }

    &::after {
      position: relative;
      display: inline-block;
      content: attr(data-title);
      transition: transform 0.2s ease;
      font-weight: bold;
      letter-spacing: 0.01em;
      will-change: transform;
      transform: translateY(var(--ty, 0)) rotateX(var(--rx, 0))
        rotateY(var(--ry, 0));
    }
  }
`;

const Button = () => {
  return (
    <div css={style}>
      <a href="#" dataTitle="Awesome Button">
        Button
      </a>
    </div>
  );
};

export default Button;

However I have encountered two difficulties.

  1. according the original example, it manipulates the <a/> tag directly in the js file using const aElem = document.querySelector('a') const boundingClientRect = aElem.getBoundingClientRect(). I am not sure how I can achieve this using React because it seems like I don't know how to directly access the DOM element I am about to render in React.

  2. Again, the original example uses const docStyle = document.documentElement.style. I don't know the equivalent in React.

I am new to React and even CSS-In-JS in general. I would greatly appreciate it if someone can code out this example using React.

1 Answer 1

1

You can actually do this using the useRef (see the documentation for hooks and more specifically the useRef hook here - https://reactjs.org/docs/hooks-reference.html#useref) hook without changing much of the code, not sure if you should do it this way but it works?

I have used an external SCSS file rather than emotion but you should be able to replicate pretty easily.

Here is the working example: https://codesandbox.io/s/cocky-neumann-kik51?fontsize=14

Sign up to request clarification or add additional context in comments.

8 Comments

Hi thanks for the prompt reply. Sorry what did you mean by saying "not sure if you should do it this way but it works?". Did you mean using useRef is not a good practice?
Well refs have always been discouraged by the React team because it is imperative programming rather than React's "usual" declarative way that's all.
If you do find this answer useful could I ask you to up vote or accept as answer at some point :) thanks
Hi. Sorry one last question, is there a way to style the title displayed in the button by ` <a href={to} ref={buttonRef} data-title="Awesome Button" />`, i.e. "Awesome Button"?
Absolutely @Joji I've just updated the codesandbox example showing you how you can pass that down as a prop.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.