¿Cómo los navegadores leen e interpretan CSS?

Pregunta de dos partes:

  1. ¿Los navegadores tienen un intérprete CSS incorporado como lo hacen para JavaScript?
  2. ¿Cuándo exactamente un navegador lee el CSS y cuándo aplica el CSS?

Específicamente, quisiera una aclaración sobre cómo o por qué JavaScript y CSS son diferentes en cuanto a que con JavaScript debe esperar específicamente hasta que windows.onload para que el intérprete pueda obtener getElementById correctamente. Sin embargo, en CSS puede seleccionar y aplicar estilos a las clases y a los identificadores todos astutamente.

(Si incluso importa, supongamos que me refiero a una página HTML básica con una hoja de estilo externa en la cabeza)

Si ha trabajado con una conexión lenta en algún momento reciente, encontrará que CSS se aplicará a los elementos a medida que aparezcan (lentamente), en realidad reorientando el contenido de la página a medida que se carga la estructura DOM. Como CSS no es un lenguaje de progtwigción, no se basa en que los objetos estén disponibles en un momento dado para ser analizados correctamente (JavaScript), y el navegador puede simplemente volver a evaluar la estructura de la página a medida que recupera más HTML por aplicando estilos a nuevos elementos.

Tal vez es por eso que, incluso hoy, el cuello de botella de Mobile Safari no es la conexión 3G en todo momento, sino que es la representación de la página.

La representación de CSS es un tema interesante y todos los competidores están prosperando para acelerar la renderización de la capa de visualización (HTML y CSS) para ofrecer los mejores resultados a los usuarios finales en un abrir y cerrar de ojos.

En primer lugar, sí, diferentes navegadores tienen sus propios motores de análisis / renderizador de CSS

  • Chrome, Opera (del ver 15): utiliza un fork de Webkit llamado motor de renderizado Blink
  • Safari: utiliza Webkit (ahora se mueve a Webkit2)
  • Internet Explorer: utiliza el motor de renderizado Trident
  • Mozilla Firefox – Utiliza Gecko

Todos estos motores de representación contienen tanto el intérprete CSS como el analizador HTML DOM .

Todos estos motores siguen los modelos enumerados a continuación, estos son el conjunto del estándar W3C

  • Modelo de procesamiento visual
  • Modelo de caja
  • Modelo de direccionamiento CSS 2.1

Nota: Todos estos modelos están interrelacionados e interdependientes. No son modelos separados que definen estándares para representar el CSS. Estos modelos arrojan luz sobre cómo se procesa CSS en función de la precedencia, como el estilo en línea, la especificidad, etc.


Explicación:


Nivel 1:


Todos los navegadores descargan el script HTML y CSS del servidor y comienzan analizando tags HTML en nodos DOM en un árbol llamado árbol de contenido .

Mientras que el documento HTML que se está analizando, los motores de representación del navegador construyen otro árbol llamado el árbol Render . Este árbol es de elementos visuales en el orden en que se mostrarán.

Firefox lo llama marcos cuando los chicos de Webkit los llaman objetos Renderer o Renderer.

Ver la imagen de abajo: (Fuente: HTML5 Rocks )

enter image description here


Etapa 2:


Después del proceso anterior, ambos árboles pasan por el proceso de diseño, lo que significa que el navegador le dice a la ventana gráfica dónde debe colocar cada nodo en la pantalla.

Esto se define como el esquema de posicionamiento de W3C (Siga este enlace para obtener información detallada) que instruye al navegador sobre cómo y dónde se colocarán los elementos. A continuación se encuentran los 3 tipos.

  • Flujo normal
  • Flotadores
  • Posición absoluta

Etapa 3:


Ahora la etapa final llamada Pintura . Este es un proceso gradual en el que el motor de renderizado atraviesa cada nodo de árbol de renderizado y los pinta visualmente utilizando la capa de fondo de UI. En este punto, todos los Fx visuales se aplican como tamaño de fuente, color de fondo, pintura de tabla, etc.

Nota: esta etapa se puede observar claramente si intenta abrir cualquier página web con conexión lenta. La mayoría de los buscadores modernos para una mejor experiencia de usuario intentan mostrar elementos lo antes posible. Esto le da al usuario la impresión de que la página se está cargando y debe esperar para completarse.


Diagtwig de bloques del flujo de trabajo para una mejor comprensión

Rocas fuente HTML5

  • Webkit:

enter image description here

  • Gecko de Mozilla: enter image description here

Referencias: (Lea los enlaces a continuación. Son los mejores recursos disponibles en la Web relacionados con este tema)

Sí, los navegadores tienen incorporado un intérprete de CSS. La razón por la que no “esperas hasta que window.onload” se deba a que JavaScript es un lenguaje de progtwigción imperativo de Turing, CSS es simplemente un conjunto de reglas de estilo que el navegador aplica para hacer coincidir elementos que encuentra.

Los navegadores leen líneas de CSS de derecha a izquierda. Eso es lo que dicen tanto Google como Mozilla. Google dice “El motor evalúa cada regla de derecha a izquierda” en http://code.google.com/speed/page-speed/docs/rendering.html . Mozilla dice “El sistema de estilo combina las reglas comenzando con el selector de llave, luego moviéndose hacia la izquierda” en https://developer.mozilla.org/en/Writing_Efficient_CSS

Tomemos como ejemplo esta línea de CSS: ‘.item h4’. El navegador primero busca todas las tags ‘h4’ en la página y luego mira si la etiqueta h4 tiene un padre con el nombre de clase ‘elemento’. Si encuentra uno, aplica la regla de CSS.

Recientemente me topé con este artículo sobre la velocidad de la página de google:

A medida que el navegador analiza HTML, construye un árbol de documento interno que representa todos los elementos que se mostrarán. A continuación, combina los elementos con los estilos especificados en varias hojas de estilo, de acuerdo con las reglas estándar de cascada, herencia y ordenamiento de CSS. En la implementación de Mozilla (y probablemente también en otras), para cada elemento, el motor de CSS busca reglas de estilo para encontrar una coincidencia. El motor evalúa cada regla de derecha a izquierda, comenzando desde el selector situado más a la derecha (llamado “clave”) y moviéndose a través de cada selector hasta que encuentra una coincidencia o descarta la regla. (El “selector” es el elemento de documento al que debe aplicarse la regla).

http://code.google.com/speed/page-speed/docs/rendering.html

Esta es la mejor descripción que encontré sobre cómo el navegador trata con HTML y CSS:

El motor de renderizado comenzará a analizar el documento HTML y convertirá las tags en nodos DOM en un árbol denominado “árbol de contenido”. Analizará los datos de estilo, tanto en archivos CSS externos como en elementos de estilo. La información de estilo junto con las instrucciones visuales en el HTML se usarán para crear otro árbol: el árbol de renderizado.


En general, los trabajos del motor de renderizado son:

  • Tokenize las reglas (rompiendo la entrada en tokens AKA Lexer)
  • Construir el árbol de análisis analizando la estructura del documento de acuerdo con las reglas de syntax del lenguaje

Analizador de CSS

A diferencia de HTML, CSS es una gramática libre de contexto (con una gramática determinista).
Por lo tanto, tendremos la especificación de CSS que define la gramática léxica y syntax de CSS, que el analizador aplica al pasar por la hoja de estilos.

La gramática léxica (vocabulario) se define mediante expresiones regulares para cada token:

 comment \/\*[^*]*\*+([^/*][^*]*\*+)*\/ num [0-9]+|[0-9]*"."[0-9]+ nonascii [\200-\377] nmstart [_a-z]|{nonascii}|{escape} nmchar [_a-z0-9-]|{nonascii}|{escape} name {nmchar}+ ident {nmstart}{nmchar}* 

“ident” es la abreviatura de identificador, como un nombre de clase. “nombre” es una identificación de elemento (que se refiere por “#”)

La gramática de syntax se describe en BNF .

 ruleset : selector [ ',' S* selector ]* '{' S* declaration [ ';' S* declaration ]* '}' S* ; selector : simple_selector [ combinator selector | S+ [ combinator selector ] ] ; simple_selector : element_name [ HASH | class | attrib | pseudo ]* | [ HASH | class | attrib | pseudo ]+ ; class : '.' IDENT ; element_name : IDENT | '*' ; attrib : '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S* [ IDENT | STRING ] S* ] ']' ; pseudo : ':' [ IDENT | FUNCTION S* [IDENT S*] ')' ] ; 

Para obtener una descripción detallada del flujo de trabajo del navegador, eche un vistazo a este artículo .

Creo que el navegador interpreta CSS como lo encuentra, con el efecto de que CSS en el cuerpo (en línea) tiene prioridad sobre CSS (externo también) en la cabeza