DEV Community

Cover image for Three more satisfying buttons and how to make them
Ammadeo
Ammadeo

Posted on • Updated on

Three more satisfying buttons and how to make them

Satisfying buttons can take many forms. Let's see three more!

Glowing button

This button is made of glass and has a colourful light inside. The light follows a user's interactions — like mouse movement.

Let's see it in action

How to implement it

I'd say upfront the implementation is not beginner-friendly.
Firstly We'll use inner shadows to make a glass-like effect.
If You want to learn more about Glassmorphism, check out New Glassmorphism? How to Create Neon Glass Effect UI Design by
Przemysław Baraniak.

button {
  /* Background color in HSL 
     It's "raw" because it needs to work with custom alpha */
  --color-background-raw: 4, 12%, 16%;

  /* Glass effect inner shadows */
  box-shadow:
    inset 0 2px 1px 0 hsla(0, 0%, 100%, 0.4),
    inset 0 2em 2em 0 hsla(0, 0%, 100%, 0.12),
    inset 0 -3px 0.25em 0 hsla(0, 0%, 100%, 0.12),
    inset 0 -0.25em 1em 0 hsla(0, 0%, 100%, 0.12),
    inset 0 -2em 2em 0 hsla(var(--color-background-raw), 0.05),
    inset 0 0.25em 0.5em 0 hsla(0, 0%, 100%, 0.2);
}
Enter fullscreen mode Exit fullscreen mode

Next, we'll use the after pseudo-element as a glowing circle following a user's interactions. Let's make use of the CSS Properties and Values API. This API allows us to define types of CSS Properties, which is needed to animate them.

/* Use CSS Properties and Values API
It enables transitions for css properties 
*/
/* Will control the left position of the glowing circle. */
@property --glow-left {
  /* Allow any length or percentage e.g. 1px, 1em or 20% */
  syntax: '<length-percentage>';
  /* Allow children elements to inherit this property */
  inherits: true;
  /* Set default value */
  initial-value: 50%;
}
/* Will control the top position of the glowing circle. */
@property --glow-top {
  syntax: '<length-percentage>';
  inherits: true;
  initial-value: 50%;
}

/* Glowing circle */
button.glow::after {
  /* Make sure it shows */
  content: "";

  /* Position it */
  position: absolute;
  top: var(--glow-top);
  left: var(--glow-left);
  /* Keep it centred */
  transform: translate(-50%, -50%);

  /* Make it smooth!
     This is why we need CSS Properties and Values API
   */
  transition: 
    top 80ms linear,
    left 80ms linear;
}
Enter fullscreen mode Exit fullscreen mode

Let's use a bit of JavaScript to control them.

// Select the button
const Button = document.querySelector("button.glow");

// Set glow position css properties
const setGlowPosition = (event) => {
  // Get the event's coordinates relative to the button
  const { left, top } = event.target.getBoundingClientRect();
  const offsetX = event.clientX - left;
  const offsetY = event.clientY - top;

  // Prevent setting position on keyboard click
  if (offsetX > 0 && offsetY > 0) {
    // wait for animation frame for better performance
    requestAnimationFrame(() => {
      // set css property
      event.target.style.setProperty("--glow-left", `${offsetX}px`);
      event.target.style.setProperty("--glow-top", `${offsetY}px`);
    });
  }
};

// Set glow position on mousemove (mouse) and click (touch and keyboard)
Button.addEventListener("mousemove", setGlowPosition);
Button.addEventListener("click", setGlowPosition);
Enter fullscreen mode Exit fullscreen mode

Plastic button

The button will deform inwards on press.

Let's see the implementation

How to make it?

To make a neuromorphic button, we need to give it a few shadows. By default, we want to make it look raised.

button {
  /* Add outside shadows */
  box-shadow: 
    /* Top left white shadow */
    -4px -4px 16px 0 hsla(0, 0%, 100%, 0.14),
    /* Bottom right black shadow */
    4px 4px 16px 0 hsla(0, 0%, 0%, 0.14);
}

/* On button press */
button:active {
  /* Add inside shadows */
  box-shadow: 
    /* Inner top left black shadow */
    inset -4px -4px 16px 0 hsla(0, 0%, 0%, 0.14),
    /* Inner bottom right white shadow */
    inset 4px 4px 16px 0 hsla(0, 0%, 100%, 0.14);

  /* Make it a bit darker */
  filter: brightness(0.96);
}
Enter fullscreen mode Exit fullscreen mode

Don't forget about UX! Let's add a light border around it to make it easier to spot.

button {
  /* Add glass-like border  */
  border: hsla(0, 0%, 100%, 0.2) 1px solid;
}
Enter fullscreen mode Exit fullscreen mode

Learn more about plastic like buttons from Neumorphism in user interfaces by Michal Malewicz.

Simple button

Not every satisfying button must be hard to implement. This simple button will use only small transitions and shadows to make it feel great.

How does it look?

Let's make it

The implementation will be very similar to the one in the first part of this series. So if You didn't read it, do it now.

button {
  /* Use realistic shadows */
  box-shadow: 1px -1px 2px 0 hsla(0, 0%, 0%, 0.06),
              3px -3px 4px 0 hsla(0, 0%, 0%, 0.08);

  /* Make sure that transform-origin match translate() direction. 
     It makes translate() and scale() work it the same axis */  
  transform-origin: bottom center;
}

/* On button press */
button:active {
  /* Make shadows much smaller */
  box-shadow: 0 0 1px 0 hsla(0, 0%, 0%, 0.06),
              1px -1px 1px 0 hsla(0, 0%, 0%, 0.08);

  /* Apply perspective transformation */
  transform: 
    /* Translate down on Y axis */
    translatey(0.25em) 
    /* Make button smaller */
    scale(0.98);
}
Enter fullscreen mode Exit fullscreen mode

Challenge for You

Make Your satisfying button and share it in a comment below. I'd love to see it!

Discussion (0)