domingo, 18 de septiembre de 2022

👨‍💻 Sobre la propiedad Clip path:. Cómo crear diseños asombrosos con esta propiedad (1)

Hace algún tiempo, existió una propiedad CSS llamada clip, cuya intención era permitir recortes con ciertas formas como rectángulos. Sin embargo, hoy en día ha sido marcada como obsoleta, en favor de una nueva propiedad llamada clip-path.

En este artículo vamos a hablar sobre la propiedad clip path, aprenderás técnicas modernas de CSS para crear diseños y efectos vanguardistas.

Desde los inicios nos han acostumbrado a que todo debe ser rectangular, no me malentiendan. Los rectángulos están bien, no tengo nada contra ellos, de hecho son de gran utilidad al momento de definir la estructura del sitio.

Solo creo que para hacer diseños que te destaquen de la competencia, a veces es necesario salir de los esquemas y apostar por algo nuevo.

Antes de esta propiedad, si querías cambiar la forma de alguna sección de tu web, tenías que hacer malabares con los pseudo elementos before y/o after, posiciones absolutas, usar imágenes…

Ya no tiene por qué ser así, clip path nos facilita la vida al momento de crear figuras o efectos que llaman la atención.

¿Cómo funciona la propiedad clip path?

La propiedad clip-path recorta o “delimita” con una forma concreta a una porción de elementos SVG, imágenes o cualquier elemento HTML, ocultando toda la región externa del recorte. Esta propiedad viene a sustituir la obsoleta clip: clip: rect() , de CSS2.

Su utilización es muy sencilla y permite realizar formas muy flexibles y versátiles.

El trazado de recorte o clipping path se define por medio de patrones, formas o polígonos.

Este trazo de recorte es una región donde todo lo que está “dentro” de esta zona es visible y todo lo que está “fuera” de esta zona no se dibuja.


El patrón de recorte (centro) se aplica a la figura con diferentes colores (izquierda). Esto da como resultado una figura recortada (derecha).

Sintaxis

La forma correcta de escribir esta propiedad es la siguiente:

