Valores calculados: más de lo que parece

Índice
  1. Curso intensivo sobre herencia y cascada.
  2. Encontrar valores calculados en DevTools
  3. Valores y cómo se procesan
  4. Herencia en cálculos de estilo navegador.
  5. Propiedades que heredan por defecto

Las Browser DevTools son indispensables para nosotros, los desarrolladores de aplicaciones para usuario. En este artículo, veremos la pestaña Calculado, una pequeña esquina del panel DevTools que nos muestra cosas importantes, como cómo se resuelven los valores CSS relativos. También veremos cómo encaja la herencia en el proceso de cálculo de estilos del navegador.

El contenido de la pestaña Calculado es importante porque nos muestra los valores que el navegador realmente utiliza en el sitio web representado. Si un elemento no tiene el estilo que cree que debería tener, observar sus valores calculados puede ayudarle a comprender el motivo.

Si está más acostumbrado a utilizar la pestaña Estilos (llamada Reglas en Firefox), es posible que se pregunte en qué se diferencia de la pestaña Calculado. Quiero decir, ambos muestran estilos que se aplican a un elemento. ¿La respuesta? La pestaña Calculado muestra una lista alfabética de estilos resueltos que incluyen lo que se declara en su hoja de estilos, los derivados de la herencia y los valores predeterminados del navegador.

La pestaña Estilos, por otro lado, muestra los conjuntos de reglas exactos de un elemento seleccionado exactamente como fueron escritos. Entonces, si bien la pestaña Estilos puede mostrarle algo como .subhead {font-size: 75%}, la pestaña Calculado le mostrará el tamaño de fuente real o lo que 70%se resuelve actualmente. Por ejemplo, el tamaño de fuente real para el texto renderizado como se muestra arriba es 13.2px.

A continuación, repasemos brevemente los conceptos de herencia y cascada, dos cosas que son una gran parte de cómo se llega a los valores calculados en la pestaña Calculado.

Curso intensivo sobre herencia y cascada.

CSS significa Hojas de estilo en cascada, y es increíblemente importante comprender la primera palabra, cascada: la forma en que se comporta la cascada es clave para comprender CSS.

MDN

La cascada es notable porque es la "C" en CSS. Es el mecanismo utilizado para resolver conflictos que existen entre las diferentes fuentes de declaraciones de estilo de un documento.

Por ejemplo, imagine una hoja de estilo que define el ancho de un div dos veces:

div {  width: 65vw;}
/* Somewhere, further down */div {  width: 85vw;}

En este ejemplo específico, el segundo ancho gana ya que se declara en último lugar. El primer ancho aún podría ganar, !importantpero técnicamente eso es romper la cascada por fuerza bruta. El punto aquí es que el algoritmo en cascada determina qué estilos se aplican a cada elemento y los prioriza en un orden predeterminado para establecer un valor.

La cascada se aplica a propiedades que se establecen explícitamente, ya sea por el navegador, el desarrollador web o el usuario. La herencia entra en escena cuando la salida de la cascada está vacía. Cuando esto sucede, el valor calculado de una propiedad en el elemento principal de un elemento se toma como su propio valor para esa propiedad. Por ejemplo, si especifica un color para un elemento, todos los elementos secundarios heredarán ese color si no especifica el suyo.

Hay cuatro valores de propiedad clave relacionados con la herencia que debemos conocer antes de seguir adelante. Los usaremos a lo largo del artículo.

initial

En un documento HTML donde el nivel más alto del árbol DOM es el htmlelemento, cuando usamos la initialpalabra clave en un elemento como este…

…el color del texto de ese elemento es negro, aunque el bodyelemento esté configurado en green. Está la cuestión de que el divselector tenga una mayor especificidad, sin embargo, nos interesa saber por qué initialse traduce al negro.

En términos sencillos, esta palabra clave establece el valor predeterminado de una propiedad como se especifica en su tabla de definición (en las especificaciones CSS). En este caso, el negro resulta ser la implementación del initialvalor de color por parte del navegador.

Menciono cerca del final del artículo que puede saber si una propiedad se hereda o no de forma predeterminada consultando su página en MDN. Bueno, también puedes encontrar el valor inicial de cualquier propiedad de esta manera.

inherit

Para propiedades no heredadas, esta palabra clave fuerza la herencia. En el siguiente ejemplo, el bodyelemento tiene un borde rojo sólido. La borderpropiedad no se hereda de forma predeterminada, pero podemos decirle a nuestro div que herede el mismo borde rojo declarado en el bodyelemento usando la inheritpalabra clave en su borderpropiedad:

unset

unsetse resolverá en un valor heredado si se hereda una propiedad. De lo contrario, initialse utiliza el valor. Básicamente, esto significa unsetrestablecer una propiedad en función de si se hereda o no. Aquí hay una demostración que alterna unsetpara mostrar su efecto en elementos con diferentes niveles de especificidad.

revert

Si no se establecen propiedades CSS en un elemento, ¿obtiene algún estilo? Puedes apostar. Utiliza los estilos predeterminados del navegador.

Por ejemplo, el valor inicial de la displaypropiedad para elementos span es inline, pero podemos especificarlo como blocken nuestra hoja de estilo. Utilice el botón en la siguiente demostración para alternar revertentre las propiedades y el spanelemento :displaycolor

El intervalo vuelve correctamente a un elemento en línea, ¡pero espera! ¿Notaste que el color del intervalo pasa a ser verde en lugar del valor negro predeterminado del navegador? Eso es porque revertpermite la herencia. Se retrocederá hasta el valor predeterminado del navegador para establecer el color, pero como hemos establecido explícitamente un color verde en el bodyelemento, eso es lo que se hereda.

Encontrar valores calculados en DevTools

Aquí es donde empezamos a hablar de los valores calculados en DevTools. Al igual que con los valores predeterminados de las propiedades, el valor calculado de una propiedad CSS está determinado por la tabla de definición de esa propiedad en las especificaciones CSS. Así es como se ve eso para la heightpropiedad.

Digamos que usamos longitudes relativas en nuestro CSS, como una de 10em o 70% o 5vw. Dado que estos son "relativos" a algo (el tamaño de fuente o la ventana gráfica), deberán resolverse en un valor absoluto de píxeles. Por ejemplo, un elemento con un ancho del 10% puede calcularse a 100 px si la ventana gráfica tiene 1000 px de ancho, pero a algún otro número cuando cambia el ancho de la ventana gráfica.

Estos valores se calculan cada vez que se modifica el DOM en un proceso llamado cálculo de estilos calculados . Esto es lo que le permite al navegador saber qué estilos aplicar a cada elemento de la página.

Los cálculos de estilo se realizan en varios pasos que involucran varios valores. Estos están documentados en la especificación CSS Cascading and Inheritance Level 4 y todos impactan el valor final que vemos en la pestaña Calculado. Echemos un vistazo a los siguientes.

Valores y cómo se procesan

Los valores definidos para el proceso de cálculo de estilo incluyen el valor declarado , el valor especificado, el valor en cascada , el valor calculado , el valor utilizado y el valor real . ¿Quién diría que había tantos, verdad?

Valores declarados

Un valor declarado es cualquier declaración de propiedad que se aplica a un elemento. Un navegador identifica estas declaraciones basándose en algunos criterios, que incluyen:

  • la declaración está en una hoja de estilo que se aplica al documento actual
  • había un selector coincidente en una declaración de estilo
  • la declaración de estilo contiene sintaxis válida (es decir, nombre y valor de propiedad válidos)

Tome el siguiente HTML:

main  pIt's not denial. I'm just selective about the reality I accept./p/main

Aquí se muestran los valores declarados que se aplican al font-sizetexto:

main {  font-size: 1.2em; /* this would apply if the paragraph element wasn't targeted specifically, and even then, as an inherited value, not "declared value" */}
main  p {  font-size: 1.5em; /* declared value */}

Valores en cascada

La lista de todos los valores declarados que se aplican a un elemento tiene prioridad en función de elementos como estos para devolver un valor único:

  • origen de la declaración (¿es del navegador, desarrollador u otra fuente?)
  • si la declaración está marcada o no como '!importante'
  • qué tan específica es una regla (p. ej., span {}vs section span {})
  • Orden de aparición (p. ej., si se aplican varias declaraciones, se utilizará la última)

En otras palabras, el valor en cascada es la declaración "ganadora". Y si la cascada no da como resultado un valor declarado ganador, entonces no hay valor en cascada.

main  p  {  font-size: 1.2em;}
main  .product-description { /* the same paragraph targeted in the previous rule */  font-size: 1.2em; /* cascaded value based on both specificity and document order, ignoring all other considerations such as origin */}

Valores especificados

