CSS Shapes

Durante mucho tiempo, los diseñadores web se han visto obligados a crear contenido dentro de las limitaciones de un rectángulo. La mayoría del contenido de la web sigue atrapado en cajas simples, porque la mayoría de las empresas que se involucran con un diseño no rectangular terminan en frustración.

Eso ya no es un problema, gracias a CSS Shapes (disponible a partir de Chrome 37).

Las formas en CSS permiten a los diseñadores web envolver contenido en torno a rutas personalizadas, como círculos, elipses y polígonos, rompiendo así con las limitaciones del rectángulo.
Las formas se pueden definir manualmente o se pueden deducir de imágenes.

Ejemplo: shape-outside

En muchas ocasiones sucede que al flotar por primera vez una imagen con partes transparentes, esperamos que el contenido se envuelva y rellene las partes sin opacidad, sólo para ser decepcionados por la forma de envoltura rectangular que persiste alrededor del elemento. Las formas CSS se pueden utilizar para resolver este problema.

<img class=”element” src=”image.png” />
<p>Expresso is…</p>

<style>
img.element{
  shape-outside: url(image.png);
  shape-image-threshold: 0.5;
  float: left;
}
</style>

La declaración CSS: shape-outside: url(image.png) le dice al navegador que extraiga una forma de la imagen.

La propiedad: shape-image-threshold define el nivel de opacidad mínimo de píxeles que se utilizará para crear la forma. Su valor debe estar en el rango entre 0.0 (completamente transparente) y 1.0 (completamente opaco). Por lo tanto, shape-image-threshold: 0.5 significa que sólo los píxeles con opacidad de 50% y superior se utilizarán para crear la forma.

La propiedad float es clave aquí. Mientras que la propiedad shape-outside define la forma del área alrededor de la cual se envolverá el contenido, sin float, no se verán los efectos de la forma.
Los elementos tienen un área de flotación en el lado opuesto de su valor de flotación. Por ejemplo, si un elemento con una imagen de taza de café se está flotando a la izquierda, el área de flotación se creará a la derecha de la copa. A pesar de que se puede diseñar una imagen con espacios en ambos lados, el contenido sólo se envolverá alrededor de la forma en el lado opuesto designado por la propiedad flotante, es decir: a la izquierda o la derecha, nunca en ambos.

 

Creando formas manualmente

Además de extraer formas desde imágenes, también se pueden crear manualmente. Podemos elegir entre algunos valores funcionales para crear formas: circle (), ellipse (), polygon (), etc.
Cada función de forma acepta un conjunto de coordenadas y se empareja con un cuadro de referencia que establece un sistema de coordenadas.

Función: circle()

La notación completa para un valor de forma de círculo es: circle(r at cx cy) donde r es el radio del círculo, mientras que cx y cy son coordenadas del centro del círculo en el eje X y el eje Y. Las coordenadas para el centro del círculo son opcionales. Si se omite, el centro del elemento (la intersección de sus diagonales) se utilizará como valor predeterminado.

img.element{
  shape-outside: circle(50%);
  width: 300px;
  height: 300px;
  float: left;
}

En este caso, el contenido se envuelve alrededor del exterior de una trayectoria circular. El argumento 50% especifica el radio del círculo, que, en este caso específico, equivale a la mitad del ancho o la altura del elemento. Cambiar las dimensiones del elemento influirá en el radio de la forma del círculo. Este es un ejemplo básico de cómo las formas CSS trabajan de forma responsiva.

Cuando se utilizan porcentajes para el radio del círculo, el valor se calcula como: sqrt (width ^ 2 + height ^ 2) / sqrt (2). Es útil entender esto porque podemos imaginar cuál será la forma del círculo resultante si las dimensiones del elemento no son iguales.

Todos los tipos de unidades CSS se pueden utilizar en coordenadas de función de forma: px, em, rem, vw, vh, etc.

