⏱️ Lectura: 11 min
Imagina un shooter en primera persona —pasillos, enemigos, disparos— corriendo en tu navegador sin una sola línea de WebGL ni un elemento <canvas>. Eso es cssQuake: un Quake en CSS puro, donde cada pared y cada enemigo es un elemento HTML al que se le aplican transformaciones 3D. El proyecto, construido sobre un motor bautizado PolyCSS, demuestra que las transformaciones de CSS pueden sostener una escena interactiva completa.
📑 En este artículo
Para quienes desarrollamos en la web, es a la vez una curiosidad técnica y una lección sobre los límites reales del navegador cuando lo empujas fuera de su terreno habitual.
TL;DR
- cssQuake es un shooter tipo Quake que se renderiza con puro CSS y transformaciones 3D, sin WebGL ni elemento canvas.
- El motor detrás se llama PolyCSS y usa el DOM como escena 3D: cada pared o enemigo es un elemento HTML transformado.
- El renderizado se apoya en transform-style: preserve-3d, perspective y translate3d/rotate para componer la profundidad.
- JavaScript solo gestiona la lógica: entrada WASD, ratón, física básica y actualización de variables CSS por frame.
- Incluye partidas por sala con enlace para invitar, límite de frags y de tiempo, y un panel de depuración con FPS y stats.
- Es una prueba de concepto: rinde en escenas pequeñas, pero el coste de composición sube con el número de polígonos.
- Demuestra cuánto puede el navegador sin tocar la GPU vía WebGL y sirve como ejercicio didáctico de CSS 3D.
Qué es cssQuake y por qué llama la atención
cssQuake es una recreación jugable del clásico Quake de id Software, pero con un giro técnico radical: no dibuja nada en un lienzo de píxeles. En lugar de usar WebGL —la API estándar para gráficos acelerados por GPU en el navegador— o el elemento <canvas>, apila elementos del DOM y los coloca en un espacio tridimensional usando exclusivamente propiedades CSS. El motor que hace posible esto se llama PolyCSS, y su idea central es tratar el árbol del DOM como si fuera el grafo de escena de un motor 3D tradicional.
La interfaz refuerza la sensación de estar ante un proyecto serio y no un simple experimento de fin de semana. Hay un menú para crear o unirse a una partida, con campos para nombre, color, mapa, límite de frags (fraglimit), límite de tiempo (timelimit) y número máximo de jugadores, además de un botón para copiar el enlace de la sala. Los controles son los canónicos del género: WASD para moverse, ratón para mirar, clic para disparar, espacio para saltar, shift para correr y ctrl para agacharse. Incluso trae un panel de depuración que permite mostrar contornos, estadísticas y FPS en tiempo real, y alternar iluminación dinámica, partículas y sonidos.
Cómo se renderiza un Quake en CSS (el motor PolyCSS)
El truco de un Quake en CSS empieza por entender que el navegador ya sabe componer planos en 3D. Desde hace más de una década, CSS soporta un modelo de transformaciones tridimensionales pensado originalmente para animaciones y efectos de tarjetas que giran. PolyCSS toma ese mismo modelo y lo lleva al extremo, usando el DOM como contenedor de geometría.
Tres propiedades hacen el trabajo pesado. La primera es perspective, que define a qué distancia está la cámara del plano de la pantalla; cuanto menor es el valor, más exagerada es la sensación de profundidad. La segunda es transform-style: preserve-3d, que le indica al navegador que los hijos de un elemento deben posicionarse en el mismo espacio 3D que el padre, en lugar de aplanarse. La tercera es la función transform con translate3d() y rotateX/Y/Z(), que coloca y orienta cada superficie del nivel.
.escena {
perspective: 800px; /* distancia de la camara */
overflow: hidden;
}
.mundo {
transform-style: preserve-3d;
/* movemos el mundo, no la camara */
transform: rotateX(var(--pitch)) rotateY(var(--yaw))
translate3d(var(--x), 0, var(--z));
}
.pared {
position: absolute;
transform-style: preserve-3d;
transform: translate3d(var(--px), 0, var(--pz)) rotateY(var(--angulo));
}
Fíjate en un detalle clave: no movemos una cámara, movemos el mundo entero en sentido contrario. Si el jugador avanza hacia adelante, en realidad desplazamos todo el escenario hacia atrás. Es el mismo principio que usan muchos motores 3D, y en CSS resulta natural porque solo tenemos que actualizar unas pocas variables CSS en un contenedor padre, y el navegador recalcula la escena.
El rol de JavaScript es deliberadamente acotado: lee el teclado y el ratón, calcula la física básica y, una vez por frame, escribe el estado en variables CSS mediante requestAnimationFrame. A partir de ahí, el compositor del navegador se encarga de todo el dibujado.
const mundo = document.querySelector('.mundo');
const jugador = { x: 0, z: 0, vx: 0, vz: 0, yaw: 0 };
function frame() {
// fisica minima: aplicar velocidad a la posicion
jugador.x += jugador.vx;
jugador.z += jugador.vz;
// volcar el estado a variables CSS, una escritura por frame
mundo.style.setProperty('--x', `${-jugador.x}px`);
mundo.style.setProperty('--z', `${-jugador.z}px`);
mundo.style.setProperty('--yaw', `${-jugador.yaw}deg`);
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
El flujo completo, de la tecla pulsada al frame pintado, se puede resumir así:
graph LR
A[Input WASD y raton] --> B[Logica de juego JS]
B --> C[Actualiza variables CSS]
C --> D[preserve-3d y translate3d]
D --> E[Compositor del navegador]
E --> F[Frame en pantalla]
💭 Clave: En un Quake en CSS, JavaScript no dibuja ni un solo píxel de la escena 3D: solo actualiza variables CSS. El renderizado lo hace el compositor del navegador, el mismo que pinta cualquier página web.
Contexto e historia: el CSS 3D no nació ayer
El CSS 3D no es una novedad de 2026. El módulo CSS Transforms, que introdujo las funciones tridimensionales, lleva siendo soportado por los navegadores principales desde alrededor de 2012. Durante años, su uso se limitó a efectos decorativos: tarjetas que se voltean (flip cards), cubos giratorios, carruseles con profundidad y transiciones llamativas en páginas de aterrizaje.
Periódicamente, sin embargo, aparecen proyectos que llevan la técnica mucho más lejos para demostrar lo que es posible. Ha habido demos de motores tipo raycasting al estilo Wolfenstein 3D hechas con sombras (box-shadow), laberintos navegables y escenas isométricas completas. cssQuake se inscribe en esa tradición de demos límite —emparentada con la cultura demoscene—, pero sube la apuesta al combinar renderizado 3D, lógica de juego en tiempo real y, según su interfaz, partidas multijugador organizadas por salas con invitación por URL.
Datos y cifras: qué incluye y cómo rinde
Aunque cssQuake es ante todo una demostración técnica, su interfaz expone una cantidad notable de funcionalidad. El menú de creación de partida ofrece configuración de nombre, color, mapa, fraglimit, timelimit y número máximo de jugadores, además de copiar el enlace de la sala para compartirla. Eso apunta a un modelo multijugador basado en salas con invitación por enlace, un patrón habitual en juegos web casuales.
El panel de depuración es quizá lo más revelador para un desarrollador. Permite activar y desactivar contornos (show outlines), panel de estadísticas, panel de FPS, mira (crosshair), iluminación dinámica, partículas, enemigos, daño, movimiento y ataques, además de invertir el ratón. También expone un modo de grabación que distingue entre captura visible, DOM, enemigos y objetos. Esa granularidad —poder apagar el daño, el movimiento o los ataques por separado— es típica de herramientas pensadas para perfilar rendimiento y aislar qué parte de la escena cuesta más renderizar.
⚠️ Ojo: Renderizar 3D con CSS no es gratis. Cada polígono es un nodo del DOM que el navegador debe recomponer; en escenas grandes, el coste de composición y repintado crece rápido y los FPS caen. Por eso estas demos cuidan mucho el número de elementos en pantalla.
Impacto y análisis: ¿curiosidad o herramienta?
¿Es cssQuake una herramienta práctica para hacer videojuegos? Casi con seguridad, no. Para cualquier juego 3D serio, WebGL y su sucesor WebGPU siguen siendo la opción correcta: hablan directamente con la GPU, manejan miles de polígonos texturizados y ofrecen shaders programables. Un Quake en CSS choca contra un techo de rendimiento mucho antes que cualquiera de esas APIs.
El valor de cssQuake es otro. Primero, es didáctico: obliga a entender de verdad cómo funciona el sistema de coordenadas 3D de CSS, qué hace preserve-3d y por qué mover el mundo equivale a mover la cámara. Segundo, es una prueba de robustez de la plataforma: demostrar que el motor de composición aguanta una escena interactiva valida lo lejos que ha llegado la web. Y tercero, es accesible: cualquiera puede abrir las DevTools, inspeccionar el DOM y ver, literalmente, las paredes del nivel como elementos HTML.
Para la comunidad de desarrollo en LATAM y en español, proyectos así son oro para aprender. No requieren instalar nada, corren en cualquier laptop modesta sin GPU dedicada potente, y el código es inspeccionable desde el propio navegador. Es una forma de estudiar gráficos 3D sin la curva de entrada de un motor como Unity o de la propia API de WebGL.
Qué sigue
La pregunta interesante no es si CSS reemplazará a WebGL —no lo hará—, sino qué aprendizajes deja. La llegada de WebGPU a los navegadores estables durante 2024 y 2025 reabrió el interés por los gráficos en la web, y demos como cssQuake recuerdan que incluso las capas más altas de la plataforma esconden capacidades sorprendentes.
Es razonable esperar más experimentos en esta línea: motores PolyCSS más pulidos, niveles compartibles por URL y, quizá, integraciones con herramientas de captura para convertir estas escenas en material educativo. Mientras tanto, lo mejor que puedes hacer es abrir cssQuake, jugar un par de partidas y luego abrir las DevTools para ver cómo está hecho por dentro. Esa combinación de jugar y diseccionar es, para muchos, la mejor manera de aprender un Quake en CSS desde cero.
📖 Resumen en Telegram: Ver resumen
Preguntas frecuentes
¿cssQuake usa WebGL o el elemento canvas?
No. Toda la escena 3D se renderiza con propiedades CSS —transformaciones 3D, perspective y preserve-3d— aplicadas a elementos del DOM. JavaScript solo gestiona la entrada, la lógica y la física básica.
¿Qué es PolyCSS?
Es el motor que da nombre al subtítulo del proyecto (Powered by PolyCSS). Trata el árbol del DOM como un grafo de escena 3D y compone los polígonos a partir de elementos HTML transformados con CSS.
¿Por qué renderizar 3D en CSS si ya existe WebGL?
Por aprendizaje y demostración, no por rendimiento. WebGL y WebGPU son muy superiores para juegos reales. El CSS 3D es más accesible, se inspecciona desde las DevTools y no exige conocer shaders.
¿Rinde bien? ¿Sirve para un juego comercial?
Para escenas pequeñas rinde de forma aceptable, pero el coste de composición crece con el número de elementos. No es la opción adecuada para un juego 3D comercial con muchos polígonos.
¿Puedo ver el código del juego?
En parte sí: al ser una página web, puedes abrir las DevTools del navegador e inspeccionar el DOM y los estilos para entender cómo se posicionan paredes y enemigos en el espacio 3D.
¿Se puede jugar en el móvil?
El juego está pensado para teclado y ratón (WASD más clic), así que la experiencia ideal es en escritorio. En móvil, la falta de esos controles y el mayor coste de composición lo hacen menos práctico.
Referencias
- cssQuake — el juego original y el motor PolyCSS.
- MDN: transform-style — la propiedad que habilita el espacio 3D para los hijos.
- MDN: perspective — cómo se define la profundidad de la cámara.
- MDN: translate3d() — función de transformación 3D usada para posicionar superficies.
- Wikipedia: Quake — contexto del juego original de id Software.
📱 ¿Te gusta este contenido? Únete a nuestro canal de Telegram @programacion donde publicamos a diario lo más relevante de tecnología, IA y desarrollo. Resúmenes rápidos, contenido fresco todos los días.
0 Comentarios