Suponer() | Consejos CSS
este hypot() La función toma una lista de valores y devuelve la raíz cuadrada de la suma de sus cuadrados.
.hypotenuse {
width: hypot(30vmin, 40vmin); /* 50vmin */
}
La mayoría de las veces pasamos dos parámetros: hypot(A, B). Piensa en ello como una finalización. Teorema de Pitágoras Le damos a la función los lados opuestos y adyacentes de un triángulo, y el lado más largo es el valor que devuelve.
este hypot() La función está definida en Valores y Unidades CSS Mod Nivel 4 Especificación
sintaxis
hypot(<calc-sum>#)
este hypot() La función toma una lista de cálculos separados por comas (<calc-sum>) debe analizarse como <number>, <dimension>o <percentage>.
argumento
/* Takes dimensions */
width: hypot(30px, 40px); /* 50px */
width: hypot(12rem, 160px)
/* Takes percentages */
width: hypot(60%, 80%);
width: hypot(30px, 10%)
/* Takes numbers */
hypot(9, 12) /* 15 */
hypot(15, 20) /* 25 */
/* Takes negative values */
width: hypot(-50px, 120px); /* 130px */
width: hypot(-90%, -120%); /* 150% */
width: hypot(9, 40); /* 41 */
<calc-sum> es una lista de cálculos separados por comas que se analiza como <number>, <dimension>o <percentage>.
Mezclando <dimension> y <percentage> Los valores están bien siempre que tengan un tipo coherente, p. 25% y 5rem existir width atributo, de lo contrario la función no tiene ningún efecto.
Finalmente, el resultado es hypot() tiene el mismo tipo que sus parámetros, por lo que hypot(<number>, <number>) Devolver un <number>y hypot(<dimension>, <dimension>) Devolver un <dimension>.
Tres formas de ver
Podemos pensar principalmente en tres formas hypot():
1. Cuando estamos aburridos, podemos pensar en hypot() Al igual que su fórmula subyacente, eleva al cuadrado cada parámetro, lo suma y luego extrae la raíz cuadrada del resultado. Ya sabes, como aprendiste en la escuela: “A al cuadrado más B al cuadrado es igual a C al cuadrado.
Esto explica por qué puede tomar valores negativos, ya que cuadran con valores positivos.
2. Sin embargo, hypot() Hay más explicaciones que solo la fórmula. Si se le dan dos valores, hypot(A, B) Devuelve la longitud de la hipotenusa del triángulo rectángulo de lados A y B.
También podemos pensar en los dos parámetros como coordenadas de puntos en el plano XY y no como lados de un triángulo. en este caso, hypot(x, y) Devuelve la longitud desde el origen hasta este punto en el espacio.

3. Es decir, hypot() Se pueden aceptar más de dos parámetros, por lo que ampliamos la última definición más allá de dos dimensiones, p. hypot(a1, a2, ..., an) es la longitud desde un punto en un espacio n-dimensional hasta su origen. Por ejemplo, desde tres dimensiones, hypot(x, y, z) Se parece a esto:

Veremos el uso básico de dos valores para ayudar a ilustrar cómo podemos poner esto en práctica. Además, a CSS no le gustan mucho las dimensiones superiores más allá de 2D.
Uso básico
Empecemos con un ejemplo menos práctico. hypot()solo para mostrar cómo funciona. Imaginemos que queremos proyectar una línea desde un punto de la pantalla hasta la posición del ratón en la ventana.
El primer paso es permitirle a CSS conocer las coordenadas xey del mouse a través del siguiente fragmento de JavaScript, que guarda cada coordenada en --m-x y --m-y variable:
window.addEventListener("pointermove", (event) => {
let x = event.clientX;
let y = event.clientY;
document.documentElement.style.setProperty("--m-x", `${Math.round(x)}px`);
document.documentElement.style.setProperty("--m-y", `${Math.round(y)}px`);
});
A partir de aquí, debemos responder dos preguntas: (1) ¿Qué longitud debería tener esa línea? (2) ¿En qué ángulo debemos girarlo?
donde esta la primera pregunta hypot() entra porque la longitud de la línea es igual a hypot(x, y).
.line {
/* Places line at the top left corner */
position: fixed;
top: 0;
left: 0;
width: hypot(var(--m-x), var(--m-y));
height: 5px; /* Thickness of the line */
}
De esta manera, nuestra línea se hará más larga a medida que el mouse se aleje de la esquina superior izquierda.
Ahora tenemos que girarlo en un ángulo, así que usaremos atan2() Función. Sin entrar en demasiados detalles, atan2(y, x) Nos da el ángulo entre un punto del plano y el eje horizontal.
.line {
/* ... */
transform-origin: left center;
transform: rotate(atan2(var(--m-y), var(--m-x)));
}
Tenga en cuenta que primero y y luego x Ingresar atan2() En lugar de al revés.
Esta línea ahora debería conectarse perfectamente a nuestro mouse.
Si queremos conectar una línea del centro al mouse, primero debemos colocar la línea en el centro:
.line {
position: fixed;
top: 50%;
left: 50%;
/* ... */
}
Luego ajustamos un poco el JavaScript para que nuestras coordenadas también comiencen desde el centro en lugar de desde la esquina superior izquierda. Esto se puede hacer restando la mitad de la ventana gráfica. innerWidth y innerHeight Obtenido de sus respectivas coordenadas antes de pasarlas a CSS.
x = x - window.innerWidth / 2;
y = y - window.innerHeight / 2;
Detectar cuando el cursor se acerca
Ahora que conocemos los conceptos básicos de cómo hacer hypot() Eficaz, podemos utilizarlo para situaciones más prácticas. No hace mucho, Daniel Schwartz escribió :near()un potencial nuevo pseudo-selector que coincidirá con el elemento cuando el cursor esté cerca de una distancia determinada:
button:near(3rem) {
/* Pointer is within 3rem of the button */
}
Esto se puede utilizar para aplicar algún efecto al botón cuando el usuario está cerca de él, como resaltarlo o escalarlo ligeramente. Desafortunadamente, al momento de escribir este artículo, no tenemos :near() en cualquier navegador, pero ya podemos simularlo usando ambos hypot() y consulta de estilo.
Nuevamente, nuestro primer paso es pasar las coordenadas del mouse a CSS a través de JavaScript. Sin embargo, esta vez mediremos la posición del mouse desde el centro del botón. Para hacer esto haremos:
- Resta de cada coordenada del botón.
offsetLeftyoffsetTopque mueve el origen a la esquina superior izquierda del botón. - menos la mitad del botón
clientWidthyclientHeightque mueve el origen hacia la derecha hasta el centro del botón.
const button = document.querySelector("button");
window.addEventListener("pointermove", (event) => {
let x = event.clientX;
let y = event.clientY;
x = x - button.offsetLeft - button.clientWidth / 2;
y = y - button.offsetTop - button.clientHeight / 2;
document.documentElement.style.setProperty("--m-x", `${Math.round(x)}px`);
document.documentElement.style.setProperty("--m-y", `${Math.round(y)}px`);
});
¡De vuelta a CSS! Definamos dos variables: (1) --near Almacene la distancia desde el mouse hasta el botón, y (2) --limit Define las restricciones dentro de las cuales consideramos ratones. cerca botón.
:root {
--near: hypot(var(--m-x), var(--m-y));
--limit: 200px;
}
Todo lo que queda es crear una consulta de estilo que coincida --near menos que --limitlo que significa que nuestro cursor está dentro de los límites.
@container style(--near < var(--limit)) {
button {
scale: 1.025;
box-shadow: #e07a5f 0px 6px 25px 0px;
}
}
Antes de ver los resultados, vale la pena comprobar si su navegador admite consultas de estilo contenedor.
No es sólo azúcar sintáctico
desde hypot() Al devolver la raíz cuadrada de la suma de cuadrados, los mayores nerds de las matemáticas entre nosotros esperarían que las dos expresiones siguientes fueran equivalentes:
hypot(A, B)
sqrt(pow(A, 2) + pow(B, 2))
Sin embargo, si intentamos cambiar el primero por el segundo, encontraremos que la mayoría de las veces no funciona. Estas dos fórmulas no son intercambiables en ningún momento hypot() necesito uno <length> o <percentage>ya que todas las demás funciones exponenciales solo aceptan <number> valores. en otras palabras, Necesitamos que hypot() Si estamos ante un tipo de valor concretoespecialmente <length> y <percentage.
La razón principal detrás de esto son las expectativas contradictorias. como Especificación Diga, si en nuestra hoja de estilo 1rem igual al valor predeterminado 16px, pow(1rem, 2) conducirá a 1rem (16px nuevamente) aunque tengan el mismo valor. al mismo tiempo, pow(16px, 2) resultado 256px. hypot() Las entradas y salidas son siempre consistentes, por lo que no pueden ocurrir resultados inesperados como este.
notas: este La especificación tiene una explicación más larga. Acerca de por qué hypot() Se requieren dimensiones y números.
casos extremos
- Si algún parámetro es
infinityo-infinityentonces el resultado esinfinity. - Si por algún motivo solo desea ingresar un valor, devolverá el mismo valor que un valor positivo.
Especificación
este hypot() La función está definida en Valores y Unidades CSS Mod Nivel 4 Especificación, actualmente en borrador editorial.