Recreando el efecto degradado de Facebook Messenger con CSS | Programar Plus

Un domingo por la mañana me desperté un poco antes de lo que me hubiera gustado, gracias al persistente zumbido de mi teléfono. Extendí la mano, aproveché Facebook Messenger y me uní a la conversación. Muy pronto, mi atención pasó de las conversaciones reales al divertido efecto degradado de las burbujas de mensajes que las contenían. Déjame mostrarte lo que quiero decir:

Esta es una nueva función de Messenger, que le permite elegir un degradado en lugar de un color simple para el fondo de los mensajes de chat. Actualmente está disponible en la aplicación móvil y en el sitio de Facebook, pero aún no en el sitio de Messenger. El degradado aparece “fijo” para que las burbujas de chat parezcan cambiar de color de fondo a medida que se desplazan verticalmente.

Pensé que esto parecía algo que se podía hacer en CSS, así que… ¡desafío aceptado!

Repasemos mi proceso de pensamiento mientras intentaba recrearlo y explicar las características de CSS que se usaron para que funcionara. Además, veremos cómo Facebook lo implementó realmente (alerta de spoiler: no como lo hice yo) y cómo se comparan los dos enfoques.

Ensuciándonos las manos

Primero, veamos el ejemplo nuevamente para ver qué es exactamente lo que estamos tratando de lograr aquí.

En general, tenemos un diseño de mensajería bastante estándar: los mensajes se dividen en burbujas que van de arriba a abajo, la nuestra a la derecha y las otras personas en el chat a la izquierda. Todos los de la izquierda tienen un color de fondo gris, pero los de la derecha parecen compartir el mismo degradado de fondo fijo. ¡Eso es practicamente todo!

Paso 1: configurar el diseño

Esta parte es bastante simple: organicemos los mensajes en una lista ordenada y apliquemos CSS básico para que se parezca más a una aplicación de mensajería real:

<ol class="messages">
  <li class="ours">Hi, babe!</li>
  <li class="ours">I have something for you.</li>
  <li>What is it?</li>
  <li class="ours">Just a little something.</li>
  <li>Johnny, it’s beautiful. Thank you. Can I try it on now?</li>
  <li class="ours">Sure, it’s yours.</li>
  <li>Wait right here.</li>
  <li>I’ll try it on right now.</li>
</ol>

Cuando se trata de dividir los mensajes a la izquierda y a la derecha, mi reacción instintiva fue usar flotadores. Podríamos usar float: left para mensajes a la izquierda y float: right para que los mensajes de la derecha se adhieran a diferentes bordes. Entonces, aplicaríamos clear: both en cada mensaje para que se apilen. Pero hay un enfoque mucho más moderno: ¡flexbox!

Podemos usar flexbox para apilar los elementos de la lista verticalmente con flex-direction: column y dígales a todos los niños que se adhieran al borde izquierdo (o “alineen los bordes del margen de inicio cruzado de los niños flexibles con los bordes del margen de inicio cruzado de las líneas”, si prefiere los términos técnicos) con align-items: flex-start. Entonces, podemos sobrescribir el align-items valor para elementos flexibles individuales configurando align-self: flex-end en ellos.

¿Qué, quieres decir que no podías visualizar el código basado en eso? Bien, así es como se ve:

.messages {
  /* Flexbox-specific styles */
  display: flex;
  flex-direction: column;
  align-items: flex-start;

  /* General styling */
  font: 16px/1.3 sans-serif;
  height: 300px;
  list-style-type: none;
  margin: 0 auto;
  padding: 8px;
  overflow: auto;
  width: 200px;
}

/* Default styles for chat bubbles */
.messages li {
  background: #eee;
  border-radius: 8px;
  padding: 8px;
  margin: 2px 8px 2px 0;
}

/* Styles specific to our chat bubbles */
.messages li.ours {
  align-self: flex-end; /* Stick to the right side, please! */
  margin: 2px 0 2px 8px;
}

Algunos rellenos y colores aquí y allá y esto ya se ve lo suficientemente similar como para pasar a la parte divertida.

Paso 2: ¡Vamos a colorear las cosas!

La idea inicial para el degradado en realidad me vino de este tweet de Matthias Ott (que Chris recreó en otra publicación):

Este es un truco desagradable con un pseudo-elemento en la parte superior del texto y el modo de mezcla no funciona en IE / Edge, pero: ¡Sí, esto es posible de hacer con CSS! 😅https://t.co/FLKGvd1YoI

— Matthias Ott (@m_ott) 3 de diciembre de 2018

La pista clave aquí es mix-blend-mode, que es una propiedad de CSS que nos permite controlar cómo el contenido de un elemento se mezcla con lo que hay detrás. Es una característica que ha estado presente en Photoshop y otras herramientas similares por un tiempo, pero es bastante nueva en la web. Hay una entrada de almanaque para la propiedad que explica todos sus posibles valores.

Uno de los valores es screen: toma los valores de los píxeles del fondo y del primer plano, los invierte, los multiplica y los vuelve a invertir. Esto da como resultado un color que es más brillante que el color de fondo original.

La descripción puede parecer un poco confusa, pero lo que significa esencialmente es que si el fondo es monocromático, siempre que el fondo sea negro, los píxeles del primer plano se muestran completos y donde sea blanco, el blanco permanecerá.

