CSS Shapes Module Level 2: Dominar la función shape() para trazados fluidos

En un laboratorio oscuro y futurista, brazos
robóticos proyectan láseres cian y violeta para esculpir una forma de onda geométrica en 3D

El diseño web moderno busca constantemente liberarse de la rigidez de las cajas rectangulares. Durante mucho tiempo, la integración de formas geométricas complejas o curvas orgánicas requería el uso de imágenes vectoriales SVG externas o aplicar pesados cálculos matemáticos a polígonos.

Con la llegada de CSS Shapes Module Level 2, una nueva funcionalidad nativa cambia las reglas del juego: la función shape(). Esta permite dibujar trazados complejos y fluidos directamente en tus hojas de estilo. En esta guía completa, exploraremos el funcionamiento técnico de esta función, sus comandos y sus ventajas frente a los métodos antiguos.

¿Por qué los métodos antiguos eran problemáticos?

Antes de la introducción de shape(), los desarrolladores disponían principalmente de dos herramientas para crear formas personalizadas mediante la propiedad clip-path:

  1. La función polygon(): Muy eficaz para formas geométricas basadas en líneas rectas (triángulos, rombos, estrellas). Sin embargo, en cuanto se necesitaba una curva, era obligatorio multiplicar los puntos de anclaje, lo que hacía que el código fuera ilegible y difícil de mantener.
  2. La función path(): Permite utilizar la sintaxis de los trazados SVG (como d="M 10,10 L 20,20 ..."). Su principal inconveniente radica en su rigidez. La función path() solo acepta valores absolutos en píxeles. Si el contenedor cambia de tamaño, el trazado permanece estático, lo que rompe el comportamiento adaptativo (responsivo) de la interfaz.

La función shape() resuelve este problema combinando la potencia de dibujo vectorial de la sintaxis SVG con la flexibilidad de las unidades de medida de CSS (porcentajes, em, rem o funciones matemáticas de cálculo).

¿Qué es la función shape()?

La función shape() es un valor de CSS que se aplica principalmente a las propiedades clip-path (para recortar un elemento) y offset-path (para animar un elemento a lo largo de un trazado preciso).

Su escritura se basa en un punto de partida definido, seguido de una serie de comandos de dibujo muy similares a los que se encuentran en el elemento <path> del formato SVG. La gran diferencia es que cada coordenada puede utilizar expresiones fluidas.

La estructura básica de un trazado shape()

Para entender cómo dibujar con esta función, imagina que sostienes un lápiz virtual sobre una hoja de papel:

  • El punto de partida (from): Colocas el lápiz sobre el papel en unas coordenadas precisas.
  • Los comandos de movimiento (move, line, curve, arc): Desplazas el lápiz para dibujar segmentos rectos, curvas o arcos de círculo.
  • El cierre (close): Dibujas una última línea recta para conectar tu posición actual con el punto de partida inicial.

Los comandos de dibujo explicados de forma sencilla

La siguiente tabla resume los principales comandos disponibles dentro de la función shape():

ComandoFunciónEjemplo de uso
fromDefine las coordenadas de inicio obligatorias del trazado.from 0% 0%
move to / move byDesplaza el lápiz sin dibujar una línea.move to 50px 50px
line to / line byDibuja una línea recta hacia un punto dado.line to 100% 50%
hline to / hline byAtajo para dibujar una línea puramente horizontal.hline to 80%
vline to / vline byAtajo para dibujar una línea puramente vertical.vline to 90%
curve toDibuja una curva Bézier utilizando puntos de control.curve to 100% 100% with 50% 80%
arc toDibuja un arco de círculo o de elipse.arc to 50% 50% of 10%
closeCierra automáticamente la forma volviendo al inicio.close

Nota sobre la diferencia entre “to” y “by”: La instrucción to utiliza coordenadas absolutas respecto al origen del contenedor (la esquina superior izquierda en 0,0). La instrucción by utiliza coordenadas relativas a la posición actual de tu lápiz virtual.

Una herramienta para dibujar tus formas en vivo

No siempre es fácil imaginar un trazado geométrico solo mirando líneas de código.

