Waves.js

Click. Splash. Repeat.

Waves.js is a lightweight JavaScript library that adds a Material Design-inspired ripple effect to UI elements. It creates a subtle, tactile feedback animation when users interact with buttons, cards, and other clickable elements, enhancing the overall user experience with visual confirmation of touch interactions.

Pro Tip: Waves.js works with both mouse and touch events, making it perfect for creating consistent interaction feedback across desktop and mobile interfaces.

Installation

Include the Waves.js script and CSS in your HTML file:

<!-- Include Waves CSS -->
<link rel="stylesheet" href="path/to/waves.min.css">

<!-- Include Waves JS -->
<script src="path/to/waves.min.js"></script>

Basic initialization

// Initialize Waves with default options
document.addEventListener('DOMContentLoaded', function() {
    Waves.init();
});

// Or with custom options
Waves.init({
    duration: 500,
    delay: 200
});

HTML Structure

<!-- Basic button with waves effect -->
<button class="waves-effect">Click me</button>

<!-- Button with waves effect and color -->
<button class="waves-effect waves-light">Light Effect</button>

<!-- Other elements with waves effect -->
<div class="card waves-effect">Card with ripple</div>
<a href="#" class="waves-effect waves-teal">Teal Ripple Link</a>
Important: The waves-effect class is required for any element you want to apply the ripple effect to. Additional classes like waves-light or waves-teal modify the appearance of the effect.

Configuration Options

Waves.js offers several configuration options to customize the ripple effect:

Option Default Value Description Type
duration 750 Duration of the ripple animation in milliseconds. number
delay 200 Delay before showing the ripple effect on touch devices, in milliseconds. number

CSS Classes

Waves.js uses several CSS classes to control the appearance of the ripple effect:

Class Description
waves-effect Base class required for any element to have the ripple effect.
waves-light Creates a light-colored ripple (white), ideal for dark backgrounds.
waves-red, waves-yellow, waves-orange, waves-purple, waves-green, waves-teal Colored ripple effects matching the specified color.
waves-circle Creates a circular ripple effect, ideal for round buttons.
waves-float Adds a subtle floating animation when hovering over the element.
waves-block Makes the ripple effect fill the entire element (useful for block elements).
Pro Tip: You can combine multiple classes for different effects. For example, waves-effect waves-light waves-circle creates a light circular ripple effect.

API Methods

Waves.js exposes several methods for programmatic control:

// Initialize Waves with options
Waves.init({
    duration: 500,
    delay: 200
});

// Attach Waves effect to elements
Waves.attach('.my-button');
Waves.attach('.my-card', ['waves-light', 'waves-block']);

// Programmatically create a ripple
Waves.ripple(document.querySelector('.my-button'), {
    wait: 1000,                // Wait 1000ms before hiding the ripple
    position: {x: 20, y: 20}   // Position of the ripple (default is center)
});

// Remove all ripples from elements
Waves.calm('.my-button');

Method Details

Method Parameters Description
Waves.init(options) options: Object with configuration options Initializes Waves.js with the specified options.
Waves.attach(elements, classes) elements: DOM element, selector, or array of elements
classes: String or array of additional classes
Attaches the Waves effect to the specified elements with optional additional classes.
Waves.ripple(elements, options) elements: DOM element, selector, or array of elements
options: Object with ripple options (wait, position)
Programmatically triggers a ripple effect on the specified elements.
Waves.calm(elements) elements: DOM element, selector, or array of elements Removes all ripples from the specified elements.
Waves.displayEffect(options) options: Object with configuration options Deprecated. Use Waves.init() instead.

Special Elements Handling

Waves.js includes special handling for certain HTML elements:

Input Elements

<!-- Input with waves effect -->
<input type="button" class="waves-effect" value="Input Button">

When applied to <input> elements, Waves.js automatically wraps the input in a container to properly display the ripple effect.

Image Elements

<!-- Image with waves effect -->
<img src="image.jpg" class="waves-effect" alt="Image with ripple">

Similar to inputs, images are wrapped in a container to properly display the ripple effect.

Note: For SVG elements, Waves.js has special handling to ensure the ripple effect works correctly.

Touch Device Handling

Waves.js includes sophisticated touch event handling to ensure a smooth experience on mobile devices:

