Creación de temas de color con propiedades personalizadas, HSL y un poco de calc() | Programar Plus

Antes de la llegada de las propiedades personalizadas de CSS (podríamos llamarlas “variables” en este artículo, ya que ese es el espíritu de ellas), implementar múltiples esquemas de color en el mismo sitio web generalmente significaba escribir hojas de estilo separadas. Definitivamente no es la cosa más mantenible del mundo. Hoy en día, sin embargo, podemos definir variables en una sola hoja de estilo y dejar que CSS haga la magia.

Incluso si no está ofreciendo algo como temas de color generados por el usuario o elegidos por el usuario, aún puede usar el concepto de tematización en su sitio web. Por ejemplo, es bastante común usar diferentes temas de colores en diferentes áreas del sitio.

Vamos a construir un ejemplo como este:

Mismo diseño, diferentes colores.

En este ejemplo, todo lo que cambia entre las secciones es el color. matiz; las variaciones de luminosidad son siempre las mismas. Aquí hay un ejemplo de una paleta de colores simplificada para un tono específico:

Una paleta de múltiples tonos podría verse así:

Esto requeriría un esfuerzo para hacerlo con el valor de color RGB, pero en HSL solo cambia un valor.

Introducir propiedades personalizadas

Las propiedades personalizadas han existido por un tiempo y son ampliamente compatibles. Polyfills y otras soluciones para IE 11 también están disponibles.

La sintaxis es muy similar al CSS tradicional. Aquí hay una descripción general del uso básico:

Es común ver variables definidas en el :root pseudo-elemento, que siempre es <html> en HTML, pero con mayor especificidad. Dicho esto, las variables se pueden definir en cualquier elemento que sea útil para determinar el alcance de variables específicas para elementos específicos. Por ejemplo, aquí hay variables definidas en atributos de datos:

Agregando calc() a la mezcla

Las variables no tienen que ser valores fijos. Podemos aprovechar el poder de la calc() función para calcular automáticamente los valores para nosotros mientras se adhiere a un patrón uniforme:

Dado que CSS no admite bucles, un preprocesador sería útil para generar una parte del código. Pero recuerda: las variables CSS no son lo mismo que las variables Sass.

Implementando variables CSS

Básicamente, lo que intentamos hacer es cambiar el color del mismo componente en diferentes secciones de la misma página. Como esto:

Disponemos de tres apartados en pestañas con sus propios ID: #food, #lifestyle, y #travel. Cada sección corresponde a un tono diferente. El data-theme-attribute sobre el div.wrapper El elemento define qué tono está actualmente en uso.

Cuándo #travel es la pestaña activa, estamos usando el --first-hue variable, que tiene un valor de 180°. Eso es lo que se usa como el --hue valor en la sección, lo que resulta en un color verde azulado:

<div class="wrapper" data-theme="travel">
.wrapper[data-theme="travel"] {
  --hue: var(--first-hue);  /* = 180° = teal */
}

Al hacer clic en cualquiera de las pestañas, se actualiza el atributo de tema de datos al ID de la sección, mientras se elimina el hash (#) de eso. Esto requiere una pizca de JavaScript. Esa es una de las (muchas) cosas buenas de CSS: se puede acceder a ellos y manipularlos con JavaScript. Esto está muy lejos de las variables del preprocesador, que se compilan en valores en la etapa de construcción y ya no son accesibles en el DOM.

<li><a href="https://css-tricks.com/creating-color-themes-with-custom-properties-hsl-and-a-little-calc/#food">Food</a></li>
const wrapper = document.querySelector('.wrapper');
document.querySelector("nav").addEventListener('click', e => {
  // Get theme name from URL and ditch the hash
  wrapper.dataset.theme = e.target.getAttribute('href').substr(1);
})

mejora progresiva

Cuando usamos JavaScript, debemos tener en cuenta los escenarios en los que un usuario puede haberlo deshabilitado. De lo contrario, nuestros scripts, y nuestra interfaz de usuario por extensión, son inaccesibles. Este fragmento garantiza que el contenido del sitio siga siendo accesible, incluso en esas situaciones:

// progressive enhancement:
// without JavaScript all sections are displayed, the theme is only set when the page loads
wrapper.dataset.theme = wrapper.querySelector('section').id;

Esto simplemente permite que las pestañas se desplacen hacia arriba en la página a la sección correspondiente. Claro, la tematización se ha ido, pero proporcionar contenido es mucho más importante.

Si bien elegí ir con un enfoque de una sola página, también es posible publicar las secciones como páginas separadas y establecer [data-theme] en el lado del servidor.

Otro enfoque

Hasta ahora, hemos asumido que los valores de color cambian linealmente y, por lo tanto, están sujetos a un enfoque matemático. Pero incluso en situaciones en las que esto es solo parcialmente cierto, aún podemos beneficiarnos del mismo concepto. Por ejemplo, si la luminosidad sigue un patrón pero el tono no, podríamos dividir la hoja de estilo de esta manera:

<head>
  <style>
    :root {
      --hue: 260;
    }
  </style>
  <link rel="stylesheet" href="https://css-tricks.com/creating-color-themes-with-custom-properties-hsl-and-a-little-calc/stylesheet-with-calculations-based-on-any-hue.css">
</head>

Compatibilidad con componentes web

Los componentes web son un concepto emocionante (y en evolución). Es tentador pensar que podemos tener componentes encapsulados que se pueden reutilizar en cualquier lugar y tematizarlos caso por caso. ¡Un componente con muchos contextos!

Podemos usar temas variables de CSS con componentes web. requiere que usemos un host-context() pseudo-selector. (¡Gracias a habemuscode por señalarme esto!)

:host-context(body[data-theme="color-1"]) {
  --shade-1: var(--outsideHSL);
}

En resumen…

Tematizar un sitio web con propiedades personalizadas de CSS es mucho más fácil que los enfoques alternativos a los que hemos recurrido en el pasado. Es más fácil de mantener (una hoja de estilo), eficaz (menos código) y abre nuevas posibilidades (usando JavaScript). Sin mencionar que las propiedades personalizadas de CSS se vuelven aún más poderosas cuando se usan con colores HSL y el calc() función.

Acabamos de ver un ejemplo en el que podemos cambiar el tema de color de un componente según la sección donde se usa. Pero nuevamente, hay muchas más oportunidades aquí cuando comenzamos a entrar en cosas como permitir que los usuarios cambien los temas por sí mismos, un tema que Chris explora en este artículo.