Logotipo de Bitdoze

Revisión de Modern Web Guidance: ejecuté la skill de agente de los navegadores en mi blog Astro

Revisión práctica de Modern Web Guidance, la skill de agente publicada por Chrome, Firefox y Edge: instalación, auditoría con legacy-scan, los 5 hallazgos reales en mi blog Astro y las correcciones aplicadas.

Dragos

lleva unos 10 min

Probado en: Linux · Node.js 24.17 · Astro 7.4 · modern-web-guidance 1.0

Portada de la revisión de Modern Web Guidance con un icono de lupa

Resultado rápido

npx modern-web-guidance@latest install → Installed 1 skill → .agents/skills/modern-web-guidance

Los agentes de código escriben frontend rápido, pero rápido no es lo mismo que actual. Pídele a Claude Code o a Cursor un modal y todavía puedes recibir un <div> con JavaScript de click-outside donde la plataforma lleva años teniendo <dialog>. Pídele un estilo de scrollbar y te devuelve reglas ::-webkit-scrollbar que ignoran Firefox y las propiedades estándar por completo.

El 10 de noviembre, Chrome, Firefox, Edge y MDN publicaron Modern Web Guidance 1.0. Es una skill de agente gratuita que inyecta más de 200 guías de plataforma web revisadas por expertos, con datos de compatibilidad Baseline integrados, directamente en el agente de código que uses. Ese mismo día llegó a la portada de Hacker News.

La instalé y ejecuté su escaneo de modernización contra el código de este mismo sitio. Esto es lo que hace realmente el comando, lo que encontró en bitdoze.com y lo que cambié por ello.

Qué es realmente Modern Web Guidance

A pesar del nombre, no es una app, ni un linter, ni una extensión de VS Code. Es una skill de agente: una carpeta de guías en markdown más una CLI pequeña que tu agente de código consulta cuando toca HTML, CSS o JavaScript del lado del cliente. El instalador detectó mi agente y la soltó en .agents/skills/modern-web-guidance/ sin pedir nada, que es el mismo formato de directorio que usan otras skills de agente.

Tres cosas la diferencian de “un prompt más”:

  • Recomendaciones conscientes de Baseline. Cada guía lleva datos de compatibilidad con navegadores, así que puede decirle a tu agente si una función es segura de usar sin prefijos o necesita fallback, en lugar de adivinar a partir de datos de entrenamiento siempre desactualizados.
  • Un modo de auditoría determinista. legacy-scan revisa estáticamente tu código existente buscando patrones legacy conocidos, con independencia del juicio de cualquier modelo.
  • Mantenimiento por los fabricantes. Las guías las revisan ingenieros de navegadores y especialistas en accesibilidad, y el corpus se actualiza con la plataforma. En su panel de evaluaciones público, los agentes pasaron del 55% al 92% de aciertos en 200 tareas de plataforma web cuando la skill estaba presente.

El repositorio está en github.com/GoogleChrome/modern-web-guidance y la documentación cubre la instalación para todos los agentes principales.

Instalación: lo que hace realmente el comando

bash
npx modern-web-guidance@latest install

Ejecutado desde la raíz del proyecto, el instalador clona el repo de guías, inventaria las skills que contiene (encontró 2 y yo seleccioné modern-web-guidance), ejecuta evaluaciones de seguridad de terceros sobre ellas (la salida mostró Gen “Safe”, Socket “1 alert”, Snyk “Low Risk”) y copia la skill al directorio de skills de tu agente. En mi máquina quedó así:

text
✓ modern-web-guidance (copied)
  → ~/projects/bitdoze.com/.agents/skills/modern-web-guidance

Dos detalles prácticos de la propia salida de instalación:

  • Recopila telemetría de uso anónima por defecto. Si te molesta, desactívala con DISABLE_TELEMETRY=1 en tu perfil de shell.
  • Al ser una skill y no una dependencia, no añade paquetes a package.json ni nada a tu build. Borra la carpeta y desaparece.

legacy-scan: auditar un código existente

Para un proyecto existente, que son casi todos, el comando relevante es el escaneo de modernización:

