sábado, 29 de octubre de 2022

Cómo crear una cinta solo CSS para su sitio web

ribbon

¿Alguna vez ha notado esas elegantes cintas en los sitios web que alertan a los usuarios sobre alguna función o evento especial? Es genial tenerlos, pero para muchos desarrolladores es una pesadilla crearlos.

Puede encontrar fácilmente una gran cantidad de código listo para usar para dicho componente, pero no son fáciles de actualizar. También tiene que lidiar con muchas pruebas y errores hasta que logre que funcionen correctamente.

En esta publicación, le mostraré cómo crear dos tipos de cintas con un código CSS simple donde no necesita molestarse con ajustar muchos valores.

Esto es lo que crearemos en este artículo:

ribbon

Cinta girada y cinta doblada

A continuación se muestra el código completo de ambas cintas para que pueda ver lo simple que es:

Below is the full code for both ribbons so you can see how simple it is:

Click para ver el código completo
 

<div class="box">
    <div class="ribbon-2">Folded Ribbon</div>
  </div>
  <div class="ribbon-1 left">Rotated Ribbon</div>
  <div class="ribbon-1 right">Rotated Ribbon</div>
 
.ribbon-1 {
    position: fixed;
    background: #08769b;
    box-shadow: 0 0 0 999px #08769b;
    clip-path: inset(0 -100%);
  }
  .left {
    inset: 0 auto auto 0;
    transform-origin: 100% 0;
    transform: translate(-29.3%) rotate(-45deg);
  }
  .right {
    inset: 0 0 auto auto;
    transform-origin: 0 0;
    transform: translate(29.3%) rotate(45deg);
  }

  .ribbon-2 {
    --f: 10px; /* control the folded part*/
    --r: 15px; /* control the ribbon shape */
    --t: 10px; /* the top offset */

    position: absolute;
    inset: var(--t) calc(-1*var(--f)) auto auto;
    padding: 0 10px var(--f) calc(10px + var(--r));
    clip-path: 
      polygon(0 0,100% 0,100% calc(100% - var(--f)),calc(100% - var(--f)) 100%,
        calc(100% - var(--f)) calc(100% - var(--f)),0 calc(100% - var(--f)),
        var(--r) calc(50% - var(--f)/2));
    background: #BD1550;
    box-shadow: 0 calc(-1*var(--f)) 0 inset #0005;
  }


  .box {
    max-width:500px;
    height:200px;
    margin:50px auto 0;
    background:lightblue;
    position:relative;
  }

Cómo crear una cinta rotada con CSS

Este tipo de cinta se utiliza, en la mayoría de los casos, para colocar una pieza de información fija en la parte superior de la pantalla. Pero también podemos usarlo dentro de un elemento dentro de la página.

Para comprender cómo crear una cinta de este tipo, veamos una ilustración paso a paso:

ribbon

Ilustración paso a paso de la cinta girada

Primero, comenzamos colocando nuestro elemento en la esquina superior izquierda de la pantalla. Los bordes rojos en la ilustración son los límites de la pantalla (o el elemento donde desea colocar la cinta).

  
 .ribbon {
  position: fixed;
  inset: 0 auto auto 0;
  background: #08769b;
} 

Nada complejo hasta ahora. Si no está familiarizado con la propiedad inset, no es más que la forma abreviada de top, right, bottom y left.

A continuación, realizamos una traducción a la izquierda usando translate(-29.3%).

Después de la traducción, rotamos nuestro elemento usando rotate(-45deg) y el código se convierte en este:

 

  .ribbon {
  position: fixed;
  inset: 0 auto auto 0;
  background: #08769b;
  transform-origin: 100% 0; /* or top left */
  transform: translate(-29.3%) rotate(-45deg);
}
 

Probablemente te estés preguntando cuál es el secreto del valor extraño 29.3%. Bueno, es igual a 100% * (1 - cos(45deg)).

Evitaré comenzar una explicación matemática "aburrida", pero puede ver que después de que hicimos la rotación, el elemento está perfectamente colocado (sus dos esquinas superiores tocan los bordes). La traducción es la clave para tener esa ubicación perfecta.

