Esquinas recortadas en 2018

Índice
  1. La idea inicial: box-shadow!
  2. Aplicando esta técnica
  3. La corner-shapeopción

Cuando vi el artículo de Chris sobre cajas con muescas, recordé que hace un tiempo recibí un desafío para usar CSS en un diseño como el siguiente en varios navegadores:

Se parece bastante al concepto de cajas con muescas, excepto que las esquinas ahora están recortadas y solo tenemos que preocuparnos de una esquina por caja. Entonces, veamos cómo podemos hacerlo, cómo podemos expandir la técnica a múltiples rincones, qué problemas encontramos y cómo podemos solucionarlos con o sin comprometer el soporte del navegador.

La idea inicial: box-shadow!

Comenzamos con un elemento de caja:

pseudoelemento cuadrado cuya longitud de borde es igual al diámetro (o el doble del radio $r) de la pala en la esquina. También le damos a este pseudoelemento un color rojizo box-shadowy una ficción background(que eliminaremos más adelante) solo para que podamos verlo mejor:

*/ :before { position: absolute; padding: $r; box-shadow: 0 0 7px #b53; background: #95a; content: '' }}

Y esto es lo que tenemos hasta ahora:

Bueno, no parece demasiado emocionante… ¡todavía! Así que sigamos adelante y hagamos de este cuadrado un disco configurándolo border-radius: 50%y dándole un negativo marginigual a su radio $r, de modo que su punto central coincida con el (0,0)punto (esquina superior izquierda) de su cuadro principal. También configuramos overflow: hiddenel cuadro principal, de modo que se corte todo lo que esté fuera de este pseudoelemento .box.

*/ :before { /* same styles as before */ margin: -$r; border-radius: 50% }}

Ahora estamos empezando a ver la forma que buscábamos:

Pero todavía no es exactamente lo que queremos. Para llegar allí, utilizamos el cuarto valor de longitud de la box-shadowpropiedad: el radio de extensión . Si necesitas un repaso sobre cómo box-shadowfunciona con estos cuatro valores, puedes consultar la demostración interactiva a continuación:

Quizás ya hayas adivinado lo que hacemos a continuación. Eliminamos la ficticio background, ponemos a cero los primeros tres box-shadowvalores (los desplazamientos x e y y la radio de desenfoque) y usamos un número bastante grande para el último (el radio de extensión):