También se puede ajustar la posición del círculo estableciendo valores explícitos para las coordenadas del centro:

img.element{
  shape-outside: circle(50% at 0 0);
}

Esto posiciona el centro del círculo en el origen del sistema de coordenadas.

 

Función: ellipse()

Podemos pensar en las elipses como círculos aplastados. Se definen como: ellipse (rx ry at cx cy) donde rx y ry son los radios para la elipse en el eje X y el eje Y, mientras que cx y cy son las coordenadas para el centro de la elipse.

.element{
  shape-outside: ellipse(150px 300px at 50% 50%);
  width: 300px;
  height: 300px;
  float: left;
}

Los valores porcentuales se calcularán a partir de las dimensiones del sistema de coordenadas. Nuevamente se pueden omitir las coordenadas para el centro de la elipse y se deducirán del centro del sistema de coordenadas.

 

Función: polygon()

Si los círculos y las elipses son demasiado limitantes, la función de forma de polígono abre un mundo de opciones. El formato es polygon (x1 y1, x2 y2, …) donde se especifican pares de coordenadas x e y para cada vértice (punto) de un polígono. El número mínimo de pares para especificar un polígono es tres, un triángulo.

img.element{
  shape-outside: polygon(0 0, 0 300px, 300px 300px);
  width: 300px;
  height: 300px;
  float: left;
}

Los vértices se colocan en el sistema de coordenadas. Para polígonos responsivos, se pueden utilizar valores porcentuales para  las coordenadas, es decir:

img.element{
  /* polygon responsive to font-size*/
  shape-outside: polygon(0 0, 0 100%, 100% 100%);
  width: 20em;
  height: 20em;
}

 

Animando formas

Se puede mezclar formas de CSS con muchas otras funciones de CSS, como transiciones y animaciones. Sin embargo, en ocasiones los usuarios encuentran molesto un diseño de texto que cambia mientras están leyendo. Por eso debemos prestar mucha atención a la user-experience si se decide animar las formas.

Se pueden por ejemplo animar los radios y centros de las formas circle () y ellipse () siempre y cuando se definan en valores que el navegador puede interpolar.
Ir de un círculo (30%) a un círculo (50%) es posible. Sin embargo, la animación entre el círculo (lado más cercano) y el círculo (más alejado) obstruirá el navegador.

img.element{
  shape-outside: circle(30%);
  transition: shape-outside 1s;
  float: left;
}

img.element:hover{
  shape-outside: circle(50%);
}

Se pueden conseguir efectos más interesantes cuando se animan las formas de un polígono, con la importante observación de que el polígono debe tener el mismo número de vértices entre los dos estados de animación. El navegador no puede interpolar si agregamos o quitamos vértices.

Un truco es agregar la cantidad máxima de vértices que se necesitan y colocarlos agrupados en el estado de animación en el que desea menos bordes percibidos a la forma.

img.element{
  /* four vertices (looks like rectangle) */
  shape-outside: polygon(0 0, 100% 0, 100% 100%, 0 100%);
  transition: shape-outside 1s;
}

img.element:hover{
  /* four vertices, but second and third overlap (looks like triangle) */
  shape-outside: polygon(0 0, 100% 50%, 100% 50%, 0 100%);
}

 

Herramientas para trabajar con CSS Shapes

CSS Shapes Editor extension for Brackets

CSS Shapes Editor extension for Google Chrome

Polyfill

Conclusión

En una web en la que el contenido se encuentra principalmente atrapado en cajas simples, las formas de CSS proporcionan una nueva alternativa para crear un diseño expresivo, superando la brecha de fidelidad entre el diseño web y el diseño impreso.
Por supuesto que las formas pueden ser abusadas y con ello crear distracciones. Por eso, deben ser aplicadas con gusto y buen juicio, de esta manera las formas pueden mejorar la presentación del contenido y enfocar la atención del usuario de una manera visualmente más interesante.