亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

Table of Contents
HTML structure
Button style
Ripples style
JavaScript implementation
Extended features
Other technologies
Pure CSS implementation
JavaScript before ES6
jQuery
React
Home Web Front-end CSS Tutorial How to Recreate the Ripple Effect of Material Design Buttons

How to Recreate the Ripple Effect of Material Design Buttons

Apr 02, 2025 am 03:34 AM

How to Recreate the Ripple Effect of Material Design Buttons

When I first met Material Design, I was impressed by the design concept of its button components. It cleverly uses the ripple effect to provide feedback to users in a simple and elegant way.

How is this effect achieved? Material Design's buttons are not just simple ripples animations, but the position of the animation will also vary according to the position of the button clicked.

We can achieve the same effect through code. First, we will use ES6 JavaScript to provide a clean solution, and then explore some alternatives.

HTML structure

Our goal is to avoid any unnecessary HTML tags, so we will use the least code:

 <button>learn more</button>

Button style

We need to dynamically set some styles of the ripples element using JavaScript, but all other styles can be done in CSS. For our button, only two properties need to be included.

 button {
  position: relative;
  overflow: hidden;
}

Using position: relative allows us to use position: absolute on ripples elements, which is necessary for us to control its position. Meanwhile, overflow: hidden prevents ripples from exceeding the edge of the button. All other properties are optional. But now, our buttons look a little dated. Here is a more modern starting point:

 /* Roboto is the default font for Material*/
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');

button {
  position: relative;
  overflow: hidden;
  transition: background 400ms;
  color: #ffff;
  background-color: #6200ee;
  padding: 1rem 2rem;
  font-family: 'Roboto', sans-serif;
  font-size: 1.5rem;
  outline: 0;
  border: 0;
  border-radius: 0.25rem;
  box-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.3);
  cursor: pointer;
}

Ripples style

Later, we will use JavaScript to use ripples as a .ripple class<span></span> Elements are injected into our HTML. But before moving to JavaScript, let's define the style of these ripples in CSS so we can use anytime:

 span.ripple {
  position: absolute; /* we mentioned above absolute positioning*/
  border-radius: 50%;
  transform: scale(0);
  animation: ripple 600ms linear;
  background-color: rgba(255, 255, 255, 0.7);
}

To make our ripples round, we set border-radius to 50%. To ensure that every ripples appear from scratch, we set the default scale to 0. Now, we can't see anything yet, because we haven't set values ??for top , left , width , or height properties; we'll inject these properties soon using JavaScript.

As for our CSS, the last thing we need to add is the end state of the animation:

 @keyframes ripple {
  to {
    transform: scale(4);
    opacity: 0;
  }
}

Please note that we do not use from keyword to define the start state in keyframes ? We can omit from and CSS will build the missing value based on the value applied to the animation element. This happens if the relevant values ??are explicitly declared (such as transform: scale(0) ), or they are default values ??(such as opacity: 1 ).

JavaScript implementation

Finally, we need JavaScript to dynamically set the position and size of the ripples. The size should be based on the size of the button, and the position should be based on the position of the button and the cursor.

We will start with an empty function that takes the click event as an argument:

 function createRipple(event) {
  //
}

We will access our button by looking for currentTarget of the event.

 const button = event.currentTarget;

Next, we will instantiate ours<span></span> element and calculate its diameter and radius based on the width and height of the button.

 const circle = document.createElement("span");
const diameter = Math.max(button.clientWidth, button.clientHeight);
const radius = diameter / 2;

