<h1>Ripple effect using CSS Variables</h1>
<span>
<button anim="ripple">Button</button>
<a href="#" anim="ripple">Link</a>
<a class="rainbow" href="#" anim="ripple">Rainbow</a>
[anim="ripple"] {
// Customize effect by defining the following
// variables on the parent element
// --ripple-background: white;
// --ripple-opacity: 0.3;
// --ripple-duration: 600ms;
// --ripple-easing: linear;
position: relative;
overflow: hidden;
&:before {
content: '';
position:absolute;
display: block;
background: var(--ripple-background, white);
border-radius: 50%;
pointer-events: none;
// position and size
top: calc(var(--y) * 1px);
left: calc(var(--x) * 1px);
width: calc(var(--d) * 1px);
height: calc(var(--d) * 1px);
// animated properties
opacity: calc(var(--o, 1) * var(--ripple-opacity, 0.3));
transition: calc(var(--t, 0) * var(--ripple-duration, 600ms)) var(--ripple-easing,linear);
transform: translate(-50%, -50%) scale(var(--s, 1));
transform-origin: center;
}
}
// Just some styling
button {
--ripple-background: white;
--ripple-opacity: 0.3;
--ripple-duration: 600ms;
border:1px solid darken(tomato, 20%);
border-radius:0;
padding: 0.75em 3em;
font-size: 1em;
outline: none;
display:block;
background: tomato;
color: white;
-webkit-tap-highlight-color: rgba(0,0,0,0);
min-width: 200px;
text-align: center;
cursor: pointer;
user-select: none;
}
a {
--ripple-background: black;
--ripple-opacity: 0.1;
--ripple-duration: 600ms;
display: block;
margin-top: 1em;
padding: 0.75em 3em;
background: whitesmoke;
color: black;
text-decoration: none;
border:1px solid darken(whitesmoke, 10%);
min-width: 200px;
text-align: center;
-webkit-tap-highlight-color: rgba(0,0,0,0);
transition: background-color 300ms;
&:hover { background-color: darken(whitesmoke, 3%);}
}
.rainbow {
--ripple-opacity: 1;
--ripple-background: radial-gradient(circle at center, rebeccapurple, dodgerblue, olive, gold, orange, tomato);
--ripple-duration: 2000ms;
--ripple-easing: cubic-bezier(0, .5, .5, 1);
background-color: skyblue;
color: rgba(white, 0.7);
transition: background-color 300ms, color 300ms;
&:hover { background-color: darken(skyblue, 10%); color: rgba(white, 1);}
}
@import url("https://fonts.googleapis.com/css?family=Roboto:400,400i,700");
html { box-sizing: border-box; } *,*::before,*::after { box-sizing: inherit; }
html, body { height: 100%; font-family: Roboto, sans-serif}
body { margin: 0; display: flex; flex-direction: column; justify-content: center; align-items: center; }
h1 { font-size:1.2em;}
View Compiled
[].map.call(document.querySelectorAll('[anim="ripple"]'), el=> {
el.addEventListener('click',e => {
e = e.touches ? e.touches[0] : e;
const r = el.getBoundingClientRect(), d = Math.sqrt(Math.pow(r.width,2)+Math.pow(r.height,2)) * 2;
el.style.cssText = `--s: 0; --o: 1;`; el.offsetTop;
el.style.cssText = `--t: 1; --o: 0; --d: ${d}; --x:${e.clientX - r.left}; --y:${e.clientY - r.top};`
})
})
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.