Como se mencionó anteriormente, es posible que la salida de la cascada esté vacía. Sin embargo, todavía es necesario encontrar un valor por otros medios.

Ahora, digamos que no declaramos un valor para una propiedad específica en un elemento, pero sí para el padre. Eso es algo que a menudo hacemos intencionalmente porque no es necesario establecer el mismo valor en varios lugares. En este caso, se utiliza el valor heredado del padre. Esto se llama valor especificado .

En muchos casos, el valor en cascada también es el valor especificado. Sin embargo, también puede ser un valor heredado si no hay ningún valor en cascada y la propiedad en cuestión se hereda, ya sea de forma predeterminada o mediante la inheritpalabra clave. Si la propiedad no se hereda, entonces el valor especificado es el valor inicial de la propiedad, que, como se mencionó anteriormente, también se puede establecer explícitamente usando la initialpalabra clave.

En resumen, el valor especificado es el valor que pretendemos utilizar en un elemento, con o sin declararlo explícitamente en ese elemento. Esto es un poco turbio porque el valor predeterminado del navegador también puede convertirse en el valor especificado si no se declara nada en la hoja de estilo.

/* Browser default = 16px */
main  p {  /* no declared value for font-size for the paragraph element and all its ancestors */}

Valores calculados

Anteriormente, analizamos brevemente cómo los valores relativos debían resolverse a su equivalente absoluto en píxeles. Este proceso, como ya se señaló, está predeterminado. Por ejemplo, las tablas de definición de propiedades tienen un campo "Valor calculado" que detalla cómo se resuelven los valores especificados, en general.

En el siguiente ejemplo, estamos trabajando con em, una unidad relativa. Aquí, el valor final utilizado al representar el elemento al que se aplica la propiedad no es un número fijo como se ve en nuestro valor declarado, sino algo que debe calcularse en función de algunos factores.

main {  font-size: 1.2em;}
main  p {  font-size: 1.5em; /* declared value */}

El font-sizevalor del elemento de párrafo se establece en 1,5 em, que es relativo al font-sizevalor del mainelemento, 1,2 em. Si main es un hijo directo del elemento body (y no font-sizese hacen declaraciones adicionales encima de eso, como por ejemplo usando el :rootselector), podemos suponer que el cálculo para los párrafos font-sizeseguirá este curso aproximado:

Browser_Default_FontSize = 16px;Calculated_FontSize_For_Main = 1.2 * Browser_Default_FontSize; // 19.2pxCalculated_FontSize_For_Paragraph = 1.5 * Calculated_FontSize_For_Main; // 28.8px

Ese 28,8 px es el valor calculado . Aquí hay una demostración:

Abra DevTools y consulte los tamaños de fuente calculados en la pestaña Calculado.

Digamos que estamos usando remunidades en su lugar:

html {  font-size: 1.2em;}
main {  font-size: 1.5rem;}
div {  font-size: 1.7rem;}

El valor calculado de una remunidad se basa en el font-sizeelemento HTML raíz, lo que significa que el cálculo cambia un poco. En este caso específico, también usamos una unidad relativa en el elemento HTML, por lo que el font-sizevalor predeterminado del navegador se usa para calcular la base font-size que usaremos para resolver todos nuestros remvalores.

Browser_Default_FontSize = 16pxRoot_FontSize = 1.2 * Browser_Default_FontSize; // 19.2pxCalculated_FontSize_For_Main = 1.5 * Root_FontSize; // 28.8pxCalculated_FontSize_For_Div = 1.7 * Root_FontSize; // 32.64px

Abra DevTools nuevamente para esta demostración:

El valor, 16px, para Browser_Default_FontSizees comúnmente utilizado por los navegadores, pero está sujeto a variaciones. Para ver su valor predeterminado actual, seleccione el htmlelemento en DevTools y consulte lo font-sizeque se muestra para él. Tenga en cuenta que si se estableció explícitamente un valor para el elemento raíz, como en nuestro ejemplo, es posible que deba desactivarlo en la pestaña Reglas. A continuación, active la casilla de verificación "Mostrar todo" o "Estilos de navegador" (Firefox) en la pestaña Calculado para ver el valor predeterminado.

Durante la herencia, los valores calculados se transmiten a los elementos secundarios desde sus padres. El proceso de cálculo para esto tiene en cuenta las cuatro palabras clave que controlan la herencia que vimos anteriormente. En general, los valores relativos se vuelven absolutos (es decir, 1rem se convierte en 16px). Aquí también es donde las URL relativas se convierten en rutas absolutas y se resuelven palabras clave como bolder(valor de la propiedad). font-weightPuede ver algunos ejemplos más de esto en acción en los documentos.