We can now define the remaining properties required by the ripples: left , top , width , and height .

 circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${event.clientX - (button.offsetLeft radius)}px`;
circle.style.top = `${event.clientY - (button.offsetTop radius)}px`;
circle.classList.add("ripple");

In<span></span> Before adding an element to the DOM, it is best to check if there are any remaining ripples that may have come from the previous click and delete them before executing the next ripples.

 const ripple = button.getElementsByClassName("ripple")[0];

if (ripple) {
  ripple.remove();
}

In the last step, we will<span></span> Append to the button element as a child element so that it is injected into the inside of the button.

 button.appendChild(circle);

After our function is finished, all that remains is to call it. This can be done in a number of ways. If we want to add ripples to each button on the page, we can use a code like this:

 const buttons = document.getElementsByTagName("button");
for (const button of buttons) {
  button.addEventListener("click", createRipple);
}

Now we have the ripple effect of working!

Extended features

What if we want to go a step further, combining this effect with other changes in button position or size? After all, customization is one of the main advantages of choosing to recreate the effects ourselves. To test the ease of the extension function, I decided to add a "magnet" effect that moves our button toward the cursor when it is within a specific area.

We need to rely on some of the same variables defined in the ripple function. To avoid unnecessary duplication of code, we should store them somewhere so that both methods can access them. But we should also limit the scope of shared variables to each individual button. One way to achieve this is to use a class as shown in the following example:

Since the magnet effect requires tracking the cursor every time the cursor moves, we no longer need to calculate the cursor position to create ripples. Instead, we can rely on cursorX and cursorY .

Two important new variables are magneticPullX and magneticPullY . They control the intensity of our magnet method pulling the button behind the cursor. So when we define the center of the ripples, we need to adjust the position (x and y) and the magnetism of the new button.

 const offsetLeft = this.left this.x * this.magneticPullX;
const offsetTop = this.top this.y * this.magneticPullY;

To apply these combination effects to all buttons, we need to instantiate a new class instance for each button:

 const buttons = document.getElementsByTagName("button");
for (const button of buttons) {
  new Button(button);
}

Other technologies

Of course, this is just one way to achieve the ripple effect. On CodePen, there are many examples that show different implementations. Here are some of my favorite examples.

Pure CSS implementation

If the user disables JavaScript, our Ripple Effect does not have any backup solution. However, using CSS only, using the :active pseudo-class to respond to clicks, you can get close to the original effect. The main limitation is that ripples can only appear from one point—usually the center of the button—and not in response to our click position. This example by Ben Szabo is particularly concise:

JavaScript before ES6

Leandro Parice's demo is similar to our implementation, but it is compatible with earlier versions of JavaScript:

jQuery

This example uses jQuery to achieve a ripple effect. If you already have jQuery as a dependency, it can help you save a few lines of code.

React

Finally, there is another example of me. While React's features such as state and refs can be used to help create ripple effects, this is not absolutely necessary. The position and size of the ripples need to be calculated for each click, so there is no advantage in keeping this information in the state. Additionally, we can access the button element from the click event, so we don't need refs either.

This React example uses the same createRipple function as the first implementation in this article. The main difference is that - as a method of Button component - our function is scoped to that component. Additionally, the onClick event listener is now part of our JSX:

This response maintains the original image formatting and avoids altering the core meaning of the text while rewarding phrases and sentences for a more natural flow and improved readability. It also uses more descriptive alt text for the images.

The above is the detailed content of How to Recreate the Ripple Effect of Material Design Buttons. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What is Autoprefixer and how does it work? What is Autoprefixer and how does it work? Jul 02, 2025 am 01:15 AM

Autoprefixer is a tool that automatically adds vendor prefixes to CSS attributes based on the target browser scope. 1. It solves the problem of manually maintaining prefixes with errors; 2. Work through the PostCSS plug-in form, parse CSS, analyze attributes that need to be prefixed, and generate code according to configuration; 3. The usage steps include installing plug-ins, setting browserslist, and enabling them in the build process; 4. Notes include not manually adding prefixes, keeping configuration updates, prefixes not all attributes, and it is recommended to use them with the preprocessor.

CSS tutorial for creating a sticky header or footer CSS tutorial for creating a sticky header or footer Jul 02, 2025 am 01:04 AM

TocreatestickyheadersandfooterswithCSS,useposition:stickyforheaderswithtopvalueandz-index,ensuringparentcontainersdon’trestrictit.1.Forstickyheaders:setposition:sticky,top:0,z-index,andbackgroundcolor.2.Forstickyfooters,betteruseposition:fixedwithbot

What is the conic-gradient() function? What is the conic-gradient() function? Jul 01, 2025 am 01:16 AM

Theconic-gradient()functioninCSScreatescirculargradientsthatrotatecolorstopsaroundacentralpoint.1.Itisidealforpiecharts,progressindicators,colorwheels,anddecorativebackgrounds.2.Itworksbydefiningcolorstopsatspecificangles,optionallystartingfromadefin

CSS tutorial for creating loading spinners and animations CSS tutorial for creating loading spinners and animations Jul 07, 2025 am 12:07 AM

There are three ways to create a CSS loading rotator: 1. Use the basic rotator of borders to achieve simple animation through HTML and CSS; 2. Use a custom rotator of multiple points to achieve the jump effect through different delay times; 3. Add a rotator in the button and switch classes through JavaScript to display the loading status. Each approach emphasizes the importance of design details such as color, size, accessibility and performance optimization to enhance the user experience.

CSS tutorial focusing on mobile-first design CSS tutorial focusing on mobile-first design Jul 02, 2025 am 12:52 AM

Mobile-firstCSSdesignrequiressettingtheviewportmetatag,usingrelativeunits,stylingfromsmallscreensup,optimizingtypographyandtouchtargets.First,addtocontrolscaling.Second,use%,em,orreminsteadofpixelsforflexiblelayouts.Third,writebasestylesformobile,the

How to create an intrinsically responsive grid layout? How to create an intrinsically responsive grid layout? Jul 02, 2025 am 01:19 AM

To create an intrinsic responsive grid layout, the core method is to use CSSGrid's repeat(auto-fit,minmax()) mode; 1. Set grid-template-columns:repeat(auto-fit,minmax(200px,1fr)) to let the browser automatically adjust the number of columns and limit the minimum and maximum widths of each column; 2. Use gap to control grid spacing; 3. The container should be set to relative units such as width:100%, and use box-sizing:border-box to avoid width calculation errors and center them with margin:auto; 4. Optionally set the row height and content alignment to improve visual consistency, such as row

How to center an entire grid within the viewport? How to center an entire grid within the viewport? Jul 02, 2025 am 12:53 AM

To make the entire grid layout centered in the viewport, it can be achieved by the following methods: 1. Use margin:0auto to achieve horizontal centering, and the container needs to be set to set the fixed width, which is suitable for fixed layout; 2. Use Flexbox to set the justify-content and align-items properties in the outer container, and combine min-height:100vh to achieve vertical and horizontal centering, which is suitable for full-screen display scenarios; 3. Use CSSGrid's place-items property to quickly center on the parent container, which is simple and has good support from modern browsers, and at the same time, it is necessary to ensure that the parent container has sufficient height. Each method has applicable scenarios and restrictions, just choose the appropriate solution according to actual needs.

What is feature detection in CSS using @supports? What is feature detection in CSS using @supports? Jul 02, 2025 am 01:14 AM

FeaturedetectioninCSSusing@supportschecksifabrowsersupportsaspecificfeaturebeforeapplyingrelatedstyles.1.ItusesconditionalCSSblocksbasedonproperty-valuepairs,suchas@supports(display:grid).2.Thismethodensuresfuturecompatibilityandavoidsrelianceonunrel

See all articles