También puede notar el uso de transform-origin: top left. En el tercer paso, tuve que rotar el elemento desde su esquina superior izquierda.

Ahora nuestro elemento está colocado correctamente, pero tenemos algunos espacios que llenar. Usaré un "grande" box-shadow para hacer eso. En la figura, utilicé un color verde para ilustrar, pero debes considerarlo como el mismo color que el fondo.

A continuación, debemos recortar la sombra para mostrar solo las partes izquierda y derecha. Para hacer esto estaré usando clip-path. Usaré lo inset(0 -100%) que significa recortar la sombra superior e inferior (el valor 0) y mostrar algo de la sombra izquierda derecha (-100% ).

100% es un valor aleatorio que necesita ser muy grande. Puede ser, por ejemplo , 999px o 100vmax cualquier valor para asegurarnos de mantener la parte izquierda y derecha de la sombra.

Ahora veremos el resultado final en el sexto paso. Todavía tenemos algunas sombras desbordantes pero nadie puede verlas ya que estamos colocando nuestro elemento en la esquina de la pantalla.

Si va a colocar la cinta dentro de otro elemento, no olvide usarla overflow: hidden en el elemento principal y también reemplazarla fixed con absolute

Nuestro código final será:

 
  
  .ribbon-1 {
  position: fixed;
  inset: 0 auto auto 0;
  background: #08769b;
  transform-origin: 100% 0;
  transform: translate(-29.3%) rotate(-45deg);
  box-shadow: 0 0 0 999px #08769b;
  clip-path: inset(0 -100%);
}
  
  

Con solo 7 declaraciones tenemos nuestra cinta girada. Notará que nuestro código es genérico y no depende del contenido del texto. Sea cual sea el contenido de la cinta, siempre se colocará correctamente. Incluso puede tener varias líneas de texto.

Para colocar la cinta en la esquina superior derecha, solo necesitamos actualizar algunos valores. Aún mejor, tengamos dos clases para controlar fácilmente la ubicación:

 

.ribbon-1 {
  position: fixed;
  background: #08769b;
  box-shadow: 0 0 0 999px #08769b;
  clip-path: inset(0 -100%);
}
.left {
  inset: 0 auto auto 0; /* top and left equal to 0 */
  transform-origin: 100% 0; /* OR top right */
  transform: translate(-29.3%) rotate(-45deg);
}
.right {
  inset: 0 0 auto auto; /* top and right equal to 0 */
  transform-origin: 0 0; /* OR top left */
  transform: translate(29.3%) rotate(45deg);
} 
   

Creo que el código se explica por sí mismo y los cambios entre derecha e izquierda son fáciles de entender.

Cómo crear una cinta doblada con CSS

Abordemos el segundo tipo de listón de la misma manera que lo hicimos con el anterior usando una ilustración paso a paso.

ribbon

Ilustración paso a paso de la cinta plegada

Primero, comenzaremos colocando nuestro elemento en el lado derecho del elemento principal.

 

 .ribbon-2 {
  --t: 10px; /* the top offset */
  
  position: absolute;
  inset: var(--t) 0 auto auto;
  padding:0 10px;
  background: #BD1550;
  
} 
  

Consideraré una variable para controlar el desplazamiento desde la parte superior, lo que significa que podemos controlar fácilmente la posición de la cinta ajustando esa variable. Ya que estamos usando position: absolute, no debemos olvidar agregar position: relative al elemento principal de la cinta.

También agregaré algo de relleno en los lados izquierdo y derecho. No hay una lógica particular detrás de 10px: puede elegir el valor que desee.

Ahora introduciré otra variable que controlará la parte plegada. Usaré esta variable para definir una sombra insertada box-shadow: 0 calc(-1*var(--f)) 0 #0005.

Como puede ver en la figura de arriba, esta sombra agregará una superposición negra semitransparente en la parte inferior que tiene una altura igual a la variable --f. También aumentaré el relleno inferior para contener esa sombra padding: 0 10px var(--f).

Luego, usando la misma variable --f, moveré la cinta un poco hacia la derecha reemplazándola right:0 con right: calc(-1*var(--f)).

