¿Qué sucede cuando los radios fronterizos se superponen?
Apostaría a que la mayoría de las veces que redondeamos las esquinas de los cuadros en CSS, aplicamos un valor de radio de borde uniforme a lo largo del borde. Es un bonito toque de brillo en muchos diseños. Pero hay ocasiones en las que es posible que queramos radios diferentes para diferentes esquinas. Fácil, ¿verdad? De esa forma la propiedad toma cuatro valores. Bueno, resulta que en realidad es posible pintarnos en una esquina porque los bordes redondeados son capaces de superponerse entre sí.
Muchos de nosotros conocemos el “truco 999em” común para obtener un rectángulo con “forma de píldora”:
Configuramos border-radius
un número absurdamente grande, como 999em o 999vmax, y en lugar de convertirse en una especie de tira de möbius imposible, al estilo de Escher, las esquinas están muy bien redondeadas para formar un semicírculo. Esto es conveniente porque significa que no tenemos que conocer las dimensiones del rectángulo para lograr este efecto; “simplemente funciona”.
Los orígenes de este truco no me resultan claros, pero encontré un ejemplo temprano en un comentario de David Baron en el blog de Lea Verou.
Pero, como muchos “trucos”, podemos encontrar algún comportamiento extraño en ciertos casos extremos. Por ejemplo, ¿por qué funciona eso cuando esto no funciona?
Queremos que el lado derecho del rectángulo tenga “forma de píldora” y que el lado izquierdo tenga las esquinas redondeadas a 40 px. ¡Pero nuestras esquinas de 40px ya no están! ¿Adónde fueron?
La respuesta es que no fueron a ninguna parte; El navegador acaba de reducir sus valores tan cerca de cero que simplemente parece que han desaparecido.
El navegador se está desviando de alguna manera de los valores que solicitamos, pero ¿cuándo y cómo decidir intervenir? Comprobemos las especificaciones:
Sea f = min(L i /S i ), donde i ∈ {arriba, derecha, abajo, izquierda}, S i es la suma de los dos radios correspondientes de las esquinas en el lado i, y L arriba = L abajo = el ancho de la caja, y L izquierda = L derecha = la altura de la caja. Si f 1, entonces todos los radios de las esquinas se reducen multiplicándolos por f.
¡Ah, eso lo explica! ¡Que tengas un excelente resto de tu semana! :se limpia las manos de manera concluyente:
…Estoy bromeando, por supuesto. Eso requiere un poco de decodificación, así que veamoslo de dos maneras, matemática y geométricamente. Tenga siempre en cuenta que el propósito de esta fórmula es evitar la superposición de radios . De hecho, ¡es por eso que el “truco 999em” funciona en primer lugar!
Esto es lo que quiero decir.
En términos sencillos, el navegador esencialmente piensa: “Reduzca todas las radios proporcionalmente hasta que no haya superposiciones entre ellas”. (Tenga en cuenta que son las radios los que no deben superponerse; los círculos que forman sí pueden superponerse).
Pero una computadora no entiende inglés, entonces lo que hace la fórmula es esto.
Primero, calcule la relación entre la longitud de cada lado del rectángulo y la suma de las radios que lo tocan. Entonces, en nuestro “truco de píldoras” estándar, esto funciona para:
[Width of Side] / [Adjacent Border Radius 1 + Adjacent Border Radius 2]Top: 200px / (400px + 400px) = 0.25Right: 100px / (400px + 400px) = 0.125Bottom: 200px / (400px + 400px) = 0.25Left: 100px / (400px + 400px) = 0.125
Luego multiplica todos los radios por la menor de estas proporciones. La proporción más pequeña es 0,125, por lo que la multiplicaremos por nuestras radios iniciales de 400 px:
400px * 0.125 = 50px
Eso deja todas nuestras radios en 50px. Para un rectángulo cuyos lados más cortos son 100 px, esto nos da una forma de pastilla perfecta. ¡Fresco! Echa un vistazo a la siguiente animación:
(Para que las cosas sean más fáciles de ver, estamos usando 400 px aquí para nuestras radios “absurdamente grandes” en lugar de 999 em; se superpondrán siempre que tengan al menos la mitad de la longitud del lado más corto del rectángulo).
Los círculos que representan las radios que especificamos comienzan con el tamaño solicitado y luego se reducen según la proporción dictada por la fórmula anterior. Lo que es importante tener en cuenta es que todos se reducen en la misma proporción. Quizás sea más intuitivo aquí, ya que de todos los modos todos comienzan con el mismo tamaño.
Ahora volvamos a nuestro ejemplo “roto” con el que empezó todo.
¿Qué está pasando aquí? Probemos con un ejemplo menos extremo para mostrar las radios de los bordes que se ven afectados por esta reducción, pero no hasta el punto de que prácticamente desaparezcan:
Podemos ver allí que no obtenemos las radios de 40 píxeles que solicitamos en las esquinas superior izquierda e inferior izquierda, pero obtenemos algo. Repasemos esa fórmula nuevamente, primero encontrando las razones entre todos los lados y sus radios adyacentes:
Top: 200px / (40px + 400px) = 0.455Right: 100px / (400px + 400px) = 0.125Bottom: 200px / (40px + 400px) = 0.455Left: 100px / (40px + 40px) = 1.25
Nuevamente, nuestra proporción más baja es 0.125, por lo que multiplicamos todos los radios especificados por esa cantidad, lo que nos da radios de 50 px para las esquinas derechas y radios de 5 px para las esquinas izquierdas.
Lo que la fórmula garantiza aquí es que los dos radios grandes en el lado derecho del rectángulo no se superpongan, pero al hacerlo, ha reducido los radios pequeños en el lado izquierdo del rectángulo más de lo que “necesitan” encogerse. para evitar la superposición de radios en los lados superior, inferior e izquierdo.
Aquí hay un ejemplo más rico que muestra lo que sucede en diferentes circunstancias. Juegue con algunos de los valores para ver qué sucede. Nuevamente, los tamaños grandes son las radios que especificamos en el código y los tamaños pequeños son la forma en que el navegador los concilia para evitar la superposición.
¿Por qué los creadores de especificaciones tipo Oz decidirían hacer las cosas de esta manera? ¿Por qué no reducir primero las radios de borde más grandes, en lugar de reducir todas las radios desde el principio?
Por supuesto, no puedo leer sus mentes, pero el beneficio de este enfoque es que los radios mantienen sus proporciones entre sí. Si le dijéramos al navegador que redujera el radio más grande hasta que no hubiera superposición o hasta que fuera igual al segundo radio más grande (lo que ocurriera primero) y repitiera, entonces nuestro “truco de píldora híbrida” habría funcionado; pero hay casos en los que se pueden terminar con cuatro radios iguales cuando el usuario ha pedido tamaños muy diferentes. En otras palabras, la implementación tiene que ser “infiel” a los números de una forma u otra, y esa es la forma que eligieron (sabiamente, creo).
¡Gracias a mis colegas Catherine por notar por primera vez este problema de “radios que desaparecen” y a James por ayudarme a comprender la especificación!
Deja un comentario