*/ border-radius: 1em; :before { /* same styles as before */ box-shadow: 0 0 0 300px rgba(#95a, .75); }}

Por supuesto, tal como Chris señaló en el artículo sobre cajas con muescas, podemos hacer que el radio de la muesca sea una variable CSS y luego modificarla fácilmente desde JavaScript. Luego, todo se actualiza correctamente, incluso con contenido de texto en nuestra caja:

*/ padding: var(--r); :before { /* same styles as before */ margin: calc(-1*var(--r)); padding: inherit;}

Tenga en cuenta que cuando también tenemos contenido de texto, debemos establecer un negativo z-indexen el ::beforepseudoelemento y colocarlo explícitamente en la esquina, ya que ahora también tenemos un paddingpara .boxcompensar la primicia.

*/ :before { /* same styles as before */ z-index: -1; top: 0; left: 0}

Aplicando esta técnica

Ahora, avancemos un poco más y veamos cómo podemos aplicar este concepto para reproducir el diseño que mostré al principio. En este caso particular, los puntos centrales de los pseudo-discos de los elementos no coinciden con las esquinas de las cajas, sino que están afuera, en el medio del espacio entre las cajas.

La estructura utilizada es bastante sencilla, solo un headerelemento seguido de cuatro articleelementos que generé en un bucle Pug:

{ /* set generic offsets */ top: calc((1 + var(--j))*50% - var(--r) + var(--j)*#{$m}); left: calc((1 + var(--i))*50% - var(--r) + var(--i)*#{$m}); }}@media (min-width: 2*($min-w + 2*$m)) { article { /* change vertical multiplier for first two (on 1st row of 2x2 grid) */ :nth-of-type(-n + 2) { --j: 1 } /* change horizontal multiplier for odd ones (on 1st column) */ :nth-of-type(odd) { --i: 1 }}

Tenga en cuenta que solo tenemos recortes de disco visibles en el sectionelemento para los dos primeros articleelementos y solo en el h3para los dos últimos. Por lo tanto, para los dos primeros articleelementos, el radio en el pseudoelemento --rdel encabezado es , mientras que para los dos últimos, este radio es para el pseudoelemento de la sección :::before00::before

{ --r: 0 ; } } }}

De manera similar, agregamos paddings diferenciados a los hijos de los articleelementos:

*/ /* any CSS background we wish */ mask: radial-gradient(circle at 0 0, #000 var(--r, 50px), transparent 0);}

Tenga en cuenta que los navegadores WebKit aún necesitan el -webkit-prefijo para las maskpropiedades.

Luego agregamos los círculos en las otras esquinas:

*/ /* any CSS background we wish */ mask: $grad-list}

Eso es increíblemente repetitivo, ya sea mucho escribir o mucho copiar y pegar, así que veamos qué podemos hacer al respecto.

En primer lugar, utilizamos una variable CSS para la lista de exclusión. Esto elimina la repetición en el CSS generado.

*/ /* any CSS background we wish */ --stop-list: #000 var(--r, 50px), transparent 0; mask: $grad-list;}

Pero todavía no es mucho mejor, así que generemos las esquinas dentro de un bucle:

*/ /* any CSS background we wish */ --stop-list: #000 var(--r, 50px), transparent 0; mask: $grad-list;}

Mucho mejor en cuanto al código porque ahora no tenemos que escribir nada varias veces y correr el riesgo de no actualizarlo en todas partes más adelante. Pero el resultado hasta ahora no es el que buscábamos:

Aquí estamos cortando todo excepto las esquinas, que es lo opuesto a lo que queremos.

Una cosa que podemos hacer es invertir los degradados, hacer los círculos de las esquinas transparenty el resto blackcon:

*/ /* any CSS background we wish */ --stop-list: transparent var(--r, 50px), #000 0; mask: $grad-list; mask-size: 50% 50%; mask-repeat: no-repeat;}

Tenga en cuenta que los navegadores WebKit aún necesitan el -webkit-prefijo para masklas propiedades.

Pero el gran problema aquí es... el problema con la división y el redondeo en general: nuestros cuatro cuartos juntos no siempre logran formar un todo nuevamente, por lo que terminamos con espacios entre ellos.

Bueno, no es como si no pudiéramos cubrir esos huecos con linear-gradient()tiras finas o aumentar el , mask-sizedigamos 51%:

¿Pero no existe una forma más elegante?

Bueno, hay una mask-compositepropiedad que puede ayudarnos si la configuramos intersectal volver a las capas de degradado de tamaño completo.

*/ /* any CSS background we wish */ --stop-list: transparent var(--r, 50px), #000 0; mask: $grad-list; mask-composite: intersect;}

Esto es muy bueno porque es un CSS puro, no una solución SVG, pero la noticia no tan buena es que el soporte está limitado a Firefox 53+.

Sin embargo, al menos tenemos la -webkit-mask-compositealternativa no estándar (¡tomando valores diferentes!) para los navegadores WebKit. Así que eso es mucho mejor que el apoyo a la última opción que tenemos cuando se trata de curvas cerradas.

La corner-shapeopción

A Lea Verou se le ocurrió esta idea hace unos cinco años e incluso creó una página de vista previa. Lamentablemente, no solo no está implementada todavía en ningún navegador, sino que la especificación no ha avanzado mucho desde entonces. Aún es algo que hay que tener en cuenta para el futuro, ya que ofrece mucha flexibilidad con muy poco código: recrear nuestro efecto solo requeriría lo siguiente:

padding: var(--r);corner-shape: scoop;border-radius: var(--r);

Sin vómitos de marcado, sin largas listas de gradientes, solo este sencillo fragmento de CSS. ¡Eso es… cuando finalmente sea compatible con los navegadores!

SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion