Una guía completa de propiedades personalizadas.

Una propiedad personalizada se considera más común como una variable en CSS.

.card {  --spacing: 1.2rem;  padding: var(--spacing);  margin-bottom: var(--spacing);}

Arriba, --spacingestá la propiedad personalizada con 1.2remel valor y var(--spacing)la variable en uso.

Quizás la razón más valiosa para usarlos: no repetirse (código DRY ). En el ejemplo anterior, puedo cambiar el valor 1.2rem en un lugar y hacer que afecte dos cosas. Esto aporta algo que los lenguajes de programación hacen un CSS.

Hay mucho que saber sobre las propiedades personalizadas, así que entremos en ello.

¿Por qué te preocupas por las propiedades personalizadas de CSS?

  1. Ayudan a SECAR tu CSS. Eso es “No te repitas”. Las propiedades personalizadas pueden hacer que el código sea más fácil de mantener porque puede actualizar un valor y reflejarlo en varios lugares. Pero tenga cuidado, exagerar la abstracción puede tener el efecto contrario y hacer que el código sea menos comprensible.
  2. Son particularmente útiles para cosas como crear temas de color en un sitio web.
  3. Desbloquean posibilidades interesantes en CSS. En gran parte porque cae en cascada.
  4. El hecho de que puedan actualizarse en JavaScript abre posibilidades aún más interesantes.

Tabla de contenido

  • ¿Por qué te preocupas por las propiedades personalizadas de CSS?
    • Nombrar propiedades personalizadas
      • Propiedades como propiedades
    • Valores válidos para propiedades personalizadas
    • rompiendo valores
      • Dividir colores
      • Oscuridad
      • degradados
      • Valores separados por comas (como fondos)
      • rejilla
      • Transforma
      • Concatenación de tipos de unidades
    • Usando la cascada
      • Lo de la raíz
    • Combinando con !importante
    • Reservas de propiedades personalizadas
    • Usando calc() y propiedades personalizadas
      • Aplazar el cálculo()
    • @propiedad
    • Comas en valores
    • Uso avanzado
      • El truco inicial y de los espacios en blanco
      • Estilos en línea
      • Hovers y pseudos
    • Propiedades personalizadas y JavaScript
    • Las propiedades personalizadas son diferentes a las variables del preprocesador.
      • ¿Puedes preprocesar propiedades personalizadas?
      • Disponibilidad
    • Propiedades personalizadas y componentes web (Shadow DOM)
    • Soporte del navegador
      • @apoya
    • Artículos relacionados
    • credito

Nombrar propiedades personalizadas

Las propiedades personalizadas deben estar dentro de un selector y comenzar con dos guiones ( --):

/* Nope, not within a selector */--foo: 1;body {  /* No, 0 or 1 dash won't work */  foo: 1;  -foo: 1;   /* Yep! */  --foo: 1;  /* OK, but they're different properties */  --FOO: 1;  --Foo: 1;    /* Totally fine */  --mainColor: red;  --main-color: red;  /* Special characters are a no */  --color@home: red;  --blackblue: black;  --black^2: black;}

Es mejor seguir con letras, números y guiones mientras se asegura de que la propiedad personalizada esté definida dentro de un selector válido.

Propiedades como propiedades

Puede establecer el valor de una propiedad personalizada con otra propiedad personalizada:

