Efecto Ripple en CSS: Animación de onda sin JavaScript para botones y radar

- Andrés Cruz - EN In english

Efecto Ripple en CSS: Animación de onda sin JavaScript para botones y radar

Vamos a conocer cómo crear un efecto ripple con puras animaciones en CSS. El efecto ripple —también conocido como efecto de onda, palpitación o expansión— consiste en un círculo que se irradia hacia afuera simulando el movimiento del agua al caer una gota, y es especialmente útil para llamar la atención del usuario sobre un elemento clave de la interfaz, sin necesidad de JavaScript ni librerías externas como jQuery o Bootstrap.

Para conseguirlo, partiremos de un círculo (aunque puede ser cualquier forma) que se expande progresivamente con una sombra transparente muy llamativa. El truco real está en animar la propiedad box-shadow, logrando que crezca desde cero hasta un radio grande mientras se va desvaneciendo, lo cual produce esa sensación de onda que se propaga.

Comencemos con el HTML, que simplemente son tres divs con la clase ripple:

<div class="ripple"></div>
<div class="ripple" style="filter:hue-rotate(120deg)"></div>
<div class="ripple" style="filter:grayscale()"></div>

Observa que usando el filtro CSS filter: hue-rotate(120deg) podemos crear variantes de color sin duplicar el código, y con filter: grayscale() obtenemos una versión en escala de grises, todo a partir de la misma clase base.

Ahora el CSS. El truco central es expandir el box-shadow mediante una animación @keyframes:

