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, --spacing
está la propiedad personalizada con 1.2rem
el 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?
- 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.
- Son particularmente útiles para cosas como crear temas de color en un sitio web.
- Desbloquean posibilidades interesantes en CSS. En gran parte porque cae en cascada.
- 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
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 background
ninguno 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-shadow
no tiene una propiedad abreviada para controlar la propagación de la sombra por sí sola. Pero podríamos desglosar el box-shadow
valor 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-columns
propiedad 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 24px
aplastando 24
y px
juntando. 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 --background
valor 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 :root
cosa
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 html
o body
cuando 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 !important
modificador 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 !important
a la --color
variable dificulta anular el valor de la --color
variable, pero aún podemos ignorarlo cambiando la color
propiedad.
El comportamiento de !important
los valores internos de las propiedades personalizadas es bastante inusual. Stefan Judis lo documenta bien, pero lo esencial es:
- En última instancia,
!important
se despoja del valor de la propiedad personalizada. - 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 #id
valor ganaría debido a la mayor especificidad, pero en realidad red
ganará debido a !important
, pero finalmente se aplicará sin !important
. Es un poco raro entenderlo.
Si se aplica el !important
exterior de la propiedad personalizada, como en el segundo ejemplo, dos bloques de código arriba, nuestra --border
variable sigue siendo de baja especificidad (fácil de anular), pero es difícil cambiar cómo se aplicará ese valor a border
sí 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.2
valor se utilizará si --scale
no 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 --scale
no 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 @keyframes
y 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 0deg
y 360deg
son valores de ángulo válidos. Tienes que definirlos como un angle
tipo para @property
que 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 initial
truco de los espacios en blanco
Piense en @media
las 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 initial
una 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 ON
y 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 --ON
cualquier momento:
.module { --dark: var(--OFF);}.dark { /* could be a media query or whatever */ --dark: var(--ON);}
Ahora puedes usar --dark
para establecer valores condicionalmente que se aplican solo cuando has cambiado --dark
a --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-ratio
propiedad 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 :hover
estilo (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