html {  --red: #a24e34;  --green: #01f3e6;  --yellow: #f0e765;  --error: var(--red);  --errorBorder: 1px dashed var(--red);  --ok: var(--green);  --warning: var(--yellow);}

A algunas personas les gusta hacerlo de esta manera porque permite que el nombre de una propiedad personalizada sea descriptivo y luego se use en otra propiedad con un nombre más funcional, lo que nuevamente ayuda a mantener las cosas SECO . Incluso puede ayudar a que los nombres funcionales sean más legibles y comprensibles.

Hay un gran problema con las propiedades personalizadas que utilizan otras propiedades personalizadas que debes tener en cuenta.

Valores válidos para propiedades personalizadas

Las propiedades personalizadas son sorprendentemente tolerantes en cuanto a los valores que aceptan.

A continuación se muestran algunos ejemplos básicos que esperaría que funcionaran y que lo hicieran.

body {  --brand-color: #990000;  --transparent-black: rgba(0, 0, 0, 0.5);    --spacing: 0.66rem;  --max-reading-length: 70ch;  --brandAngle: 22deg;  --visibility: hidden;  --my-name: "Chris Coyier";}

¿Mira eso? Pueden ser valores hexadecimales, funciones de color, unidades de todo tipo e incluso cadenas de texto.

Patrones para el uso práctico de propiedades personalizadas de CSS

propiedades personalizadas tyler niños

Una guía de estrategia para las propiedades personalizadas de CSS.

propiedades personalizadas Chris Coyier

Ventajas de las variables nativas CSS

propiedades personalizadas Chris Coyier

Propiedades personalizadas como estado

propiedades personalizadas Chris Coyier

Pero las propiedades personalizadas no tienen por qué ser valores completos como ese. Veamos lo útil que puede ser dividir los valores CSS válidos en partes que podamos incluir en propiedades personalizadas.

rompiendo valores

Puede utilizar propiedades personalizadas para dividir valores de varias partes.

Imaginemos que estás usando una función de color, por ejemplo rgba(). Cada valor de canal de color allí puede tener su propia propiedad personalizada. Eso abre un montón de posibilidades, como cambiar el valor alfa para un caso de uso específico o quizás crear temas de color.

Dividir colores

Tomemos como ejemplo el color HSL. Podemos dividirlo en partes y luego ajustar muy fácilmente las partes donde queramos. Quizás estemos trabajando con el color de fondo de un botón. Podemos actualizar partes específicas de su composición HSL cuando el botón está suspendido, enfocado o deshabilitado, sin declarar backgroundninguno de esos estados en absoluto.

button {  --h: 100;  --s: 50%;  --l: 50%;  --a: 1;  background: hsl(var(--h) var(--s) var(--l) / var(--a));}button:hover { /* Change the lightness on hover */  --l: 75%;}button:focus { /* Change the saturation on focus */  --s: 75%;}button[disabled] {  /* Make look disabled */  --s: 0%;  --a: 0.5;}

Al separar valores de esta manera, podemos controlar partes de ellos como nunca antes. Solo mire cómo no necesitábamos declarar todos los argumentos HSL para diseñar el estado de desplazamiento, enfoque y desactivación de un botón. Simplemente anulamos valores HSL específicos cuando lo necesitábamos. ¡Cosas geniales!

Oscuridad

box-shadowno tiene una propiedad abreviada para controlar la propagación de la sombra por sí sola. Pero podríamos desglosar el box-shadowvalor del diferencial y controlarlo como una propiedad personalizada (demostración).

button {  --spread: 5px;  box-shadow: 0 0 20px var(--spread) black;}button:hover {  --spread: 10px;}

degradados

No existe una abreviatura background-gradient-angle(o similar) para los gradientes. Con las propiedades personalizadas, podemos cambiar simplemente cambiar esa parte como si existiera tal cosa.

body {  --angle: 180deg;  background: linear-gradient(var(--angle), red, blue);}body.sideways {  --angle: 90deg;}

Valores separados por comas (como fondos)

Cualquier propiedad que admita múltiples valores separados por comas también podría ser una buena candidata para dividir valores, ya que no existe tal cosa como apuntar solo a un valor de una lista separada por comas y cambiarlo solo.

/* Lots of backgrounds! */background-image:  url(./img/angles-top-left.svg),  url(./img/angles-top-right.svg),  url(./img/angles-bottom-right.svg),  url(./img/angles-bottom-left.svg),  url(./img/bonus-background.svg);

Supongamos que deseamos eliminar solo uno de los muchos fondos en una consulta de medios. Podrías hacerlo con propiedades personalizadas como esta, haciendo que sea una tarea trivial intercambiar o fondos anulares.

body {  --bg1: url(./img/angles-top-left.svg);  --bg2: url(./img/angles-top-right.svg);  --bg3: url(./img/angles-bottom-right.svg);  --bg4: url(./img/angles-bottom-left.svg);  --bg5: url(./img/bonus-background.svg);    background-image: var(--bg1), var(--bg2), var(--bg3), var(--bg4);}@media (min-width: 1500px) {  body {    background-image: var(--bg1), var(--bg2), var(--bg3), var(--bg4), var(--bg5);  }}

rejilla

Estamos en una buena racha aquí, por lo que también podríamos hacer algunos ejemplos más. Oye, podemos tomar la grid-template-columnspropiedad y abstraer sus valores en propiedades personalizadas para crear un sistema de cuadrícula súper flexible:

.grid {  display: grid;  --edge: 10px;  grid-template-columns: var(--edge) 1fr var(--edge);}@media (min-width: 1000px) {  .grid {     --edge: 15%;   }}

Transforma

CSS pronto obtendrá transformaciones individuales, pero podemos hacerlo antes con propiedades personalizadas. La idea es aplicar todas las transformaciones que un elemento pueda tener desde el principio y luego controlarlas individualmente según sea necesario:

button {  transform: var(--scale, scale(1)) var(--translate, translate(0));}button:active {  --translate: translate(0, 2px);}button:hover {  --scale: scale(0.9);}

Concatenación de tipos de unidades

Hay ocasiones en las que combinar partes de valores no funciona como se esperaba. Por ejemplo, no se puede hacer 24pxaplastando 24y pxjuntando. Sin embargo, se puede hacer multiplicando el número bruto por un valor numérico con una unidad.

body {  --value: 24;  --unit: px;    /* Nope */  font-size: var(--value) + var(--unit);    /* Yep */  font-size: calc(var(--value) * 1px);  /* Yep */  --pixel_converter: 1px;  font-size: calc(var(--value) * var(--pixel_converter));}

Clases de utilidad contextuales para color con propiedades personalizadas

propiedades personalizadas Christopher Kirk Nielsen

Hacer que las propiedades personalizadas (variables CSS) sean más dinámicas

propiedades personalizadas Daniel Wilson

Más gráficos CSS, con cuadrículas y propiedades personalizadas.

propiedades personalizadas Miriam Susana

Diseños responsivos y propiedades personalizadas de CSS: definición de variables y puntos de interrupción

propiedades personalizadas Mikolaj Dobrucki

El estado del cambio de degradados con transiciones y animaciones CSS

propiedades personalizadas Ana Tudor

Uso de propiedades personalizadas de CSS para ajustar los pesos de fuente variables en modo oscuro

propiedades personalizadas Greg Gibson

Usando la cascada

El hecho de que las propiedades personalizadas utilicen la cascada es una de las cosas más útiles que tienen.

Ya lo ha visto en acción en muchos de los ejemplos que hemos cubierto, pero lo dejémoslo en claro. Digamos que tenemos una propiedad personalizada configurada bastante “en lo alto” (en el cuerpo) y luego configurada nuevamente en una clase específica. Lo usamos en un componente específico.

body {  --background: white;}.sidebar {  --background: gray;}.module {  background: var(--background);}

Luego digamos que tenemos HTML práctico como este:

body !-- --background: white --  main    div      I will have a white background.    /div  main  aside !-- --background: gray --    div      I will have a gray background.    /div  /aside/body

El "módulo" en la barra lateral tiene un fondo gris porque las propiedades personalizadas (como muchas otras propiedades CSS) se heredan a través de la estructura HTML. Cada módulo toma el --backgroundvalor del "ancestro" más cercano donde se ha definido en CSS.

Entonces, tenemos una declaración CSS pero hace cosas diferentes en diferentes contextos, gracias a la cascada. Eso es simplemente genial.

Esto se desarrolla de otras maneras:

button {  --foo: Default;}button:hover {  --foo: I win, when hovered;  /* This is a more specific selector, so re-setting      custom properties here will override those in `button` */}

Las consultas de medios no cambian la especificidad, pero a menudo aparecen más tarde (o más abajo) en el archivo CSS que donde el selector original establece un valor, lo que también significa que una propiedad personalizada se anulará dentro de la consulta de medios:

body {  --size: 16px;  font-size: var(--size);}@media (max-width: 600px) {  body {    --size: 14px;  } }  

Las consultas de medios no son solo para tamaños de pantalla. Se pueden utilizar para cosas como preferencias de accesibilidad. Por ejemplo, modo oscuro:

body {  --bg-color: white;   --text-color: black;  background-color: var(--bg-color);  color: var(--text-color);}/* If the user's preferred color scheme is dark */@media screen and (prefers-color-scheme: dark) {  body {    --bg-color: black;    --text-color: white;  }}

La :rootcosa

A menudo verá propiedades personalizadas configuradas "en la raíz". Esto es lo que eso significa:

:root {  --color: red;}/* ...is largely the same as writing: */html {  --color: red;}/* ...except :root has higher specificity, so remember that! */   

No existe ninguna razón particularmente convincente para definir propiedades personalizadas como esa. Es solo una forma de configurar propiedades personalizadas lo más alto posible. Si te gusta eso, está totalmente bien. De alguna manera me parece más normal aplicarlos a los selectores htmlo bodycuando configuro propiedades que pretendo poner a disposición globalmente o en todas partes.

Tampoco hay ninguna razón por la que necesite establecer variables en un alcance tan amplio. Puede ser igual de útil, y quizás más legible y comprensible, configurarlos justo en el nivel en el que los vas a utilizar (o bastante cerca en el árbol DOM).

.module {  --module-spacing: 1rem;  --module-border-width: 2px;  border: var(--module-border-width) solid black;}.module + .module {  margin-top: var(--module-spacing);}

Tenga en cuenta que establecer una propiedad personalizada en el módulo mismo significa que esa propiedad ya no se heredará de un antepasado (a menos que establezcamos el valor en inherit). Al igual que otras propiedades heredadas, a veces hay razones para especificarlas en su lugar (a nivel global) y otras veces queremos heredarlas del contexto (a nivel de componente). Ambos son útiles. Lo bueno de las propiedades personalizadas es que podemos definirlas en un lugar, heredarlas detrás de escena y aplicarlas en algún lugar completamente diferente. ¡Tomamos el control de la cascada!

Una guía de estrategia para las propiedades personalizadas de CSS

propiedades personalizadas Chris Coyier

Configuración de estilo global y de componentes con variables CSS

propiedades personalizadas Chris Coyier

Eliminar las propiedades personalizadas de CSS de :root podría ser una buena idea

propiedades personalizadas Kevin Powell

Combinando con!important

Puede crear un !importantmodificador dentro o fuera de una variable.

.override-red {  /* this works */  --color: red !important;    color: var(--color);  /* this works, too */  --border: red;  border: 1px solid var(--border) !important;}

Aplicar !importanta la --colorvariable dificulta anular el valor de la --colorvariable, pero aún podemos ignorarlo cambiando la colorpropiedad.

El comportamiento de !importantlos valores internos de las propiedades personalizadas es bastante inusual. Stefan Judis lo documenta bien, pero lo esencial es:

  1. En última instancia, !importantse despoja del valor de la propiedad personalizada.
  2. Pero se utiliza para determinar qué valor gana cuando se establece en varios lugares.
div {  --color: red !important;}#id {  --color: yellow;}

Si ambos selectores se aplican a un elemento, podría pensar que el #idvalor ganaría debido a la mayor especificidad, pero en realidad redganará debido a !important, pero finalmente se aplicará sin !important. Es un poco raro entenderlo.

Si se aplica el !importantexterior de la propiedad personalizada, como en el segundo ejemplo, dos bloques de código arriba, nuestra --bordervariable sigue siendo de baja especificidad (fácil de anular), pero es difícil cambiar cómo se aplicará ese valor a bordersí mismo porque se conserva toda la declaración !important.

Reservas de propiedades personalizadas

La var()función es lo que permite valores alternativos en propiedades personalizadas.

Aquí estamos configurando una scale()función de transformación en una propiedad personalizada, pero hay un segundo valor separado por comas1.2 de . Ese 1.2valor se utilizará si --scaleno se establece.

.bigger {  transform: scale(var(--scale, 1.2));}

Después de la primera coma, cualquier coma adicional forma parte del valor alternativo. Eso nos permite crear reservas con valores separados por comas dentro de ellas. Por ejemplo, podemos hacer que una variable recurra a una pila completa de fuentes:

html {  font-family: var(--fonts, Helvetica, Arial, sans-serif);}

También podemos proporcionar una serie de alternativas variables (tantas como queramos), pero tenemos que anidarlas para que eso funcione:

.bigger {  transform: scale(var(--scale, var(--second-fallback, 1.2));}

Si --scaleno está definido, probamos el --second-fallback. Si eso tampoco está definido, finalmente recurrimos a 1.2.

Uso calc()y propiedades personalizadas

¡Se desbloquea aún más poder de las propiedades personalizadas cuando las combinamos con matemáticas!

Este tipo de cosas es común:

main {  --spacing: 2rem;}.module {  padding: var(--spacing);}.module.tight {  /* divide the amount of spacing in half */  padding: calc(var(--spacing) / 2)); } 

También podríamos usarlo para calcular el tono de un color complementario:

html {  --brand-hue: 320deg;  --brand-color: hsl(var(--brand-hue), 50%, 50%);  --complement: hsl(calc(var(--brand-hue) + 180deg), 50%, 50%);}

calc()Incluso se puede utilizar con múltiples propiedades personalizadas:

.slider {  width: calc(var(--number-of-boxes) * var(--width-of-box));}

Aplazando elcalc()

Puede parecer extraño ver matemáticas de tipo cálculo sin calc():

body {  /* Valid, but the math isn't actually performed just yet ... */  --font-size: var(--base-font-size) * var(--modifier);  /* ... so this isn't going to work */  font-size: var(--font-size);}

El truco es que siempre que lo pongas en una calc()función, funcionará bien:

body {  --base-font-size: 16px;  --modifier: 2;  --font-size: var(--base-font-size) * var(--modifier);  /* The calc() is "deferred" down to here, which works */  font-size: calc(var(--font-size));}

Esto puede ser útil si está haciendo bastantes cálculos con sus variables y el calc()contenedor distrae o hace ruido en el código.

@propiedad

La @property"regla at" en CSS le permite declarar el tipo de una propiedad personalizada, así como su valor inicial y si se hereda o no.

Es como si estuvieras creando una propiedad CSS real y tuvieras la capacidad de definir cómo se llama, su sintaxis, cómo interactúa con la cascada y su valor inicial.

@property --x {  syntax: 'number';  inherits: false;  initial-value: 42;}
Tipos válidos
  • length
  • number
  • percentage
  • length-percentage
  • color
  • image
  • url
  • integer
  • angle
  • time
  • resolution
  • transform-list
  • transform-function
  • custom-ident(una cadena de identificación personalizada)

Esto significa que el navegador sabe con qué tipo de valor está tratando, en lugar de asumir que todo es una cadena. Eso significa que puedes animar cosas de maneras que de otro modo no podrías.

Por ejemplo, supongamos que tiene un ícono en forma de estrella con el que desea girar @keyframesy rotar con un transform. Entonces haces esto:

.star {  --r: 0deg;  transform: rotate(var(--r));  animation: spin 1s linear infinite;}@keyframes spin {  100% {    --r: 360deg;  }}  

En realidad, eso no funcionará, ya que el navegador no lo sabe 0degy 360degson valores de ángulo válidos. Tienes que definirlos como un angletipo para @propertyque eso funcione.

@property --r {  syntax: 'angle';  initial-value: 0deg;  inherits: false;}.star {  --r: 0deg;  transform: rotate(var(--r));  animation: spin 1s linear infinite;}@keyframes spin {  100% {    --r: 360deg;  }} 
Manifestación

@propiedad

propiedades personalizadas Chris Coyier

Usando @property para propiedades personalizadas de CSS

propiedades personalizadas Chris Coyier

Explorando @property y sus poderes de animación

propiedades personalizadas Jhey Tompkins

241: La @property es mágica

propiedades personalizadas Geoff Graham

Comas en valores

Esto puede resultar un poco confuso. Quizás no tanto esto:

html {  --list: 1, 2, 3;}

Pero a continuación necesitarás estar atento para darte cuenta de que el valor alternativo es en realidad 1.2, 2. La primera coma separa el recurso alternativo, pero el resto es parte del valor.

html {  transform: scale(var(--scale, 1.2, 2));}

Obtenga más información sobre las alternativas arriba ⮑

Uso avanzado

Raven es una técnica que emula consultas de contenedores utilizando propiedades matemáticas y personalizadas. ¡Esté preparado, esto va de 0 a 100 en complejidad desde el principio!

Manifestación

Cambie el tamaño de esta demostración para ver una cuadrícula de elementos de bloque en línea que cambian el número de columnas de 4 a 3 a 1.

Aquí hay algunos ejemplos más favoritos que muestran el uso avanzado de propiedades personalizadas:

Uso de propiedades personalizadas para discutir variaciones en animaciones de fotogramas clave

propiedades personalizadas sandrina pereira

El poder (y la diversión) del alcance con propiedades personalizadas de CSS

propiedades personalizadas Jhey Tompkins

Cómo reproducir y pausar animaciones CSS con propiedades personalizadas de CSS

propiedades personalizadas Mads Stoumann

El principio de la cigarra, revisado con variables CSS

propiedades personalizadas Chris Coyier

El initialtruco de los espacios en blanco

Piense en @medialas consultas y en cómo cuando algo cambia (por ejemplo, el ancho de la página) puede controlar varias cosas. Esa es la idea con este truco. Cambias una propiedad personalizada y controlas varias cosas.

El truco es que el valor de initialuna propiedad personalizada activará un respaldo, mientras que un valor de espacio en blanco vacío no lo hará. En aras de la explicación, definamos dos propiedades personalizadas de ámbito global ONy OFF:

:root {  --ON: initial;  --OFF: ;}

Digamos que tenemos una clase de variación "oscura" que establece varias propiedades diferentes. El valor predeterminado es --OFF, pero se puede cambiar a --ONcualquier momento:

.module {  --dark: var(--OFF);}.dark { /* could be a media query or whatever */  --dark: var(--ON);}

Ahora puedes usar --darkpara establecer valores condicionalmente que se aplican solo cuando has cambiado --darka --ON. Manifestación:

Lea Verou tiene un excelente artículo que cubre todo esto.

Estilos en línea

Es totalmente legítimo establecer una propiedad personalizada en HTML con un estilo en línea.

div/div

Como cualquier estilo en línea, tendrá un nivel muy alto de especificidad.

Esto puede ser muy útil cuando el HTML puede tener acceso a información de estilo útil que sería demasiado extraña/difícil de colocar en un archivo CSS estático. Un buen ejemplo de ello es mantener la relación de aspecto de un elemento:

div/div

Ahora puedo configurar algo de CSS para crear un cuadro de ese tamaño exacto donde lo necesite. El artículo completo sobre esto está aquí, pero aquí hay CSS que usa trucos como el viejo cuadro acolchado aplicado a un pseudo elemento que empuja el cuadro al tamaño deseado:

[style*="--aspect-ratio"]  :first-child {  width: 100%;}[style*="--aspect-ratio"]  img {    height: auto;} @supports (--custom: property) {  [style*="--aspect-ratio"] {    position: relative;  }  [style*="--aspect-ratio"]::before {    content: "";    display: block;    padding-bottom: calc(100% / (var(--aspect-ratio)));  }    [style*="--aspect-ratio"]  :first-child {    position: absolute;    top: 0;    left: 0;    height: 100%;  }  }

Pero bueno, hoy en día tenemos una aspect-ratiopropiedad nativa en CSS, por lo que configurarla en el estilo en línea podría tener más sentido en el futuro.

div/div

Hovers y pseudos

No hay forma de aplicar un :hoverestilo (u otras pseudoclases/elementos) con estilos en línea. Es decir, a menos que nos pongamos complicados con las propiedades personalizadas. Digamos que queremos colores personalizados al pasar el cursor sobre algunos cuadros; podemos pasar esa información como algo personalizado

Deja un comentario

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

Subir