Valores usados

El valor utilizado es el resultado final después de realizar todos los cálculos sobre el valor calculado. Aquí todos los valores relativos se vuelven absolutos. Este valor usado es el que se aplicará (provisionalmente) en el diseño de la página. Quizás se pregunte por qué es necesario realizar más cálculos. ¿No se solucionó todo en la etapa anterior cuando los valores especificados se procesaron en valores calculados?

Aquí está la cuestión: algunos valores relativos solo se resolverán en píxeles absolutos en este punto. Por ejemplo, es posible que un ancho especificado por porcentaje necesite un diseño de página para resolverse. Sin embargo, en muchos casos, el valor calculado acaba siendo también el valor utilizado.

Tenga en cuenta que hay casos en los que es posible que no exista un valor utilizado. Según la especificación CSS Cascading and Inheritance Level 4:

…si una propiedad no se aplica a un elemento, no tiene valor usado; entonces, por ejemplo, la flexpropiedad no tiene valor usado en elementos que no son elementos flexibles.

Valores actuales

A veces, un navegador no puede aplicar el valor utilizado inmediatamente y necesita realizar ajustes. Este valor ajustado se llama valor real . Piense en casos en los que es necesario modificar el tamaño de una fuente en función de las fuentes disponibles, o cuando el navegador solo puede usar valores enteros durante la renderización y necesita aproximarse a valores no enteros.

Herencia en cálculos de estilo navegador.

En resumen, la herencia controla qué valor se aplica a un elemento para una propiedad que no está establecida explícitamente. Para las propiedades heredadas, este valor se toma de lo que se calcula en el elemento principal, y para las propiedades no heredadas, se establece el valor inicial de esa propiedad (el valor utilizado cuando initialse especifica la palabra clave).

Anteriormente hablamos de la existencia de un "valor calculado", pero realmente necesitamos aclarar algo. Hablamos de los valores calculados en el sentido de un tipo de valor que participa en el proceso de resolución de estilo, pero "valor calculado" también es un término general para los valores calculados por el navegador para el estilo de la página. Normalmente comprenderá a qué tipo nos referimos cuando hablamos del contexto circundante.

Sólo los valores calculados son accesibles para una propiedad heredada. Un valor absoluto de píxeles como 477 px, un número como 3 o un valor como left (p. ej. text-align: left) están listos para el proceso de herencia. Un valor porcentual como el 85% no lo es. Cuando especificamos valores relativos para propiedades, se debe calcular un valor final (es decir, "usado"). Los valores porcentuales u otros valores relativos se multiplicarán por un tamaño de referencia ( font-sizepor ejemplo) o valor (por ejemplo, el ancho de la ventana gráfica de su dispositivo). Por lo tanto, el valor final de una propiedad puede ser exactamente el que se declaró o puede necesitar un procesamiento adicional para poder utilizarlo.

Puede que ya lo hayas notado o no, pero los valores que se muestran en la pestaña Calculado del navegador no serán necesariamente los valores calculados que analizamos anteriormente (como en los valores calculados frente a los valores especificados o usados). Más bien, los valores mostrados son los mismos que devuelve la getComputedStyle()función. Esta función devuelve un valor que, según la propiedad, será el valor calculado o el valor utilizado.

Ahora, veamos algunos ejemplos.

Herencia de color

main {  color: blue;}/* The color will inherit anyway, but we can be explicit too: */main  p {  color: inherit;}

El valor calculado para la colorpropiedad del elemento principal será azul. Como colorse hereda de forma predeterminada, realmente no necesitábamos color: inheritel elemento secundario del párrafo porque de todos modos terminaría siendo azul. Pero ayuda a ilustrar el punto.

Los valores de color pasan por su propio proceso de resolución para convertirse en valores usados.

Herencia del tamaño de fuente

main {  font-size: 1.2em;}main  p {  /* No styles specified */}

Como vimos anteriormente en la sección sobre valores y cómo se procesan, nuestro valor relativo para font-sizese calculará como un valor absoluto y luego será heredado por el elemento de párrafo, incluso si no lo declaramos explícitamente (nuevamente, font-sizese hereda de forma predeterminada ). ). Si previamente habíamos establecido estilos a través de un selector de elementos de párrafo global, entonces el párrafo puede obtener algunos estilos adicionales en virtud de la cascada. Cualquier valor de propiedad que pueda heredarse lo será, y algunas propiedades para las cuales la cascada y la herencia no produjeron un valor se establecerán en su valor inicial.