Con mix-blend-mode: screen; en primer plano, veremos más primer plano a medida que el fondo es más oscuro.

Entonces, para nuestros propósitos, el fondo será la ventana de chat en sí y el primer plano contendrá un elemento con el degradado deseado establecido como fondo que se coloca sobre el fondo. Luego, aplicamos el modo de fusión apropiado al elemento de primer plano y cambiamos el estilo del fondo. Queremos que el fondo sea negro en los lugares donde queremos que se muestre el degradado y blanco en otros lugares, así que diseñaremos las burbujas dándoles un fondo negro simple y texto blanco. Ah, y recordemos agregar pointer-events: none al elemento de primer plano para que el usuario pueda interactuar con el texto subyacente.

En este punto, también cambié un poco el HTML original. Todo el chat es un envoltorio en un contenedor adicional que permite que el degradado permanezca “fijo” sobre la parte desplazable del chat:

.messages-container:after {
  content: '';
  background: linear-gradient(rgb(255, 143, 178) 0%, rgb(167, 151, 255) 50%, rgb(0, 229, 255) 100%);
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 100%;
  mix-blend-mode: screen;
  pointer-events: none;
}

.messages li {
  background: black;
  color: white;
  /* rest of styles */
}

El resultado se parece a esto:

El degradado aplicado a las burbujas de chat.

Paso 3: Excluye algunos mensajes del degradado

¡Ahora se muestra el degradado donde están las burbujas de texto debajo! Sin embargo, solo queremos que se muestre sobre nuestras burbujas, las que están a lo largo del borde derecho. Una pista de cómo se puede lograr eso está oculta en la descripción de MDN de la mix-blend-mode propiedad:

El mix-blend-mode La propiedad CSS establece cómo el contenido de un elemento debe combinarse con el contenido del padre del elemento y el fondo del elemento.

¡Así es! El fondo. Por supuesto, el efecto solo tiene en cuenta los elementos HTML que están detrás del elemento actual y tienen un orden de pila más bajo. Afortunadamente, el orden de apilamiento de los elementos se puede cambiar fácilmente con el z-index propiedad. Así que todo lo que tenemos que hacer es darle a las burbujas de chat de la izquierda una mayor z-index que la del elemento de primer plano y se elevarán por encima de él, fuera de la influencia de mix-blend-mode! Entonces podemos darles el estilo que queramos.

El degradado aplicado a las burbujas de chat.

Hablemos de compatibilidad con el navegador

En el momento de escribir, mix-blend-mode no es compatible en absoluto en Internet Explorer y Edge. En esos navegadores, el gradiente se coloca sobre todo el chat y las burbujas de los demás aparecen encima, lo que no es una solución ideal.

Estos datos de soporte del navegador son de Caniuse, que tiene más detalles. Un número indica que el navegador admite la función en esa versión y en adelante.

Escritorio

Cromo Firefox ES DECIR Borde Safari
41 32 No 79 TP

Móvil / Tableta

Android cromo android firefox Androide iOSSafari
96 95 96 15.2

Entonces, esto es lo que obtenemos en los navegadores no compatibles:

Cómo los navegadores que no son compatibles mix-blend-mode renderizar el chat.

Afortunadamente, todos los navegadores que soportan mix-blend-mode también admite consultas de funciones CSS. Su uso nos permite escribir primero estilos alternativos para navegadores no compatibles e incluir los efectos sofisticados para los navegadores que los admiten. De esta manera, incluso si un usuario no puede ver el efecto completo, aún puede ver todo el chat e interactuar con él:

Una interfaz de usuario simplificada para navegadores más antiguos, retrocediendo a un color de fondo cian simple.

Aquí está el Pen final con el efecto completo y los estilos alternativos:

ver la pluma
Coloreado degradado similar a Facebook Messenger en CSS por Stepan Bolotnikov (@Stopa)
en CodePen.

Ahora veamos cómo lo hizo Facebook.

Resulta que la solución de Facebook es casi lo contrario de lo que hemos cubierto aquí. En lugar de colocar el degradado sobre el chat y cortar agujeros en él, aplican el degradado como una imagen de fondo fija a todo el chat. El chat en sí está lleno de un montón de elementos vacíos con fondos y bordes blancos, excepto donde el degradado debería ser visible.

El HTML final presentado por la aplicación Facebook Messenger React es bastante detallado y difícil de navegar, así que recreé un ejemplo mínimo para demostrarlo. Muchos de los elementos HTML vacíos se pueden cambiar por pseudo-elementos en su lugar:

ver la pluma
Coloreado degradado similar a Facebook Messenger en CSS: The Facebook Way por Stepan Bolotnikov (@Stopa)
en CodePen.

Como puede ver, el resultado final es similar al mix-blend-mode solución, pero con un poco de marcado adicional. Además, su enfoque brinda más flexibilidad para contenido enriquecido, como imágenes y emojis. El mix-blend-mode El enfoque realmente no funciona si el fondo no es monocromático y no he podido encontrar una manera de “elevar” el contenido interno por encima del degradado o sortear esta limitación de otra manera.

Debido a esta limitación, es más inteligente utilizar el enfoque de Facebook en una aplicación de chat real. Aún así, nuestra solución usando mix-blend-mode muestra una forma interesante de usar una de las propiedades CSS menos apreciadas en el diseño web moderno y, con suerte, te ha dado algunas ideas sobre lo que podrías hacer con ella.