bash
npx modern-web-guidance@latest legacy-scan src --json

Lo apunté a src/. La salida JSON reportó totalFindings: 5 repartidos en 4 guías, y terminaba con una advertencia honesta que vale la pena citar:

json
"activeRuleCount": 35,
"activeGuideCount": 33,
"note": "Checked 33 guides (35 deterministic rules; ~20% of the guidance corpus).
        Finding 5 items here only reflects deterministic legacy patterns;
        use 'search <topic>' for the rest of the catalog."

O sea que legacy-scan es una alarma de humo, no una inspección completa. Solo cubre el ~20% de las guías que tienen reglas deterministas. El otro 80% (patrones de accesibilidad, comportamientos de UX, prácticas de seguridad) se alcanza con search/retrieve, que el agente invoca bajo demanda mientras escribe código.

Salida de terminal de modern-web-guidance legacy-scan sobre el código de bitdoze.com: 5 hallazgos en 4 guías

Lo que encontró en bitdoze.com

Cinco hallazgos. Verifiqué cada uno contra la rúbrica keep/drop de su guía antes de escribir esto. Dos necesitaron una segunda mirada: uno ya estaba parcialmente mitigado y otro resultó ser código muerto. Ese es el tipo de matiz que cabe esperar de cualquier escáner.

1. Pseudo-elementos de scrollbar de vendor, src/styles/global.css:314-326

La hoja de estilos personalizaba el scrollbar de las tablas del artículo con pseudo-elementos exclusivos de WebKit:

css
.prose .table-scroll::-webkit-scrollbar {
  height: 6px;
}
.prose .table-scroll::-webkit-scrollbar-thumb {
  background-color: var(--color-border-base);
  border-radius: 3px;
}

::-webkit-scrollbar no hace nada en Firefox, así que los usuarios de Firefox veían el scrollbar por defecto en las tablas con scroll horizontal mientras Chrome y Safari veían el fino personalizado. La solución de la guía es el par estándar, scrollbar-width y scrollbar-color en el contenedor, manteniendo las reglas WebKit como fallback dentro de @supports not (scrollbar-color: auto). El matiz que añade la guía: scrollbar-color solo alcanzó Baseline en diciembre de 2025 (Safari 26.2), así que borrar las reglas WebKit sin más sería una regresión en Safari antiguos. “Moderno” aquí significa estándar primero, fallback de vendor después, no código de vendor eliminado.

2. El toggle de modo oscuro no sincronizaba <meta name="color-scheme">, src/layouts/Layout.astro:121

El bootstrap de tema alternaba una clase .dark en <html> y guardaba la elección en localStorage:

js
const isDark = stored === "dark" || (!stored && prefersDark);
root.classList.toggle("dark", isDark);
root.style.colorScheme = isDark ? "dark" : "light";

El escáner marcó la ausencia de actualización del <meta name="color-scheme">. Para ser justos con el código existente: la asignación inline de style.colorScheme sí propagaba el esquema a la UI nativa como scrollbars y controles de formulario, así que era una mitigación parcial, no un bug. Donde el modelo de la guía sigue siendo mejor: lo alimenta todo desde el meta, lo que hace correctos también los colores light-dark() y la ruta de primer pintado para la UI nativa.

3. CSS de animación escalonada muerto, src/components/views/ResourcesView.astro:117-150

La hoja de estilos definía un keyframe fadeIn, una clase .animate-fade-in y seis reglas :nth-child que escalonaban animation-delay de 0.1s a 0.6s, justo el patrón que sibling-index() colapsaría en calc(sibling-index() * 0.1s). Pero aquí es donde importa la verificación: ningún elemento de la página llevaba realmente animate-fade-in. Los hijos del grid eran simples <div class="h-full"> envolviendo ResourceCard, y una búsqueda en todo el repo encontraba la clase definida solo ahí. Todo el bloque, keyframes incluidos, era CSS muerto, probablemente heredado de una refactorización.

