Volver al Centro de conocimiento
Huella digital

Colector CSS de CreepJS: estilos calculados

Analiza la recopilación de claves CSSStyleDeclaration en CreepJS, la normalización de alias y las sondas separadas de colores y fuentes del sistema.

BotBrowser Team

Documentación

Quieres la documentación estructurada de Huella digital?

Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.

CreepJS tiene un colector CSS de estilos calculados separado del colector de media queries. El src/css/index.ts fijado crea un inventario de nombres de propiedades, normaliza alias y después lee colores del sistema y fuentes genéricas como valores calculados independientes. BotBrowser documenta ajustes CSS del perfil, pero no afirma implementar este colector de terceros ni predecir su resultado. Una lista de nombres disponibles no es una lista de valores observados ni una identidad de dispositivo.

Flujo del colector CSS de CreepJS: enumera prototipo y claves propias de CSSStyleDeclaration, normaliza alias en un inventario y consulta aparte colores y fuentes del sistema mediante estilos calculados

TL;DR

  • El colector fijado lee nombres disponibles en CSSStyleDeclaration; no calcula el valor de cada propiedad nombrada.
  • Combina nombres del prototipo, claves propias enumerables y alias reconocidos en formato con guiones y camelCase; después elimina duplicados con Set.
  • Los colores del sistema y las palabras clave genéricas de fuente forman sondas de valores separadas mediante getComputedStyle().
  • CreepJS mantiene este módulo separado de las comprobaciones @media y matchMedia() descritas en el análisis de los canales de media queries.

Contenido

Entrada del colector

El código llama a getComputedStyle(document.body) y pasa el CSSStyleDeclaration resultante a computeStyle(). Ese objeto aporta nombres de propiedades disponibles, pero el colector no recorre la lista para guardar el valor calculado de cada propiedad. Si color aparece en keys, eso solo indica que la interfaz expone ese nombre en este entorno; no indica qué color calculó para un elemento.

El colector también obtiene el prototipo de la declaración con Object.getPrototypeOf() y Object.getOwnPropertyNames(). Registra los nombres propios del prototipo como otra entrada del inventario. La guía de fingerprinting CSS cubre la recopilación con media queries y carga de recursos, no el inventario de propiedades de esta declaración.

No es el colector CSS de media queries de CreepJS. Ese otro módulo consulta preferencias mediante un canal de propiedades personalizadas @media y matchMedia(); sus catorce claves emparejadas responden a una pregunta distinta del inventario de propiedades calculadas.

Cómo se crea el inventario de claves

Primero se recorre Object.keys(cssStyleDeclaration). Las claves numéricas se tratan como entradas indexadas: sus valores son nombres de propiedades, así que el colector añade el valor en vez del índice numérico. Las claves no numéricas se añaden salvo que sean nombres de propiedades personalizadas que comiencen por --. También se excluye de esa ruta indexada un valor que parezca un token de propiedad personalizada.

CSS ofrece muchas propiedades tanto con guiones como en camelCase. Por ejemplo, existen formas como background-color y backgroundColor. El colector comprueba con el operador in si existe la forma contraparte y la marca para que las dos escrituras no se traten como observaciones independientes. También contempla un prefijo inicial al reducir un nombre para buscar su contraparte.

La lista final combina nombres del prototipo, nombres propios enumerables y nombres inferidos mediante las comprobaciones de contraparte. Un Set elimina duplicados. Por eso, el conteo mostrado describe el inventario de claves combinado para el entorno activo. No es un número estable entre versiones y no implica que cada nombre aporte un valor calculado único.

EntradaQué toma el códigoQué significa la entrada resultante
PrototipoObject.getOwnPropertyNames(proto)Nombre declarado en el prototipo de la declaración
Claves propiasObject.keys(cssStyleDeclaration)Clave propia enumerable; las entradas indexadas se convierten en nombres
Alias contraparteComprobaciones in entre formas con guiones y camelCaseRelación entre escrituras para evitar contar alias como propiedades distintas
Inventario finalnew Set([...])Lista de nombres deduplicada, no un mapa de valores

La fuente fijada del colector CSS es la autoridad para estos pasos. La referencia estándar de CSSStyleDeclaration da contexto sobre el objeto; no afirma que todos los navegadores enumeren los mismos nombres.

El colector puede revisarse como una canalización pequeña. La primera etapa elige getComputedStyle(document.body) y el prototipo de CSSStyleDeclaration. La segunda crea nombres desde el prototipo y las claves propias, incluidos los alias. La tercera consulta por separado al navegador para resolver colores del sistema y fuentes genéricas. Las etapas tienen entradas y formas de salida distintas; no conviene aplanarlas en un único campo llamado «huella CSS».

EtapaOperación de origenForma de salidaPregunta útil
Elegir declaracióngetComputedStyle(document.body)Objeto de declaración del body¿Qué elemento y documento lo produjeron?
Enumerar nombresNombres del prototipo y Object.keys()Array keys deduplicado¿Cambió el conjunto de nombres disponibles?
Resolver coloresasignar palabra clave y leer backgroundColorResultado por palabra clave en system.colors¿Cambió un color del sistema resuelto?
Resolver fuentesasignar font genérico y leer tamaño/familiaCadena con tamaño y familia en system.fonts¿Cambió la resolución del shorthand de fuente?

Esta separación tiene una consecuencia práctica al comparar versiones del navegador. Si cambia keys, la primera pregunta es si cambió el conjunto de nombres expuestos, no si cambió el color renderizado. Un alias nuevo puede afectar al array previo a la deduplicación; una posición distinta en el prototipo puede alterar una entrada; y Set puede ocultar grafías duplicadas. El inventario puede seguir igual mientras cambia un color calculado, ya que se guarda en system.colors.

Conserva la jerarquía del informe. El objeto CSS contiene el resultado de estilos calculados y el de estilos del sistema; la interfaz añade un hash breve y un conteo. Ese conteo es un resumen con pérdida: no conserva qué nombres estaban presentes ni qué devolvieron las sondas. Para comparar, guarda los objetos completos en vez de transcribir solo el conteo.

Inspecciona una página propia sin inventar una base

En una página que controlas, esta captura de consola conserva separadas las categorías. Es una ayuda de lectura, no una réplica de todos los helpers de CreepJS ni una afirmación sobre lo que usa otro servicio:

const declaration = getComputedStyle(document.body);
const prototype = Object.getPrototypeOf(declaration);
const ownNames = Object.keys(declaration).map(key => {
  const numeric = !Number.isNaN(Number(key));
  return numeric ? declaration[key] : key;
});
const prototypeNames = Object.getOwnPropertyNames(prototype);
const inventory = [...new Set([...prototypeNames, ...ownNames])];
const selectedValues = Object.fromEntries(
  ['color', 'background-color', 'font-family', 'font-size'].map(name => [name, declaration.getPropertyValue(name)])
);
console.log({ inventory, selectedValues });

El ejemplo llama selectedValues a la muestra de valores; no afirma replicar la lógica completa de alias. Tampoco sustituye las sondas CreepJS de colores y fuentes del sistema. En el código fijado, esas sondas crean o reutilizan un elemento, asignan una palabra clave al estilo en línea, llaman a getComputedStyle() y leen un campo resuelto concreto. Registra el elemento observado y si se modificó antes de interpretar el valor.

Para comparar capturas, conserva por separado la versión del navegador, origen de la página, elemento elegido, hora y objeto exacto. Después compara la lista de nombres independientemente de los valores. No ordenes ni normalices el objeto original antes de guardarlo, porque podrías borrar detalles de representación. Se puede crear una vista normalizada derivada si también se conserva el original.

Un valor ausente merece su propio estado. Una propiedad puede no estar soportada, una consulta puede devolver cadena vacía o el colector puede fallar antes de crear el objeto esperado. No son resultados equivalentes. La API CSSOM define acceso y cálculo de estilos, pero el registro debe señalar si el campo falta, está vacío o tiene contenido. Así no se transforma una observación ausente en un negativo medido.

La normalización de alias tiene límites

Las comprobaciones de contraparte del código son una regla de deduplicación, no una prueba de que todas las escrituras CSS sean intercambiables en cualquier contexto. Deriva una contraparte para nombres con guiones, considera un marcador de prefijo inicial y también deriva una forma con guiones desde mayúsculas. Si la contraparte existe en el objeto, el código la marca en propertiesInPrototypeChain; después incluye los nombres marcados antes de eliminar duplicados exactos con Set.

Hay dos preguntas distintas al comparar salidas: si este colector reconoce dos cadenas como alias y si leer ambas formas en un elemento da el mismo resultado. El código responde a la primera al crear un inventario. No guarda una comparación de valores para cada pareja. No infieras una prueba de equivalencia de valores porque ambas formas se normalizaran durante la enumeración.

Las propiedades personalizadas también reciben un tratamiento distinto. Los nombres que coinciden con --... no se añaden por la rama ordinaria, y se excluyen ciertos valores parecidos a tokens de propiedades personalizadas de la ruta indexada. Es una decisión de filtrado propia de esta fuente. No demuestra que CSS no pueda leer una propiedad personalizada mediante getPropertyValue(); keys no es un volcado completo de declaraciones ni de hojas de estilo.

Cambio observadoPrimera zona que revisarEvita concluir
Cambia el conteo keys, pero permanecen nombres comunesContrapartes de alias y enumeración del prototipoQue cambió un valor de estilo en la misma proporción
Aparece otra forma con guiones o camelCaseTransformación del nombre y comprobación inQue se midieron valores de ambas formas
Cambia system.colorsAsignación de palabra clave y backgroundColor calculadoQue la causa única fue el tema del sistema
Cambia system.fontsAsignación de font genérico y tamaño/familia resueltosQue se enumeraron todas las fuentes instaladas
El informe CSS falta o está incompletoCaptura de errores y ruta de renderizadoQue el navegador devolvió inventario vacío

