
Hola a todos, mi nombre es Vitalik, soy un desarrollador senior senior en Skyeng. Nuestro equipo está creando una plataforma Vimbox en línea para aprender inglés. Hace aproximadamente un año, el diseñador y yo completamos un pequeño kit de interfaz de usuario que desarraigó el caos en la interfaz y la base de código.
Resultó que no éramos los únicos en la empresa que queríamos el kit de interfaz de usuario, y otros equipos comenzaron a acudir a nosotros para pedirnos "cómo escribir uno propio". Nos las arreglamos para disuadirlos de esta empresa, prometiendo moderar la nuestra, esto le ahorró a la compañía cientos de horas de desarrollo. Al elegir una solución, examinamos el material angular, los ensamblajes personalizados y las variables CSS y finalmente nos decidimos por este último, a pesar de su débil compatibilidad con SCSS, la base del kit de interfaz de usuario existente. Debajo del corte: detalles de lo que hicimos.

El problema
El primer kit de interfaz de usuario consistía en fuentes, una paleta, un conjunto de elementos para crear formularios (entrada, botón, etc.), un sistema para administrar iconos svg. También se implementaron ventanas emergentes e información sobre herramientas basadas en materiales angulares. Fue encarcelado por trabajar solo con el Vimbox "clásico": muchas cosas fueron cosidas deliberadamente y no permitieron cambios desde el exterior. Y Skyeng comenzó a tener nuevos productos en la misma plataforma, por ejemplo, para niños.
Los desarrolladores de nuevas direcciones, sabiendo que tenemos algo, vinieron por consejo. Además, para nuestra sorpresa, ya venían con los diseños de sus kits de interfaz de usuario: iban a desarrollar sus soluciones desde cero, porque Necesitaban un aspecto diferente para los componentes. Estaba claro que algo iba mal, y propusimos refinar nuestra biblioteca, agregando la posibilidad de su temática.
El argumento era simple: el diseño de nuestro kit de interfaz de usuario tomó 200 horas de diseño de UX y más de 500 horas de desarrollo. Este es el tiempo requerido para crear un sistema de fuentes, colores y unos 10 componentes básicos. En consecuencia, si escribe una biblioteca separada para cada producto, la compañía pasará N * 500 horas de tiempo de desarrollo. Pensamos que mejorar nuestro kit de IU sería más barato, además este paso no tendría que repetirse para cada producto.
Nuestros argumentos fueron aceptados, las áreas relacionadas acordaron esperar, y partimos a buscar una solución técnica.
Datos de origen
Nuestras herramientas: Angular, SCSS.
Solo admitimos navegadores modernos y, con algunas limitaciones, IE11. Lo que hace la vida más fácil.
Todos nuestros componentes del kit de IU estaban imbuidos de estilos comunes que UI kit.var.scss
en UI kit.var.scss
como constantes SCSS:
@mixin fontSizeXl { @include fontSize(18px, 26px); } $colorSkillListening: #9679e0; $colorSkillListeningText: #7754d1; $colorSkillListeningBackground: mix($colorSkillListening, #ffffff, 16%); $colorSkillListeningBackgroundHover: mix($colorSkillListening, #ffffff, 8%);
Desafío
- Todos los productos nuevos se ensamblan a partir de elementos existentes que están presentes en el Vimbox "adulto": aulas, cuentas personales, etc.
- Los diseñadores deben tener amplia libertad para implementar ideas creativas, características distintivas y requisitos específicos de nuevos productos.
- Al mismo tiempo, la continuidad permanece, es decir. No importa qué colores ácidos y fuentes locas invente el diseñador, la pertenencia del resultado de su trabajo al ecosistema Skyeng sigue siendo obvia.
- Todo esto se agrega al kit de interfaz de usuario existente, conservando todas sus ventajas.
Vamos!
Entonces, el resultado se espera de nosotros ayer, debemos realizar rápidamente revisiones técnicas y discutir opciones. En las primeras reuniones, identificamos un círculo de posibles soluciones:
Material angular
No nos gusta escribir bicicletas, por lo que recurrimos primero al material angular. En los componentes, los estilos dinámicos se mueven a un archivo {component}-theme.scss
. Estos estilos están vinculados al selector global del componente.
Variables CSS
Tenemos una gran razón para probar las variables CSS de moda. El plan es trasplantar las partes personalizadas del kit de interfaz de usuario a las variables CSS. Los componentes usan las mismas constantes SCSS, pero en lugar de valores específicos, los vars CSS están escritos en ellos.
Construcciones personalizadas
Nos encantan las soluciones simples, ¿por qué no intentar cambiar el ensamblaje? Cada equipo crea su propio archivo con la configuración del tema. Al ensamblar para todos los temas personalizados, se crean paquetes separados con su propio tema.
Solución
Durante una semana estudiamos cada opción, discutimos, posponemos la decisión y volvimos a estudiar.
Nos encantan las nuevas tecnologías y las supervisamos, pero solo las implementamos si nos dan bonificaciones reales. Sabíamos acerca de las variables CSS, queríamos probarlas, pero la falta de funciones SCSS causó mucha tristeza. Sin embargo, las ventajas de esta opción eran obvias, decidimos averiguar cómo y qué funciones SCSS utilizamos, si es posible hacer amigos con CSS vars.
Entendiendo CSS vs SCSS
Después de experimentar, nos dimos cuenta de que el problema principal es la falta de soporte para #hex en CSS: en SCSS escribimos rgba(#ffffff, 0.4)
, y en CSS lo mismo requiere un conjunto diferente de parámetros: rgba(255, 255, 255, 0.4)
. Todo funciona para nosotros con #hex, y realmente, realmente no queremos cambiar esto. Encontramos soluciones, lo diré en el orden de admisión.
Aligerar y oscurecer
A nuestro diseñador se le ocurrió una paleta que consta de una pequeña cantidad de colores básicos, expandiéndose debido a las funciones SCSS de lighten
y darken
:
Intentamos encontrar un análogo de lighten
y darken
en CSS, pero no encontramos nada. Pensamos durante varios días hasta que nos dimos cuenta de que para la personalización necesitamos deshacernos de estas funciones dentro de la biblioteca y eliminarlas. Después de todo, cada equipo puede querer crear su propia fórmula para cambiar el color al cambiar de enfoque; por ejemplo, los colegas de Kids necesitan más contraste.
La solución simple fue transferir nuestras transformaciones al lado de la plataforma que inicializará el tema. Y para la plataforma, estamos escribiendo una función que crea automáticamente los valores necesarios:
@function getMainColors($color, $colorText) { $colors: ( text: $colorText, base: $color, background: mix($color, #ffffff, 16%), backgroundHover: mix($color, #ffffff, 8%), lightenLess: lighten($color, 5), darkenLess: darken($color, 5), lightenMore: lighten($color, 20), ); @return $colors; }
La plataforma lo usa al inicializar colores:
RGBA
En nuestro kit de IU utilizamos la función rgba
. Con él, ajustamos la transparencia de los colores base. Pero si rgba funciona con #hex en SCSS, entonces CSS no puede. Tuve que escribir una función que descomponga el valor #hex en r / g / b:
Bueno, dado que no queremos generar valores RGB con tiradores para toda la paleta, creamos una función separada que hace esto de forma recursiva para cada color de la colección:
Como resultado, la inicialización de la paleta con los valores RGB generados se ve así:
$colorValues: withRgbValues( ( text: ( base: #242d34, secondary: #50575c, label: #73797d, placeholder: #969b9e, inversed: #ffffff, inversedSecondary: #dadada, ), brand: getMainColors(#5d9cec, #4287df), positive: getMainColors(#8cc152, #55a900), accent: getMainColors(#ff3d6f, #ff255d), wrong: getMainColors(#ff6666, #fe4f44),
El resultado es un mapa de color SCSS, que luego se puede convertir en un método que lo convierte en variables CSS. Para obtener el valor del tema RGB, escribimos una función:
@function getUiKitRgbVar($path...) { $path: set-nth($path, -1, #{nth($path, -1)}Rgb);
Convierta SCSS const en CSS vars
El primer paso es crear una estructura espejo (similar a SCSS) que almacene los nombres de las variables CSS:
$colorCssVars: withRgbCssVars( ( text: ( base: getColorCssVar(text, base), secondary: getColorCssVar(text, secondary), label: getColorCssVar(text, label), placeholder: getColorCssVar(text, placeholder), inversed: getColorCssVar(text, inversed),
getColorCssVar
: un método que agrega prefijos a nombres de variables. Agregue el prefijo --sky
para evitar colisiones con bibliotecas externas. Y también agregue el prefijo de la biblioteca del - UI kit
a --sky
para evitar conflictos con las bibliotecas internas. Resultó --sky- UI kit
:
@function getColorCssVar($parts...) { @return getUiKitCssVar(color, $parts...); } @function getUiKitCssVar($parts...) { $uiKitCssVarPrefix: '--sky- UI kit'; $cssVar: $uiKitCssVarPrefix; @each $part in $parts { $cssVar: $cssVar + '-' + $part; } @return $cssVar; }
Por ejemplo, para getColorCssVar(text, base)
obtenemos --sky- UI kit-color-text-base
en la salida.
El toque final es una mezcla recursiva que inicializa los valores de la estructura SCSS a variables con nombres de la estructura CSS Var:
Un ejemplo de uso de un tema en la plataforma:
.popup { font-family: getUiKitVar(font, family); background-color: getUiKitVar(color, background, base); ... }
Cual es el resultado
Pudimos usar Variables CSS, al tiempo que conservamos la capacidad de usar funciones SCSS. Creó la capacidad de personalizar la apariencia de los componentes. Escribimos un par de métodos recursivos para automatizar la extensión del tema. Bueno y lo más importante: pasé 30 horas de desarrollo en lugar de N * 500.
Beneficio!