Para ayudarte, puedes utilizar esta herramienta interactiva gratuita: shape.lionel-peramo.com.

Esta herramienta te permite dibujar tus formas visualmente en la pantalla. Después, genera automáticamente el código CSS correspondiente, listo para copiar en tu hoja de estilo.

Caso práctico 1: Crear una burbuja de diálogo responsiva

Para ilustrar la sencillez de escritura y la fluidez de esta nueva especificación, crearemos una burbuja de diálogo adaptativa. La forma debe ajustarse automáticamente a las dimensiones del texto que contiene.

.speech-bubble
{
  width: clamp(15rem, 45vw, 35rem);
  height: clamp(10rem, 30vh, 22rem);
  background-color: oklch(25% 0.01 250);
  color: oklch(98% 0.005 250);
  clip-path: shape(
    from 0% 0%,
    line to 100% 0%,
    line to 100% min(80%, 18rem),
    line to min(60%, 20rem) min(80%, 18rem),
    line to min(50%, 17rem) 100%,
    line to min(40%, 14rem) min(80%, 18rem),
    line to 0% min(80%, 18rem),
    close
  );
}

Descifrando el trazado de la burbuja

  1. from 0% 0%: El lápiz comienza en la esquina superior izquierda.
  2. line to 100% 0%: Dibujamos una línea horizontal hasta la esquina superior derecha.
  3. line to 100% min(80%, 18rem): Bajamos por el borde derecho. La altura de la burbuja (sin incluir la flecha) se detendrá al 80% de la altura total del elemento, sin superar las 18rem.
  4. line to min(60%, 20rem) min(80%, 18rem): Comenzamos a dibujar la flecha inferior dirigiéndonos hacia el centro.
  5. line to min(50%, 17rem) 100%: Bajamos hasta el punto más bajo de nuestra flecha (al 100% de la altura del contenedor).
  6. line to min(40%, 14rem) min(80%, 18rem): Subimos de nuevo hacia el cuerpo de la burbuja.
  7. line to 0% min(80%, 18rem): Terminamos la línea horizontal inferior hacia el borde izquierdo.
  8. close: El navegador dibuja automáticamente el segmento vertical izquierdo restante para cerrar la forma.

Gracias a las funciones matemáticas min() y clamp(), la estructura se ajusta de manera fluida sin necesidad de consultas de medios (@media) para reorganizar la geometría de la caja.

Caso práctico 2: Un banner con el borde inferior curvado

Veamos ahora cómo introducir curvas dinámicas con el comando curve to. Queremos crear una sección de cabecera (Hero Banner) cuya parte inferior presente una suave ondulación.

.hero-banner:not(.is-minimal) {
  width            : 100%;
  height           : clamp(20rem, 50vh, 45rem);
  background-image : url('banner-image.avif');
  clip-path        : shape(
    from 0% 0%,
    line to 100% 0%,
    line to 100% min(90%, 40rem),
    curve to 0% min(90%, 40rem) with 50% 100%,
    close
  );
}

¿Cómo funciona la curva aquí?

El comando curve to 0% min(90%, 40rem) with 50% 100% le indica al navegador:

  • Que desplace el trazado desde el punto actual (la esquina inferior derecha) hacia la esquina inferior izquierda ( 0% min(90%, 40rem)).
  • Que utilice un punto de control situado en el centro, abajo del todo del elemento (50% 100%). Este punto de control actúa como un imán virtual que atrae el trazado hacia abajo, creando una curva simétrica.

Rendimiento y beneficios para el SEO

La integración de la función shape() aporta ventajas importantes a la arquitectura técnica y a la visibilidad de tus páginas web.

Rendimiento de hardware óptimo

La propiedad clip-path aplicada con funciones nativas de CSS como shape() es gestionada directamente por el procesador gráfico (GPU) del dispositivo. A diferencia de las soluciones alternativas que utilizan JavaScript para recalcular la posición de las etiquetas SVG al cambiar el tamaño de la ventana, shape() se ejecuta de forma casi instantánea.