La tabla es un mapa de triaje derivado de la implementación fijada. Indica de dónde obtiene cada clase de salida; no diagnostica una diferencia concreta sin objetos originales y metadatos del entorno.

Colores y fuentes del sistema son sondas separadas

getSystemStyles() hace dos grupos de llamadas. Para colores como Canvas, CanvasText, ButtonFace y Highlight, asigna background-color al elemento temporal y lee getComputedStyle(el).backgroundColor. Para palabras clave genéricas de fuente como caption, icon, menu, message-box, small-caption y status-bar, establece el shorthand font y guarda fontSize y fontFamily calculados.

Son observaciones de valores, a diferencia del inventario keys. También son distintas de un parser de colores: el colector pide al navegador que resuelva palabras clave del sistema y almacena la cadena de color resultante. La referencia de colores de sistema CSS explica esa categoría, y getComputedStyle() describe la API usada para leer estilos resueltos.

Sin elemento suministrado, el código crea un div, lo añade a document.body, obtiene estilos y lo elimina. Si se pasa un elemento, usa ese elemento. La función captura errores y no devuelve el resultado de estilos cuando falla, después de notificarlo mediante la ruta de errores de CreepJS. Por tanto, un resultado ausente no equivale a una lista vacía medida.

Las listas fijas también delimitan lo que no se intenta medir. La lista de colores incluye Canvas, CanvasText, Field, FieldText, Highlight y WindowText; la de fuentes contiene palabras clave genéricas, no un catálogo de todas las familias instaladas. El resultado responde cómo resolvió el navegador esas palabras clave en el elemento elegido, no qué fuentes hay instaladas ni qué preferencia informó matchMedia().

El código establece cada color como background-color: <keyword> !important y lee el fondo resuelto. Establece cada fuente con el shorthand font y combina el tamaño y familia resueltos en una cadena. Esas elecciones definen la superficie medida. Un registro comparativo debe conservar tanto la palabra clave como el nombre del campo y la cadena devuelta; de otro modo, CanvasText → rgb(...) podría confundirse con una lectura directa del color de texto de una página arbitraria.

El estado temporal del DOM también importa. La ruta predeterminada añade su propio div al body, lee los estilos y lo quita. Eso no es lo mismo que leer un elemento de aplicación que tenga clases, estilos heredados o declaraciones en línea. La fuente deja explícito el elemento usado; una reproducción no debería cambiarlo en silencio y atribuir luego la diferencia al navegador.

Lo que no revela una lista de claves

Un inventario de propiedades no demuestra que una página haya usado una propiedad, que se devolviera un valor concreto ni que un detector remoto consumiera el informe. La fuente permite ver qué nombres registra y qué valores de colores y fuentes solicita. Por sí sola no identifica hardware, sistema operativo ni persona. La presencia de un nombre es una observación de interfaz; interpretarla exige contexto de versión, documento y valores reales.

BotBrowser documenta ajustes CSS del perfil en la referencia de coherencia de señales CSS, pero sus ajustes no reproducen este colector CreepJS y BotBrowser no garantiza su resultado. Mantén separadas las capacidades del producto y las afirmaciones sobre CreepJS.

Preguntas frecuentes

¿keys contiene todos los valores CSS calculados?

No. Contiene nombres reunidos de las claves y alias de la declaración. El código mostrado solicita por separado solo los valores de colores y fuentes del sistema mediante getSystemStyles().

¿Por qué inspecciona el objeto y su prototipo?

La fuente trata las claves propias enumerables y los nombres propios del prototipo como entradas diferentes y luego las combina. Eso expone la normalización del colector; no significa que cada origen sea una medición distinta del navegador.

¿Es la misma señal que matchMedia()?

No. src/css/index.ts lee nombres de declaraciones y estilos del sistema. src/cssmedia/index.ts consulta preferencias por reglas CSS y matchMedia(). Que ambos lleven la etiqueta CSS no los convierte en el mismo colector.

¿La lista identifica un dispositivo?

No. Los nombres describen una superficie de API y los resultados de estilos son valores resueltos por el navegador. Ninguno establece por sí solo un dispositivo físico o una identidad única.

Fuentes

Conclusión práctica

Lee el informe CSS de CreepJS como dos clases de datos: un inventario combinado de nombres y valores calculados separados para colores y fuentes del sistema. Al comparar informes, conserva esas categorías por separado, fija la revisión de la fuente y registra el objeto real en vez de inferirlo del conteo. El artículo sobre los canales CSS de media queries cubre las preferencias; el análisis de las tablas de fuentes de CreepJS describe otro campo del informe, no los valores de fuentes CSS del sistema.

#CreepJS#CSSStyleDeclaration#Estilo Calculado#fingerprinting#Privacidad

Este artículo forma parte de la guía: ¿Qué es la huella digital del navegador?

Ejecuta la misma comprobación en BotBrowser

Carga un perfil, mantén dentro del navegador las señales que acabas de leer y confirma el resultado en tu propia máquina antes del despliegue.