El código hasta ahora se ve así:

 

  .ribbon-2 {
  --t: 10px; /* the top offset */
  --f :10px /* control the folded part */
  
  position: absolute;
  inset: var(--t) calc(-1*var(--f)) auto auto; /* the right value is here*/
  padding:0 10px var(--f);
  background: #BD1550;
  box-shadow: 0 calc(-1*var(--f)) 0 inset #0005; 

  }
  

El código puede parecer extraño (y el resultado también), pero todo tendrá sentido en el siguiente paso cuando creemos la forma final.

En el cuarto paso (el último), nos introduciremos clip-path para cortar nuestro elemento. También agregaré otra variable --r para controlar la forma de flecha de la cinta.

Antes de agregar la ruta de recorte, primero aumentaré el relleno izquierdo para tener el espacio necesario para la forma de flecha:

  
  
  padding: 0 10px var(--f) calc(10px + var(--r));
  
  
  • El relleno superior es igual a 0.
  • El relleno derecho es igual a 10px (un valor aleatorio)
  • El relleno inferior está definido por --f
  • El relleno izquierdo es igual a 10px(igual que el derecho) más un valor definido por la nueva variable --r

Ahora agreguemos el clip-path. Aquí hay una ilustración para entender el camino que nos llevará a la forma final.

ribbon

Ilustración del clip-path

La ruta se define mediante 7 puntos. Empezando por el punto (1) y siguiendo la flecha tenemos el siguiente código:

  
  
 clip-path: polygon(
  0 0,  /* (1) */
  100% 0, /* (2) */
  100% calc(100% - var(--f)), /* (3) */
  calc(100% - var(--f)) 100%, /* (4) */
  calc(100% - var(--f)) calc(100% - var(--f)), /* (5) */
  0 calc(100% - var(--f)), /* (6) */
  var(--r) calc(50% - var(--f)/2) /* (7) */
 }
  
    

No se preocupe si no está familiarizado clip-path, esto puede parecerle un poco extraño. No es necesario manipular ese camino. Todo lo que necesita para actualizar las variables CSS para controlar la forma general.

Dicho esto, es bueno jugar con ese camino cambiando algunos valores para comprender mejor cómo funciona.

Hemos terminado. Nuestro código final es:

 
  
  .ribbon-2 {
  --f: 10px; /* control the folded part*/
  --r: 15px; /* control the ribbon shape */
  --t: 10px; /* the top offset */
  
  position: absolute;
  inset: var(--t) calc(-1*var(--f)) auto auto;
  padding: 0 10px var(--f) calc(10px + var(--r));
  clip-path: 
    polygon(0 0,100% 0,100% calc(100% - var(--f)),calc(100% - var(--f)) 100%,
      calc(100% - var(--f)) calc(100% - var(--f)),0 calc(100% - var(--f)),
      var(--r) calc(50% - var(--f)/2));
  background: #BD1550;
  box-shadow: 0 calc(-1*var(--f)) 0 inset #0005;
}
  

Puede ajustar los valores de las variables para obtener diferentes resultados:

ribbon

Como hicimos con la cinta girada, podemos actualizar algunos valores para cambiar la posición de este de derecha a izquierda, pero esta vez no le daré el código. Dejaré que intentes encontrarlo solo 😉

Es un buen ejercicio averiguar qué valor debe actualizar, especialmente para el archivo clip-path.

Terminando

Ahora ya sabe cómo crear hermosas cintas para sus sitios web usando solo CSS.

Acá otro artículo sobre la creación de cintas si deseas una continuación de este. Allí se detalla cómo crear una cinta girada y doblada, una especie de combinación de lo que aprendimos aquí.

Además puedes también revisar:

Cómo hacer un ribbon destacado usando solo CSS y el pseudoelemento ::before

¡Gracias por leer!



Fuente original de este artículo:

https://www.freecodecamp.org (inglés)

Para complementr este artículo:

https://www.smashingmagazine.com/



¡¡Aprender es interesante y divertido!!


Salu2 y bendiciones,
Atte, Angel Paz
Duda con el Efecto rayo 71pkhu