Así que la solución sugerida por el escáner era técnicamente correcta y prácticamente errónea. Modernizar código muerto sigue siendo código muerto. La solución real era borrar el bloque, o, si el fundido escalonado era el diseño previsto, devolver animate-fade-in a las tarjetas y entonces usar sibling-index(), que además hace que las parrillas de cualquier tamaño escalonen bien en vez de parar en seis elementos.

4. <div role="progressbar"> a medida, src/components/courses/CourseSidebar.astro:40-54

La barra lateral del curso construía su pista de progreso con dos divs:

html
<div class="h-1.5 w-24 overflow-hidden rounded-full bg-gray-200 ..."
     role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"
     data-progress-track>
  <div data-progress-fill class="h-full rounded-full bg-blue-600 ..." style="width: 0%">

Un <progress value max> nativo te da lo mismo visualmente con la semántica de accesibilidad integrada. Los lectores de pantalla lo anuncian sin el andamiaje ARIA. La trampa de estilos que advierte la guía: al pasar de accent-color, hay que poner appearance: none y apuntar a ::-webkit-progress-value y ::-moz-progress-bar, y no se pueden agrupar esos dos pseudo-elementos en una misma regla, porque la regla entera se descarta por inválida. Ese es el tipo de detalle que separa una guía escrita por gente que ha publicado motores de navegador de los consejos genéricos de un LLM.

search y retrieve: el otro 80%

legacy-scan solo cubre reglas deterministas. Para todo lo demás, el flujo del agente es search y luego retrieve. Ejecuté una consulta real mientras escribía esto:

bash
npx modern-web-guidance@latest search "dark mode toggle"

Devolvió IDs de guías ordenadas con descripciones (dark-mode-toggle, dark-mode, component-specific-light-dark-theme, selector-atrule-combinations y más), y retrieve "<id>" descarga la guía completa. Las guías grandes (la mía guardó 25 KB) van a un archivo temporal en vez de a stdout para que no se trunquen. Las propias instrucciones de la skill le dicen al agente que busque antes de escribir UI, que juzgue los resultados por descripción y que solo recupere lo que encaje, lo cual es una guarda razonable contra la saturación de contexto.

Diagrama del flujo de Modern Web Guidance: instalar la skill, ejecutar legacy-scan sobre tu código, luego buscar y recuperar guías

Si tu agente soporta skills, instalar esto significa que su próxima tarea de modal, formulario o animación tira de guías revisadas por ingenieros de navegadores en lugar de datos de entrenamiento desactualizados. Eso es el producto real.

Qué hacen realmente estas correcciones para el lector

Siendo honestos: ninguna de estas cosas era una página rota. Eran pulido, consistencia y peso de página. Esto es lo que cada cambio hace por alguien que visita bitdoze.com:

Hallazgo Efecto para el lector Coste de la corrección
Scrollbars de vendor Los usuarios de Firefox veían un scrollbar por defecto en las zonas con scroll de tablas; ahora todos los navegadores tienen el mismo fino personalizado Dos propiedades estándar + envoltorio @supports, ~10 líneas
Meta color-scheme La UI nativa (scrollbars, controles de formulario, overscroll) elige el tema correcto en el primer pintado, antes de que cargue el CSS; los colores light-dark() y la ruta sin JS quedan correctos Una meta etiqueta + tres líneas en el bootstrapper de tema
CSS de animación muerto Nada visible, pero 34 líneas de CSS se enviaban a /resources/ en cada visita sin hacer nada Borrado el bloque <style> completo
Progressbar con div Los lectores de pantalla ya lo anunciaban bien (el ARIA estaba), así que la ganancia es menos markup y semántica que no puede derivar Dos divs cambiados por un <progress> + CSS de pseudo-elementos

El beneficio mayor no es ninguna corrección suelta. Es que la skill se queda instalada, así que la próxima vez que un agente escriba un modal, formulario, scrollbar o animación para este sitio, tira de guías revisadas por ingenieros de navegadores en lugar de patrones desactualizados. Prevenir gana a limpiar.

Las correcciones que apliqué

Scrollbar: propiedades estándar primero, WebKit como fallback

css
.prose .table-scroll {
  scrollbar-width: thin;
  scrollbar-color: var(--color-border-base) var(--color-bg-muted);
}