Esta optimización reduce el tiempo de cálculo en el hilo principal (main thread) del navegador, mejorando de forma medible tus métricas de rendimiento clave (Core Web Vitals):

  • CLS (Cumulative Layout Shift): No hay desplazamientos inesperados del contenido durante la carga de la página.
  • LCP (Largest Contentful Paint): El renderizado visual de tus bloques gráficos más grandes se muestra más rápido.

Un impacto indirecto pero fuerte en el SEO

Los motores de búsqueda valoran la experiencia del usuario y la velocidad de carga. Un sitio web que responde de manera rápida y estable tanto en móviles como en ordenadores disfruta de un mejor potencial de indexación.

Además, al eliminar archivos SVG externos superfluos o scripts de JS para ajustes geométricos, reduces el peso total de tus páginas. Esto facilita que los robots de los motores de búsqueda exploren (crawl) tu sitio.

¿Todos los navegadores aceptan esta función?

La función shape() funciona en todos los navegadores web recientes. Es un estándar oficial desde el año 2026.

Aquí tienes la lista de versiones compatibles:

  • Chrome y Edge: a partir de la versión 135.
  • Safari: a partir de la versión 18.4.
  • Firefox: a partir de la versión 148.

¿Cómo ayudar a los ordenadores antiguos?

Algunos usuarios tienen ordenadores antiguos. Para estas personas, debes ofrecer una solución de respaldo. En informática, llamamos a esto un fallback.

Aquí tienes cómo hacerlo en CSS:

  1. Defines una forma sencilla con el comando polygon(). Todos los navegadores la entienden.
  2. Utilizas la regla @supports para hacerle una pregunta al navegador.
  3. Si el navegador comprende la función shape(), aplica la forma fluida en lugar de la forma sencilla.
.card-shape {
  clip-path : polygon(0% 0%, 100% 0%, 100% 80%, 60% 80%, 50% 100%, 40% 80%, 0% 80%);
}

@supports (clip-path: shape(from 0px 0px, line to 0px 0px)) {
  .card-shape {
    clip-path : shape(
      from 0% 0%,
      line to 100% 0%,
      line to 100% min(80%, 18rem),
      line to min(60%, 20rem) min(80%, 18rem),
      line to min(50%, 17rem) 100%,
      line to min(40%, 14rem) min(80%, 18rem),
      line to 0% min(80%, 18rem),
      close
    );
  }
}

Gracias a este código, todos los usuarios pueden visitar tu sitio sin ningún problema de visualización.

Lo que hay que recordar

La función shape() cambia nuestra forma de programar sitios web.

Aquí tienes sus 3 grandes ventajas:

  • Es fluida: la forma se adapta al tamaño de la pantalla sin código adicional.
  • Es rápida: el navegador dibuja la forma directamente. Tu sitio se muestra más rápido.
  • Es moderna: combinada con el espacio de color OKLCH, te ayuda a crear diseños más limpios y más accesibles.

Intenta utilizar la función shape() en tu próximo proyecto para crear interfaces únicas y ligeras.


Preguntas Frecuentes (FAQ)

¿Cuál es la diferencia principal entre path() y shape()? El comando path() utiliza únicamente píxeles. La forma no puede cambiar de tamaño. La función shape() utiliza porcentajes. La forma se adapta automáticamente al tamaño de tu pantalla.
¿Se pueden mezclar varias unidades de medida en shape()? Sí. Es una de las grandes ventajas de la función shape(). Puedes mezclar porcentajes (como 50%), píxeles (como 20px) y medidas relativas (como 3rem) dentro del mismo dibujo.
¿Se puede mover un objeto a lo largo de una forma shape()? Sí. Puedes dibujar una línea invisible con la función shape(). Un objeto de tu página puede deslizarse después a lo largo de esa línea para crear una animación.
¿Se puede usar shape() para obligar al texto a rodear una forma? Sí. Puedes utilizar la función shape() de dos maneras: 1. Para recortar un elemento de tu página con clip-path. 2. Para obligar a un texto a rodear el elemento con shape-outside.
Lionel Péramo
Lionel Péramo
Experto en Rendimiento Web y Ecodiseño

Desarrollador Full Stack y creador del framework OTRA (PHP) y de la librería EcoComposer. Escribo para hacer la web más rápida e inclusiva.

Sobre mí →