@Función | Consejos CSS
este @function at-rule define funciones personalizadas de CSS. Estas funciones personalizadas son bloques CSS reutilizables que aceptan parámetros, contienen lógica compleja y devuelven un valor basado en esa lógica. Esta característica es esencialmente similar a una versión más dinámica de Propiedades personalizadas (variables CSS).
notas: hay otro @function La regla at en Sass tiene un propósito similar, pero Diferentes funciones a CSS nativo @function. Tenga en cuenta esto si Sass es parte de su pila o cuando busque recursos, ya que es fácil confundir uno con el otro.
sintaxis
este @function at-rule utiliza la siguiente sintaxis para definir funciones personalizadas:
@function --function-name(<function-parameter>#?) (returns <css-type>)? {
<declaration-rule-list>
}
<function-parameter> = <custom-property-name> <css-type>? ( : <default-value> )?
En otras palabras, definimos el nombre de la función para que se identifique con un guión (--my-function), proporciona algunas condiciones que queremos cumplir (<function-parameter>), y decir qué tipo de cosas queremos devolver, digamos CSS(<length>) valor. Y, si esa condición coincide, aplicamos el estilo (<declaration-rule-list>).
Echemos un vistazo más de cerca a lo que realmente significan estas cosas.
Parámetros y descriptores
La gramática se compone de varias partes. @function Manejar diferentes partes de la función. Puede parecer muy complicado (y lo es), pero quedará más claro más adelante cuando veamos algunos ejemplos.
--function-token
Identificador definido por el usuario, debe comenzar con dos guiones (--),similar dashed-ident Propiedades personalizadas. Al igual que las propiedades personalizadas, los nombres distinguen entre mayúsculas y minúsculas. Por ejemplo, --conversion y --Conversion Se hará referencia a diferentes definiciones de funciones personalizadas.
@function --progression()
<function-parameter> (Electivo)
Una lista opcional de entradas separadas por comas que puede incluir:
--param-name: El nombre del parámetro (debe terminar con--).<css-type>(Electivo): palabra clave o tipo (por ejemplo,<length>,<color>) le dice a la función qué tipo de entrada o resultado devolver cuando encuentra una condición coincidente.<default-value>(Electivo): Si el resultado no es válido (como un argumento omitido durante una llamada a una función), se devuelve un valor alternativo. Si proporciona un valor predeterminado, debe ser válido para lo anterior<css-type>(Por ejemplo<length>Debe establecerse en una longitud CSS válida). Está separado del resto de la definición del parámetro por dos puntos (:).returns <css-type>(Electivo): Define el tipo de salida esperado de la función. Esto ayuda al navegador a validar la lógica antes de renderizar. Si no se especifica ningún tipo, cualquier cosa será válida (por ejemplo, escribirreturns type(*)).<declaration-rule-list>: Construya declaraciones CSS y reglas para cuerpos de funciones y lógica. Puede incluir atributos personalizados yresultDescriptor: ubicado en la raíz o anidado dentro de una regla at.
@function --progression(--current <number>, --total <number>) returns <percentage> {
result:
}
este result Un descriptor que define lo que devolverá la función personalizada. Si la función personalizada se da por vencida result descriptor, siempre volverá guaranteed-invalid valorcomo una propiedad personalizada rota.
@function --progression(--current <number>, --total <number>) returns <percentage> {}
Uso básico
Como ejemplo de la función más básica que puede crear, tenemos una función que calcula un valor proporcionado (p. ej. 20px) reducido a la mitad (p. ej. 10px), y lo devuelve como una unidad de longitud (p. ej. px):
@function --half(--size <length>) {
result: calc(var(--size) / 2);
}
Aquí, “nombramos” nuestra función a través de la configuración. function-token llegar --half. Entonces estamos creando un function-parameter llamado --sizey establecer css-type llegar <length>de modo que solo acepta valores de longitud. El descriptor de resultado se establece en calc(--size / 2)que utiliza Función de cálculo CSS Reducir a la mitad el valor derivado de size function-parameter.
Luego usamos la función así:
.container {
margin-inline: --half(20px); /* This will resolve to 10px */
}
verificación de tipos
Al igual que cuando escribimos JavaScript u otros lenguajes, a veces queremos asegurarnos de que una función solo acepte ciertos parámetros. Por ejemplo, ¿qué sucede si queremos asegurarnos de que solo se puedan ingresar números y solo se puedan generar porcentajes?
@function --progression(--current <number>, --total <number>) returns <percentage> {
result: calc(var(--current) / var(--total) * 100%);
}
.progress-bar {
width: --progression(3, 5); /* Evaluates to 60% */
}
este <css-type> Encerrado entre corchetes angulares de la misma manera que verificaría una propiedad personalizada con @property. Si el parámetro no coincide con el tipo declarado (p. ej. <color>), la llamada a la función deja de ser válida, lo cual es muy valioso para detectar errores tempranamente en bases de código grandes.
puedes usar <syntax-combinator> Permitir múltiples tipos envolviendo el tipo en type() y usar | como separador. Por ejemplo, --alpha Ambos están permitidos aquí. <number> y <percentage>:
@function --transparent(--color <color>, --alpha type(<number> | <percentage>));
lista separada por comas
CSS usa comas para separar las entradas de funciones personalizadas, lo que plantea una pregunta: ¿Qué sucede si desea proporcionar una lista de valores? Para proporcionar una lista de valores como una entrada en lugar de varias entradas separadas, primero debe marcar la función como que requiere una lista.
Para esto necesitas agregar el sufijo # personaje <css-type>. Al llamar a una función, puede incluir una lista de valores entre llaves, lo que le indica al navegador que trate todo lo que está dentro de las llaves como un único parámetro.
Por ejemplo:
/* Calculates the distance between the highest and lowest values in a list, plus another input */
@function --get-range(--list <length>#, --n <length>) {
result: calc(max(var(--list)) - min(var(--list)) + var(--n));
}
div {
/* Finds the difference between 10px and 100px, then adds 200px */
padding-block: --get-range({10px, 100px, 50px, 25px}, 200px); /* 290px */
}
Construcción y cascada CSS
este result Los descriptores siguen las reglas de CSS Cascade. Esto significa que puede declarar varios valores de resultados y el último valor coincidente válido ganará, como cualquier otra propiedad. Por lo tanto, la regla del grupo de condiciones (@media, @container, @supports) y otras funciones como if()ofreciendo muchas posibilidades adicionales.
En este caso devolvemos un --suitable-font-size El valor predeterminado es 16px Cuando la pantalla es más pequeña que 1000px píxeles. Si la pantalla es más grande que 1000px Entonces el estilo “ganador” es @media obstruido.
@function --suitable-font-size() returns <length> {
result: 16px;
@media (width > 1000px) {
result: 20px;
}
}
body {
font-size: --suitable-font-size();
}
Recuerda que el último valor definido siempre gana, por lo que si escribieras el siguiente ejemplo, el resultado sería siempre Sí 16pxindependientemente de si se activa la consulta de medios.
@function --suitable-font-size() returns <length> {
@media (width > 1000px) {
result: 20px;
}
result: 16px;
}
Respetar la cascada establecida también permite utilizar propiedades personalizadas en las funciones. Estas propiedades personalizadas tienen un alcance local, por lo que solo se puede acceder a ellas dentro de su función personalizada y cualquier función personalizada que haga referencia a ella, por lo que no pueden filtrarse accidentalmente al alcance global e interactuar con el resto del CSS.
@function --spacing-scale(--multiplier) {
--base-unit: 8px;
result: calc(var(--base-unit) * var(--multiplier));
}
También puedes usar otro Una función personalizada dentro de una función personalizada es esencialmente una función anidada dentro de otra función. Esto permite un código muy limpio donde cada parte solo realiza un trabajo y la funcionalidad se puede reutilizar ampliamente.
@function --square(--n) {
result: calc(var(--n) * var(--n));
}
@function --circle-area(--radius) {
--pi: 3.14159;
result: calc(var(--pi) * --square(var(--radius)));
}
.blob {
width: calc(--circle-area(10) * 1px); /* 314.159px */
}
valor predeterminado
Las funciones pueden manejar múltiples parámetros y proporcionar valores preestablecidos. Los valores predeterminados se definen incluyéndolos al final de los parámetros de la función, separados por dos puntos (:).
/* Define the function */
@function --brand-glass(--opacity <number>: 0.5) returns <color> {
result: rgb(10 120 255 / var(--opacity));
}
/* Use the function */
.header {
background: --brand-glass(); /* Defaults to 0.5 */
}
.header:hover {
background: --brand-glass(0.8); /* Overrides to 0.8 */
}
Sin efectos secundarios
un CSS @function Sólo se puede devolver un valor; no puede hacer nada más. Por ejemplo, no puede cambiar propiedades dentro de una función ni usar una función para realizar múltiples declaraciones. Para esta habilidad uno debe buscar consejo. @mixin reglaproporcionará funcionalidad de esta manera, permitiendo propiedades CSS de varias líneas y otra lógica compleja.
dependencia circular
CSS es muy estricto con la lógica circular. Si la función A llama a la función B y la función B llama a la función A, el navegador detectará esta dependencia circular e inmediatamente marcará ambas como no válidas.
Esto también se aplica a las propiedades personalizadas de CSS y a las referencias a la función personalizada en sí. Si una función se basa en una propiedad personalizada o una función que a su vez es calculada por la misma función, el navegador finalizará el cálculo para evitar la recursividad infinita.
Especificación
este @function La regla en se define en Módulo de funciones personalizadas y mixins de CSS Nivel 1 Especificación.
Soporte del navegador
Los navegadores que no lo admitan lo ignorarán. @functionpor lo que las declaraciones alternativas y las estrategias de mejora progresiva pueden resultar ventajosas. puedes usar @supports comprobar si @function El soporte del navegador del usuario es el siguiente:
@supports (at-rule(@function)) {
/* ... */
}
Irónicamente, al momento de escribir este artículo, @supports La función de evaluación de reglas at no es totalmente compatible con varios navegadores (Cromo 148+ solamente), por lo que debes verificar si tu situación lo admite. Puedes ver la discusión sobre esto. Borrador de CSS número 2463.