@supports not (scrollbar-color: auto) {
  .prose .table-scroll::-webkit-scrollbar {
    height: 6px;
  }
  /* ...reglas existentes de track/thumb... */
}

Firefox recibe scrollbar-width: thin y scrollbar-color hoy; los navegadores sin soporte de scrollbar-color caen en las reglas WebKit. Mismos colores, mayor cobertura.

Modo oscuro: meta sincronizada en el bootstrapper

html
<meta name="color-scheme" content="light dark" />

Y dentro de applyTheme():

js
document
  .querySelector('meta[name="color-scheme"]')
  ?.setAttribute(
    "content",
    stored === "dark" ? "dark" : stored === "light" ? "light" : "light dark"
  );

light dark significa “seguir el sistema”; un light o dark guardado fija la preferencia. La meta está antes del script de tema en <head>, así que existe antes de que applyTheme() se ejecute por primera vez.

CSS muerto: borrado, no modernizado

Eliminado el bloque <style> completo de ResourcesView.astro: los keyframes fadeIn, .animate-fade-in y las seis reglas :nth-child de retardo. Si la animación escalonada vuelve algún día, sibling-index() es la herramienta correcta, con el fallback de custom property --sibling-index que la guía prescribe para navegadores anteriores a Baseline.

Barra de progreso: elemento nativo, pseudo-elementos separados

html
<progress
  class="course-progress h-1.5 w-24 rounded-full bg-gray-200 dark:bg-gray-700"
  max="100"
  value="0"
  aria-label="Course progress"
  data-progress-track
></progress>
css
.course-progress {
  appearance: none;
  border: 0 solid;
  overflow: clip;
}
.course-progress::-webkit-progress-bar { background: transparent; }
.course-progress::-webkit-progress-value { background: #2563eb; border-radius: 9999px; }
.course-progress::-moz-progress-bar { background: #2563eb; border-radius: 9999px; }

Ojo con los dos pseudo-elementos de relleno en reglas separadas. Agrúpalos y los navegadores descartan todo. El JavaScript de progreso ahora asigna bar.value en vez de animar un ancho, lo que también hace que el relleno se actualice al instante en lugar de con transición: un intercambio justo por markup semántico.

bun run build:ci pasa con las cuatro correcciones aplicadas.

Veredicto: ¿merece la pena instalarla?

  • Gratis, open source y mantenida por los propios fabricantes de navegadores, no un envoltorio sobre un LLM.
  • Los datos de compatibilidad Baseline hacen que las recomendaciones encajen con tus objetivos reales de navegadores en vez de conjeturas del tipo “funciona en Chrome”.
  • Coste cero en runtime: es guía del lado del prompt, nada llega a tus usuarios.
  • La auditoría legacy-scan es útil aunque ignores el resto. Cinco hallazgos en una base de código que conozco bien es un buen promedio, y verificarlos cazó un falso positivo y un caso de código muerto.

Las pegas honestas:

  • legacy-scan cubre ~20% del catálogo por diseño. Tómalas como primera pasada y deja que search/retrieve cubran el trabajo por función.
  • Los hallazgos son pistas, no veredictos. Verifícalos contra la rúbrica de la guía. Dos de mis cinco necesitaron una segunda mirada.
  • Las guías asumen un objetivo “Baseline Widely Available”. Si compilas para runtimes restringidos (Electron, Safari antiguo), dilo en AGENTS.md o el agente aplicará fallbacks que no necesitas.
  • Tiene dos días de vida. La 1.0 salió el 10 de noviembre; espera que el corpus y la CLI se muevan rápido.

Si usas un agente de código en trabajo de frontend, instálala. Si solo escribes backend o infraestructura, sáltala: la propia skill dice que no se activa para esas tareas. Para más comparativas de herramientas para agentes, mira mi guía de las mejores skills de IA para diseño web y la guía de configuración del agente Pi si aún estás eligiendo entorno.

#AI Agents#CSS#Modern Web Guidance

¿Te funcionó esta guía?

¿Necesitas ayuda con Astro, VPS o una app self-hosted? Ver servicios →