Kodokon kodokon.com

Variables CSS y las funciones calc/clamp

Domina las propiedades personalizadas, cómo se resuelven en tiempo de ejecución dentro de la cascada, y las funciones calc() y clamp() para interfaces fluidas.

10 min · 3 preguntas

Abrir esta lección en Kodokon

Las propiedades personalizadas no son variables de preprocesador. Una variable de Sass se sustituye en tiempo de compilación; una propiedad --brand se resuelve en tiempo de ejecución, participa en la cascada, se hereda como cualquier otra propiedad y puede modificarse mediante una media query, una clase o JavaScript con setProperty(). Eso es lo que hace posibles la tematización dinámica, el modo oscuro sin recompilación y la comunicación entre CSS y JS sin volver a renderizar.

CSS
:root {
  --brand: #6c5ce7;
  --spacing: 8px;
}

.card {
  color: var(--brand);
  padding: calc(var(--spacing) * 2);
  border-color: var(--accent, currentColor);
}
Declarar, leer y valores de reserva

El segundo argumento de var() es un valor de reserva, utilizado únicamente cuando la propiedad no está definida. Trampa clásica: si --accent vale 12px y lo inyectas en color, el valor de reserva no se usa. La declaración pasa a ser inválida en el momento del valor calculado: la propiedad recae en su valor heredado o inicial, no en la declaración anterior como haría un error de sintaxis normal.

La regla @property corrige dos limitaciones importantes: da a la variable un tipo (y por tanto validación) y la hace animable, ya que el motor ahora sabe cómo interpolar entre dos valores tipados en lugar de tratar la variable como una cadena opaca.

CSS
@property --progress {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 0%;
}

.gauge {
  background: conic-gradient(
    var(--brand) var(--progress),
    #e5e7eb 0
  );
  transition: --progress 0.4s ease-out;
}

.gauge.is-full {
  --progress: 100%;
}
Una variable tipada y animable con @property

Por el lado matemático, calc() te permite mezclar unidades (calc(100% - 2rem)), algo imposible con un preprocesador, ya que la resolución depende del contexto de renderizado. clamp(min, ideal, max) es azúcar sintáctico para max(min, min(ideal, max)) y supera a las pilas de puntos de ruptura para la tipografía fluida: el valor ideal, a menudo expresado en vw o cqi, se desliza libremente entre los dos límites.

CSS
:root {
  --fluid-title: clamp(
    1.5rem,
    1rem + 2.5vw,
    3rem
  );
}

h1 {
  font-size: var(--fluid-title);
  max-width: clamp(20ch, 60%, 65ch);
}
Tipografía fluida sin media query

Prueba de conocimientos

Comprueba que has retenido los puntos clave de esta lección.

  1. ¿Qué ocurre si se evalúa color: var(--gap) mientras --gap vale 12px?
    • La declaración se ignora y se aplica la regla color anterior
    • La declaración pasa a ser inválida en el momento del valor calculado y color se resuelve como unset
    • El navegador convierte 12px en un color cercano al negro
    • Se lanza un error en la consola y se rechaza la hoja de estilos
  2. ¿A qué equivale estrictamente clamp(1rem, 2.5vw, 2rem)?
    • max(1rem, min(2.5vw, 2rem))
    • min(1rem, max(2.5vw, 2rem))
    • calc(1rem + 2.5vw + 2rem)
  3. ¿Cuál es el principal beneficio de @property frente a una propiedad personalizada normal?
    • Hace que la variable sea accesible desde JavaScript
    • Permite que la variable se use dentro de un calc()
    • Da a la variable un tipo, lo que en particular la hace interpolable en animaciones
    • Fuerza a la variable a heredarse en todo el documento