// Touch handling in Waves.js
var TouchHandler = {
    touches: 0,
    
    allowEvent: function(e) {
        var allow = true;
        
        if (/^(mousedown|mousemove)$/.test(e.type) && TouchHandler.touches) {
            allow = false;
        }
        
        return allow;
    },
    
    registerEvent: function(e) {
        var eType = e.type;
        
        if (eType === 'touchstart') {
            TouchHandler.touches += 1; // push
        } else if (/^(touchend|touchcancel)$/.test(eType)) {
            setTimeout(function() {
                if (TouchHandler.touches) {
                    TouchHandler.touches -= 1; // pop after 500ms
                }
            }, 500);
        }
    }
};

Key features of the touch handling include:

  • Touch and mouse event coordination: Prevents duplicate events when both touch and mouse events are triggered
  • Delay for touch devices: Adds a configurable delay before showing the ripple on touch devices
  • Touch movement detection: Cancels the ripple effect if the user moves their finger (for scrolling)
  • Multi-touch support: Properly handles multiple simultaneous touches

Usage Examples

Basic Buttons

<!-- Default ripple effect -->
<button class="btn waves-effect">Default</button>

<!-- Light ripple effect (for dark backgrounds) -->
<button class="btn btn-dark waves-effect waves-light">Light Effect</button>

<!-- Colored ripple effects -->
<button class="btn waves-effect waves-red">Red Effect</button>
<button class="btn waves-effect waves-yellow">Yellow Effect</button>
<button class="btn waves-effect waves-orange">Orange Effect</button>
<button class="btn waves-effect waves-purple">Purple Effect</button>
<button class="btn waves-effect waves-green">Green Effect</button>
<button class="btn waves-effect waves-teal">Teal Effect</button>

Cards and Panels

<!-- Card with ripple effect -->
<div class="card waves-effect">
    <div class="card-body">
        This entire card has a ripple effect
    </div>
</div>

<!-- Panel with block ripple effect -->
<div class="panel waves-effect waves-block">
    <div class="panel-heading">Panel Title</div>
    <div class="panel-body">
        This panel has a block ripple effect
    </div>
</div>

Circular Buttons

<!-- Circular button with ripple effect -->
<button class="btn btn-circle waves-effect waves-circle">
    <i class="fa fa-plus"></i>
</button>

<!-- Circular button with light ripple effect -->
<button class="btn btn-dark btn-circle waves-effect waves-circle waves-light">
    <i class="fa fa-check"></i>
</button>

Dynamic Attachment

// Dynamically add waves effect to elements created after page load
document.addEventListener('DOMContentLoaded', function() {
    // Initialize Waves
    Waves.init();
    
    // Create a new button
    var button = document.createElement('button');
    button.textContent = 'Dynamic Button';
    document.body.appendChild(button);
    
    // Attach waves effect to the new button
    Waves.attach(button, ['waves-light']);
    
    // Attach to multiple elements with additional classes
    Waves.attach('.dynamic-elements', ['waves-green', 'waves-float']);
});

Best Practices

  • Apply the ripple effect only to interactive elements that users can click or tap
  • Use appropriate colors for the ripple effect that complement your UI design
  • For dark-colored elements, use the waves-light class for better visibility
  • For circular buttons, use the waves-circle class for a more natural-looking effect
  • Initialize Waves.js after the DOM is fully loaded to ensure all elements are properly processed
  • For dynamically created elements, use Waves.attach() to add the ripple effect
  • Consider using waves-float for elements that should have additional hover feedback
Pro Tip: For the best user experience, keep the ripple effect subtle and quick. A duration of 500-750ms is usually ideal for most interfaces.

Browser Support

Waves.js supports all modern browsers including:

  • Chrome
  • Firefox
  • Safari
  • Edge
  • Opera
  • Mobile browsers (iOS Safari, Android Chrome)

For older browsers like IE11, Waves.js includes fallbacks to ensure basic functionality.

Note: For optimal performance on mobile devices, consider adjusting the duration and delay options to match the responsiveness of your target devices.

Troubleshooting

Common Issues:
  • Ripple effect not showing? Ensure the element has the waves-effect class and is properly initialized.
  • Ripple effect not visible on dark elements? Add the waves-light class for better contrast.
  • Effect not working on dynamically created elements? Use Waves.attach() after creating the elements.
  • Ripple effect looks distorted? For non-rectangular elements, try adding the waves-circle class.
  • Performance issues on mobile? Reduce the duration value when initializing Waves.js.