Propiedad Valor Descripción
clip-path none | | url(file.svg#name) Efectua un recorte con una forma concreta.

La propiedad clip-path en general puede tomar 3 tipos de valores: none, el valor por defecto, donde no utilizamos ningún tipo de recorte (o lo desactivamos si lo había), un valor , es decir, una forma básica específica de las que veremos a continuación, o usar url(), donde indicamos una imagen SVG para utilizar un recorte personalizado usado en su interior mediante <clipPath>.

clip-path: <clip-source> | [ <basic_shape> || <geometry_box> ] | none

<clip-source>: La URL que haga referencia a un elemento SVG <clipPath> interno o externo.

clip-path: url(resources.svg#blob);

<basic shape>: Acepta las formas definidas en la especificación de formas de CSS. Una forma básica utiliza el cuadro de referencia especificado para dimensionar y colocar la forma básica. Si no se especifica ningún cuadro de referencia, el cuadro de borde (border-box) se utilizará como cuadro de referencia.

Formas básicas de recorte

Las formas básicas de recorte son diferentes palabras clave que permiten realizar un tipo de recorte particular, donde en cada una de ella le podemos pasar parámetros para definir sus coordenadas.

Dentro de los valores podemos utilizar cualquiera de los siguientes:

Valores Descripción
inset(top right bottom left) Recorta en forma rectangular hacia dentro.
inset(top right bottom left round radius) Idem al anterior, con bordes redondeados, tamaño radius.
circle(size at x y) Recorta en forma circular con un tamaño size con centro en x,y.
ellipse(sx sy at x y) Idem al anterior, pero diferenciando tamaño de ancho sx y de alto sy.
polygon(x y, x y, ...) Recorta un polígono siguiendo las coordenadas establecidas.
path(coords) Recorta siguiendo los datos de un trayecto SVG.

Las formas que acepta son las siguientes: inset(), circle(), ellipse(), polygon() y path():

clip-path: inset(100px 50px);
clip-path: circle(50px at 0 100px);
clip-path: ellipse(50px 60px at 0 10% 20%);
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
clip-path: path('M0.5,1 C0.5,1,0,0.7,0,0.3 A0.25,0.25,1,1,1,0.5,0.3 A0.25,0.25,1,1,1,1,0.3 C1,0.7,0.5,1,0.5,1 Z');

<geometry-box>: Si se usa en combinación con <basic-shape>, proporciona el box de referencia para <basic-shape>. Si se especifica por sí mismo, utiliza los bordes del cuadro especificado, incluida cualquier forma de esquina (border-radius), como ruta de recorte. Geometry-box puede tener uno de los siguientes valores:

  • margin-box: utiliza el margin box como el cuadro de referencia.
  • border-box: utiliza el border box como cuadro de referencia.
  • padding-box: utiliza el padding box como cuadro de referencia.
  • content-box: utiliza el content box como cuadro de referencia.
  • fill-box: utiliza el cuadro delimitador del objeto como cuadro de referencia.
  • stroke-box: Utiliza el cuadro delimitador de trazo como cuadro de referencia.
  • view-box: Utiliza el viewport SVG más cercano como cuadro de referencia.
  • none: No se crea ningún trazado de recorte.
 clip-path: margin-box;
clip-path: border-box;
clip-path: padding-box;
clip-path: content-box;
clip-path: fill-box;
clip-path: stroke-box;
clip-path: view-box;

En este ejemplo, el círculo usaría el content-box como cuadro de referencia.


.caja {
  clip-path: circle(50%) content-box;
}

Actualmente, los navegadores no admiten el uso de valores de cuadro para la propiedad clip-path. Sin embargo, son compatibles con shape-outside.

Ahora, veamos la función polygon(), que se ve así:

img {
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

Le estamos diciendo que todas las imágenes serán recortadas en forma de triángulo equilatero, la forma se la damos por medio de los vértices (x, y), la siguiente imagen lo ilustra mejor:

vertices en clip path

La primera coordenada determina la posición en el eje x, la segunda especifica la posición en el eje y. Los puntos están trazados en sentido de las manecillas del reloj.

Nota: no sucede así en el caso que el polígono tenga 3 pares de valores, como es el caso del triángulo de la imagen.

El primer valor se localiza a la mitad del eje x, por lo que su coordenada es 50%, para el eje y tiene un valor de 0%.

vertices en clip path

Pero ahora veamos detalladamente, cómo funcionan cada una de estas funciones de formas básicas.

Usando las formas básicas

Como mencionamos arriba clip path acepta las formas: inset(), circle(), ellipse(), polygon().

Circle

En el caso de los recortes circle(), vamos a establecer un recorte circular en una porción del elemento, pudiendo recortar formas como círculos, medias lunas, etc...

La función circle() se define con la siguiente sintaxis: circle(radio en posX posY). La posición es opcional y está predeterminada en 50% 50%.

.circulo1 {
  clip-path: circle(50%);
}
.circulo2 {
  clip-path: circle(70% at 70% 20%);
}
la propiedad Clip path:

Veamos el siguiente caso:

<div class="box"></div>

<style>
.box {
background: hotpink;
width: 200px;
height: 200px;
clip-path: circle(50% at 50% 0);
}
</style>

Así pues, en este caso, observa que indicamos circle(50% at 50% 0). El primer parámetro indica el tamaño del recorte en forma de círculo (50%), y las coordenadas después de at es el punto central del círculo: 50% en x y 0% en y. Quedaría algo así:

Clip-path CSS usando circle

Recorte usando Ellipse

En el caso del ellipse() es exactamente igual que el de circle() sólo que en el primero podemos establecer un ancho y alto al elipse y en el segundo sólo podemos establecer un tamaño de ancho y alto (que será siempre el mismo).

La función ellipse() se define de la siguiente forma: ellipse(radioX radioY at posX posY). La posición es opcional y está predeterminada en 50% 50%.

.ellipse1 {
  clip-path: ellipse(50% 35%);
}
.ellipse2 {
  clip-path: ellipse(50% 65% at 70% 50%);
}

Como ya hemos comentado, la diferencia respecto a ellipse() es que en el tamaño de la elipse le podemos indicar el tamaño de ancho y de alto, mientras que en el círculo este valor es el mismo en ambos y sólo se indica uno:

<div class="box"></div>

<style>
.box {
background: hotpink;
width: 200px;
height: 200px;
clip-path: ellipse(50% 25% at 50% 0);
}
</style>

Recorte usando Inset

En el caso de los recortes con la función inset(), estamos estableciendo un cuadrado o rectángulo, donde cada parámetro (top, right, bottom, left) indicará un porcentaje que representa la distancia desde su punto concreto.

Todo lo que quede fuera de esa área, desaparece. Además, también es posible redondear las esquinas con la palabra border radius:

.inset1 {
  clip-path: inset(20% 25% 20% 10%);
}
.inset2 {
  clip-path: inset(45% 0 33% 10% round 10px);
}
<div class="box"></div>

<style>
.box {
background: hotpink;
width: 200px;
height: 200px;
clip-path: inset(0 0 50% 50%);
}
</style>

Así pues, inset(0% 0% 50% 50%) parte desde el 0% de la parte superior, desde el 0% de la parte derecha, desde la mitad (50%) de la parte inferior y desde la mitad (50%) de la parte izquierda:

Clip-path CSS usando inset

También es posible redondear los bordes del cuadrado o rectángulo, indicando al final la palabra clave round junto al radio de borde que quieres especificar. Por ejemplo:

.box {
background: hotpink;
width: 200px;
height: 200px;
clip-path: inset(50px round 20px);
}

Observa que en este caso, hemos establecido sólo un valor para los parámetros, es decir, equivalente a inset(50px 50px 50px 50px), pero además incluimos round 20px, por lo que va a establecer un border-radius de 20px en cada esquina, es decir, algo similar a border-radius: 20px 20px 20px 20px.

Recorte usando polygon

Probablemente, el tipo de recorte básico más potente y versátil sea el recorte poligonal utilizando polygon().

Con esta forma puedes crear una gran variedad de figuras, al ser un polígono puedes especificar cualquier cantidad de puntos. Se requieren al menos tres vértices para definir un polígono. Acepta pares de coordenadas en X y Y, lo valores que pueden tomar son: píxeles, porcentajes, ems, rems, etc.

Su funcionamiento es muy sencillo, pero a la vez muy flexible, simplemente hay que indicar los puntos de corte deseados e iremos realizando el recorte:

.triangle {
  clip-path: polygon(50% 0, 0 100%, 100% 100%);
}
.right-arrow {
  clip-path: polygon(0% 20%, 60% 20%, 60% 0%, 100% 50%, 60% 100%, 60% 80%, 0% 80%);
}
.octagon {
  clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
}
.close {
  clip-path: polygon(20% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%);
}

Un ejemplo:

<div class="box"></div>

<style>
.box {
background: hotpink;
width: 200px;
height: 200px;
clip-path: polygon(0 0, 100% 0, 50% 100%);
}
</style>

En este ejemplo, polygon() tiene 3 puntos de corte separados por comas (cada uno con sus coordenadas en X e Y), formando un triángulo, pero se pueden indicar tantos puntos de corte como se quiera (incluso con valores negativos o superiores a 100%).

Clip-path CSS usando polygon

Aunque es posible utilizar otras unidades, lo más habitual suele ser establecer las coordenadas con porcentajes, ya que resulta muchísimo más sencillo y claro, siendo también mucho más escalable y mantenible si el elemento padre cambia sus dimensiones.

See the Pen
Clip path
by Plectro lab (@Plectro-lab)
on CodePen.

Recorte usando path

Si buscamos algo un poco más flexible y potente, necesitamos el recorte utilizando la función path(). Con ella, podemos definir un trayecto SVG para aplicar como recorte, consiguiendo formas mucho más complejas, imposibles (o muy difíciles) de conseguir con sólo HTML/CSS.

En los parámetros de path() se pasa un que es una serie de coordenadas de un trayecto SVG, o lo que es lo mismo, el atributo d (data) de un elemento <path> de SVG.

<div class="box"></div>

<style>
.box {
width: 300px;
height: 300px;
background: url("https://gudh.github.io/ihover/dist/images/assets/rect/1.jpg") center / cover;
clip-path: path("m4,87l93,0l29,-84l29,84l93,0l-76,52l29,84l-76,-52l-76,52l29,-84l-76,-52z");
}
</style>

En este caso, hemos definido una estrella a través de una serie de coordenadas de un trayecto SVG.

Usando con un elemento SVG

Además de recortar con las figuras básicas, puedes hacer uso de un vector SVG para hacer los recortes.

<svg width="0" height="0">
  <defs>
    <clipPath id="blob">
      <polygon points="15,99 30,87 65,99 85,55 122,57 184,73 198,105
      199,150 145,159 155,139 126,120 112,138 80,128 39,126
      24,104"/>
    </clipPath>
  </defs>
</svg>

Trabaja con las mismas propiedades que usamos en CSS, cada par de coordenadas separadas por comas representa un punto del polígono.

Ahora puedes aplicar la forma definida en la función url(), usando el id definido en el elemento <clipPath>:

.clipped {
  clip-path: url(#blob);
}

See the Pen
Clip path SVG
by Plectro lab (@Plectro-lab)
on CodePen.

Animaciones y transiciones

Las animaciones y transiciones también se pueden aplicar con clip-path para crear efectos interesantes. Solo asegúrate de que todos los pasos de tu animación contengan la misma cantidad de pares de puntos.

See the Pen
Clip path animation
by Plectro lab (@Plectro-lab)
on CodePen.

Soporte en navegadores en 2021

Al momento de escribir estas líneas, la propiedad clip path tiene un excelente soporte para navegadores.

Sí deseas ofrecer soporte a navegadores antiguos, una alternativa puede ser permitir que el navegador ignore la propiedad clip-path y muestre la imagen sin recortar. Otra alternativa, puedes probar la propiedad con @supports de css y ofrecer un diseño alternativo para los navegadores que no son compatibles.

@supports(clip-path: circle(45%)) {
  /* soporte para clip-path */
}

Al principio el trabajar con la propiedad clip path puede ser intimidante, pero una vez ubicas la forma en que opera con elementos SVG y conoces el sentido de los pares de valores para la función polygon(), verás que es muy sencillo. Echa a valor la imaginación y atrévete a crear diseños únicos.

Para más información:

Clip path Nota:
Si quieres conocer y ejercitarte en diferentes modelos, para estudiar cuál (o cuáles) vienen mejor a tus proyectos, consulta la siguiente ----> publicación.





Fuentes


https://plectrolab.com/clip-path/



https://lenguajecss.com/