.ripple {
  width: 1rem; /* control the size */
  background: #ff0; /* control the color here */
}
.ripple,
.ripple::before,
.ripple::after {
  content: "";
  display: grid;
  grid-area: 1/1;
  aspect-ratio: 1;
  border-radius: 50%;
  box-shadow: 0 0 0 0 #ff03; /* and here, 3 is the transparency */
  animation: r 3s linear infinite var(--s,0s);
}
.ripple::before {--s: 1s}
.ripple::after  {--s: 2s}
@keyframes r {
  to {box-shadow: 0 0 0 6rem #0000}
}
body {
  margin: 0;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 11rem;
  background: #000;
}
  • Con la propiedad gap se especifica la separación entre columnas y filas del contenedor flex, controlando el espacio visual entre los tres elementos ripple.
  • Con grid-area: 1/1 indicamos que los tres contenedores (.ripple, .ripple::before y .ripple::after) se apilen exactamente en el mismo espacio de la cuadrícula. Si comentas esta línea, verás que las tres ondas aparecen en posiciones distintas en lugar de superponerse.
  • Con los pseudoelementos ::before y ::after, definimos dos "capas" adicionales sobre el elemento principal sin añadir HTML extra. Cada una de estas capas representa una onda distinta dentro de la animación, y es lo que le da ese aspecto de múltiples ondas concéntricas.
CSS ripple effect animación con box-shadow expandiéndose
Efecto ripple CSS animando box-shadow
  • Como tenemos dos pseudoelementos (::before y ::after), en total son tres capas animadas: el propio .ripple más las dos capas generadas puramente con CSS.
  • Lo más interesante del código es que usa una propiedad personalizada (custom property) con alcance local. La variable --s vale 0s por defecto en .ripple, 1s en ::before y 2s en ::after. Ese desfase escalonado en el animation-delay es exactamente lo que produce el efecto de onda continua, pulsando cada segundo.
CSS ripple animation resultado final con múltiples ondas concéntricas
Resultado final del CSS ripple animation con múltiples ondas

Efecto ripple en los botones con CSS

Efecto ripple en los botones en CSS

Ahora vemos cómo aplicar el efecto ripple directamente sobre botones en CSS. A diferencia del ejemplo anterior, aquí el efecto no es continuo, sino que se activa al hacer clic, imitando el comportamiento del famoso ripple effect de Material Design de Google, pero sin una sola línea de JavaScript.

CSS ripple effect en botones al hacer clic con animación de onda

El estilo base del botón utiliza un radial-gradient como fondo, inicialmente colapsado a un tamaño mínimo. Esto es fundamental para el efecto: la transición de tamaño del gradiente es lo que simula la onda expansiva:

button {
  border: 2px solid;
  padding: 15px 40px;
  font-size: 25px;
  text-transform: uppercase;
  font-weight: bold;
  cursor: pointer;
  background: 
    radial-gradient(circle, #0000 1%, var(--c) 1%) 50%/0%
    var(--c);
  transition: background 0.6s;
}

El HTML de los botones es muy sencillo; usamos variables CSS (custom properties) para personalizar los colores de cada variante:

<button class="light">Button</button>
<button class="dark" style="--r: #f3738a;">Button</button>

El truco está en el estado :hover, donde expandimos el background-size a un valor enorme (15000%). Esto hace que el gradiente llene por completo el botón con una transición suave de 0.6s definida anteriormente:

button:hover{
  background-size: 15000%;
}

Y con la pseudoclase :active —que se activa en el momento exacto del clic— realizamos el cambio de color instantáneo (sin transición, gracias a transition: 0s) y reiniciamos el background-size a 100%. Es esta combinación de expansión en hover y colapso en active lo que genera la ilusión del efecto ripple al pulsar el botón:

button:active {
  background-color: var(--r,#FA6900); /* color of the ripple effect*/
  background-size: 100%;
  transition: 0s;
}
.light {
  --c: #fff;
  color: #0B486B;
}
.dark {
  --c: #0B486B;
  color: #fff;
  border-color: var(--c);
}
body {
  margin:0;
  height:100vh;
  display:grid;
  grid-auto-flow:column;
  place-content:center;
  grid-gap:50px;
}

¿Cómo crear un efecto radar con animaciones en CSS?

Efecto radar CSS con animaciones y keyframes - ondas expansivas

En esta sección veremos cómo crear un efecto radar con CSS empleando múltiples etiquetas div y un @keyframes que anima el tamaño y la opacidad de cada onda. El resultado es una animación de ondas concéntricas que se expanden desde el centro, muy similar a las que ves en aplicaciones de mapas o rastreo en tiempo real:

 
 
 
 

Para esto emplearemos las animaciones en CSS definiendo el siguiente @keyframes llamado radar. Observa cómo en los distintos puntos de la animación controlamos simultáneamente el width, el height, el grosor del border y la opacity:

@keyframes radar{
0%{
    width:75px;
    height:75px;
    border:40px 
    solid #fff;
    opacity:0
}50%{
    opacity:.1
}
90%{
    width:750px;
    height:750px
}
90%,100%{
    border:2px 
    solid #fff;
    opacity:0
}100%{
    width:1500px;
    height:1500px
}

Y un poco más de CSS para definir su forma, color, tamaño inicial y posicionarlo en el centro de la pantalla usando la propiedad transform junto con translate(-50%, -50%), una técnica clásica de centrado absoluto sobre un elemento con position: absolute:

.radar {
   position: absolute;
   top: 50%;
   left: 50%;
   border-radius: 50%;
   border: 10px solid #fff;
   width: 150px;
   height: 150px;
   transform: translate(-50%,-50%);
   animation: radar 2s infinite;
   opacity: 0;
}

Ahora definiremos cada una de las ondas en el HTML. Cada div con clase radar representa una onda independiente; al usar cuatro, conseguimos una sensación de profundidad y continuidad en la animación:

<div class="radar"></div>
<div class="radar"></div>
<div class="radar"></div>
<div class="radar"></div>

Para evitar que las ondas se solapen entre sí y se perciban como una sola, escalonamos el inicio de cada animación usando la propiedad animation-delay en combinación con el selector :nth-child(). Así, cada onda arranca en un momento ligeramente distinto, creando ese efecto visual de propagación continua:

.radar:nth-child(2) {
    animation-delay: .4s;
}
.radar:nth-child(3) {
    animation-delay: .9s;
}
.radar:nth-child(4) {
    animation-delay: .15s;
}

Y esto es lo esencial que necesitas saber para construir el efecto. Además, añadimos un fondo con azul oscuro como color de contraste, que es lo que permite apreciar las ondas blancas con claridad. Sin un buen contraste de color, el efecto pierde completamente su impacto visual.

Lo interesante de este código es su versatilidad: podemos adaptar fácilmente el ejemplo inicial para colocar cualquier elemento en el centro —como una imagen, un icono o un botón de llamada a la acción— obteniendo un efecto que atrae la atención del usuario al 100% sobre el elemento principal:

 
 
 
 

El siguiente experimento a ver es el de Múltiples fondos animados con CSS

Descubre cómo crear el CSS ripple effect (efecto de onda o palpitación) usando solo CSS y @keyframes. Incluye ripple en botones al hacer clic, efecto radar con animation-delay y variantes de color con filter. Sin JavaScript.


Únete a la comunidad de desarrolladores que han decidido dejar de picar código y empezar a construir productos reales. Recibe mis mejores trucos de arquitectura cada semana:

Acepto recibir anuncios de interes sobre este Blog.