Herencia del tamaño de fuente especificada por porcentaje

body {  font-size: 18px;}main {  font-size: 80%;}main  p {  /* No styles specified */}

De manera similar al ejemplo anterior, los mainelementos font-sizese absolutizarán en preparación para la herencia y el párrafo heredará un font-sizevalor que es el 80 % del valor de 18 px del cuerpo, o 14,4 px.

Herencia forzada y cálculo posterior al diseño.

Los valores calculados generalmente resuelven el valor especificado tanto como sea posible sin diseño, pero como se mencionó anteriormente, algunos valores solo se pueden resolver después del diseño, como widthlos valores especificados por porcentaje. Aunque widthno es una propiedad heredada, podemos forzar la herencia con el fin de ilustrar la resolución del estilo previo y posterior al diseño.

Este es un ejemplo artificial, pero lo que estamos haciendo es eliminar un elemento del diseño de la página estableciendo su displaypropiedad en none. Tenemos dos divs en nuestro marcado que heredan un width50% de su elemento principal section. En la pestaña Calculado en DevTools, el cálculo widthpara el primer div es absoluto y se resolvió en un valor de píxel (243,75 px para mí). Por otro lado, el ancho del segundo div que se eliminó del diseño display: nonesigue siendo del 50%.

Imaginemos que el valor especificado y calculado para el sectionelemento principal es 50% (prediseño) y el valor usado es el que se muestra en la pestaña Calculado; eso es 487,5 px para mí, después del diseño. Este valor se reduce a la mitad para que lo hereden los divs secundarios (50% del bloque contenedor).

Estos valores deben calcularse cada vez que cambia el ancho de la ventana gráfica del navegador. Por lo tanto, los valores especificados por porcentaje se convierten en valores calculados por porcentaje, que a su vez se convierten en valores utilizados por píxeles.

Propiedades que heredan por defecto

¿Cómo saber si una propiedad se hereda por defecto o no? Para cada propiedad CSS en los documentos de MDN, hay una sección de especificaciones que proporciona algunos detalles adicionales que incluyen si la propiedad se hereda o no. Así es como se ve eso para la colorpropiedad:

Qué propiedades se heredan de forma predeterminada y cuáles no depende en gran medida del sentido común.

MDN

Otra opción de referencia es la sección de propiedades de las especificaciones del W3C. Otro más es este hilo de StackOverflow que puede no ser exhaustivo al momento de escribir este artículo.

A continuación se muestran algunos ejemplos de propiedades que se heredan de forma predeterminada:

  • color
  • direction
  • font-family
  • font-size
  • font
  • letter-spacing
  • line-height
  • list-style-type
  • tab-size
  • text-align
  • text-justify
  • text-transform
  • visibility
  • word-wrap

Ejemplos de propiedades que no lo hacen (pero que puedes forzar a heredar con la inheritpalabra clave):

  • box-shadow
  • border
  • content
  • height
  • margin
  • object-fit
  • opacity
  • padding
  • position
  • transform
  • transition
  • width
  • z-index

Con suerte, esto le dará una idea sólida de cómo los navegadores calculan los estilos y cómo hacer referencia a ellos en DevTools. Como puede ver, hay muchas cosas que implican un valor detrás de escena. Tener ese contexto le ayudará en gran medida a solucionar problemas en su trabajo, así como a mejorar su comprensión general del maravilloso lenguaje que conocemos como CSS.

Otras lecturas

  • Los valores heredados, iniciales y no establecidos por QuirksMode.org
  • Herencia CSS: Introducción de Asha Laxmi
  • Herencia CSS, cascada y alcance global: sus nuevos, viejos y peores mejores amigos por Heydon Pickering
  • Las últimas formas de abordar la cascada, la herencia y la especificidad por Ollie Williams
  • Cascada y herencia por MDN
  • Herencia por MDN
  • Cascada por MDN
  • CSS en cascada y herencia nivel 4 (especificación W3C)
  • Construcción, diseño y pintura del árbol de renderizado por Ilya Grigorik
  • Window.getComputedStyle() por MDN
  • URL interactiva de Aaron Gustafson
SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Deja un comentario

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

Subir

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion