- 98.css permite crear interfaces web que se ven como Windows 98 usando solo CSS, reproduciendo fielmente la UI clásica de escritorio
- La accesibilidad depende de HTML semántico, con el supuesto de usar correctamente los atributos ARIA en botones, etiquetas y botones de ícono
- Como no incluye JavaScript, puede integrarse sin depender del framework en proyectos con React, JavaScript puro o HTML tradicional
- Ofrece componentes con estilo Windows 98 como botones, casillas de verificación, botones de opción, ventanas, vista de árbol, pestañas, vista de tabla y barras de progreso
- Puede usarse vía npm, GitHub Releases o unpkg, y está publicado bajo licencia MIT, aceptando reportes de errores y pull requests
Cómo recrea la UI de Windows 98 con CSS
- 98.css es una librería CSS para crear interfaces con apariencia de Windows 98
- El proyecto puede consultarse en GitHub
- La accesibilidad depende de una estructura HTML semántica más que de scripts adicionales
- Los botones deben usar
<button>
- Los elementos de entrada necesitan su
<label> correspondiente
- Los botones de ícono transmiten su intención con
aria-label
- Se puede sobrescribir parte del estilo de los elementos manteniendo la apariencia base
- Por ejemplo, se puede aumentar el padding de un botón o agregar color a la etiqueta de un campo
Instalación e integración con frameworks
- 98.css aplica el estilo de Windows 98 a elementos HTML solo con CSS, sin JavaScript
- Puede usarse de forma independiente del framework frontend
- Se ofrecen ejemplos de uso con React y uso con JavaScript puro
- La forma más rápida de usarlo es importar la hoja de estilos desde unpkg
<link rel="stylesheet" href="https://unpkg.com/98.css">
npm install 98.css
Controles básicos de formulario
-
Button
- El botón estándar mide 75px de ancho por 23px de alto, con bordes exteriores e interiores elevados y padding horizontal base de 12px
- Al agregar la clase
default, se puede indicar visualmente la acción predeterminada que se ejecutaría con la tecla Enter en Windows 98
- En estado de clic, el borde elevado cambia a una apariencia presionada
- Los botones deshabilitados mantienen el mismo borde elevado, pero la etiqueta se ve atenuada
- El foco se muestra con un borde punteado a 4px dentro del contenido del botón
-
Checkbox
- La casilla de verificación representa una selección independiente o no excluyente
- Al seleccionarse, muestra un ícono de marca dentro de un panel hundido, con una etiqueta al lado que describe la opción
- Después de
<input type="checkbox"> debe incluirse un <label> cuyo atributo for apunte al id del campo
- Puede usar los atributos
checked y disabled
- Al agrupar varias entradas, cada una debe envolverse en un contenedor con clase
field-row para alinear el espaciado
-
Option Button
- El botón de opción es un control para elegir solo una opción entre un conjunto limitado
- Se usa con
<input type="radio">, y al compartir el mismo atributo name se agrupan
- Igual que con las casillas de verificación, pueden envolverse en
field-row para mantener un espaciado consistente
- Soporta los atributos
checked y disabled
-
Group Box
- El cuadro de grupo es un marco rectangular para organizar varios controles
- Se usa envolviendo los elementos con
fieldset, que proporciona un borde exterior hundido y un borde interior elevado
- Se puede agregar una etiqueta de grupo colocando
legend dentro del fieldset
Entrada de texto, slider y menú desplegable
-
TextBox
- La caja de texto es un control rectangular para que el usuario escriba o edite texto
- La entrada de una sola línea se renderiza con
<input type="text">
- Se recomienda proporcionar un
<label> correspondiente con el atributo for correcto y envolver ambos en un contenedor field-row
- Con la clase
field-row-stacked, la etiqueta puede colocarse arriba del campo en vez de a su lado
- Para entrada de varias líneas se usa
textarea
- Pueden usarse atributos estándar de HTML como
disabled y value
-
Slider
- El slider está compuesto por una barra que representa el rango de ajuste y un indicador que muestra el valor actual
- Se renderiza con
<input type="range">
- La clase
has-box-indicator cambia el indicador predeterminado por uno en forma de caja
- Si se envuelve en un
div con is-vertical, se muestra como slider vertical
- Para cambiar la longitud del slider vertical, hay que ajustar el width del
input y el height del div
-
Dropdown
- La lista desplegable permite seleccionar un solo elemento de una lista
- En estado cerrado muestra el valor actual, y el usuario abre la lista para cambiarlo
- Se renderiza con los elementos
select y option
- El valor predeterminado es la primera opción, aunque puede cambiarse marcando una
option específica con selected
Construcción de ventanas estilo Windows 98
-
Title Bar
- La barra de título se ubica dentro del borde superior de la ventana e identifica su contenido
- Se compone con las clases
title-bar, title-bar-text y title-bar-controls
- El botón de cerrar usa
aria-label="Close" para comunicar su intención a las tecnologías de asistencia
- También pueden usarse
aria-label como Minimize, Maximize, Restore y Help
- Cada
aria-label tiene una clase de estilo correspondiente, para evitar problemas de renderizado, accesibilidad o localización aunque el texto de aria-label esté en otro idioma
- El botón de maximizar puede deshabilitarse con
disabled
- Si se agrega la clase
inactive, puede mostrarse como una barra de título inactiva
-
Window contents
- La clase
window crea el contenedor de la ventana donde va la barra de título, con bordes exteriores e interiores elevados y padding
- Se puede ajustar libremente el tamaño de la ventana asignando width al estilo del contenedor
- El contenido debajo de la barra de título puede renderizarse con la clase
window-body
-
Status Bar
- La barra de estado suele ubicarse en la parte inferior de la ventana y muestra información de estado o contexto actual
- Se renderiza con la clase
status-bar
- Cada elemento de texto usa la clase
status-bar-field
- El ejemplo incluye campos de estado como
Press F1 for help, Slide 1 y CPU Usage: 14%
Listas, pestañas, tablas y progreso
-
TreeView
- La vista de árbol es un cuadro de lista especializado que muestra un conjunto de objetos en forma de esquema con sangría según relaciones jerárquicas lógicas
- Se renderiza agregando la clase
tree-view al elemento ul
- Los elementos hijos
li pueden contener el contenido que se desee
- Al incluir
ul anidados, se muestra la estructura de árbol con bordes punteados y sangría
- Las secciones expandibles pueden construirse colocando la lista hija dentro de un elemento
details
-
Tabs
- El control de pestañas se usa para definir varias páginas lógicas o secciones de información dentro de una misma ventana
- Se agrega
role="tablist" al elemento menu, y role="tab" a los elementos hijos li
- La gestión de pestañas debe manejarse con código JavaScript del usuario
- Para una pestaña activa, basta con agregar
aria-selected="true"
- Las pestañas de varias filas pueden crearse agregando la clase
multirows a la etiqueta menu
-
TableView
- La vista de tabla se renderiza con el elemento
table
- Para proporcionar bordes apropiados y un contenedor con overflow, debe envolverse en un
div con clase sunken-panel
- Con un poco de script adicional, la vista de tabla puede volverse interactiva
- Si se agrega la clase
interactive a table, al pasar el cursor sobre las filas del cuerpo se muestra el cursor de puntero
- Si se agrega la clase
highlighted a una fila, esta se verá como seleccionada
-
Progress Indicator
- La barra de progreso se usa para mostrar el porcentaje de avance de una tarea larga
- De forma predeterminada, es una barra de progreso sólida
- Con la clase
segmented, puede declararse una barra de progreso segmentada
- El avance se representa con el estilo
width de progress-indicator-bar
Bordes de campo y participación open source
-
Field borders
- Las cajas de texto, casillas de verificación, listas desplegables, spin boxes y cuadros de lista usan el estilo de borde de campo
- La misma apariencia también puede usarse para áreas de trabajo dentro de una ventana
- Los bordes de campo usan un borde exterior hundido y un borde interior hundido
- El interior de la mayoría de los controles usa el color button highlight
- Cuando campos de texto como cajas de texto y combo boxes están en modo de solo lectura o deshabilitados, el interior usa el color button face
- Para uso general se ofrecen las clases
field-border, field-border-disabled y status-field-border
- Estas clases solo definen el borde, el color de fondo y un padding mínimo, por lo que normalmente hay que ajustar padding adicional manualmente
-
Licencia y contribuciones
- 98.css es un proyecto con licencia MIT
- Para revisar y reportar errores se usa la GitHub issues page
- Se aceptan pull requests, y se indica especialmente que se ofrecerá code review a personas nuevas en el open source
- El proyecto busca ser un lugar para adquirir una experiencia divertida en open source
1 comentarios
Opiniones de Hacker News
Hice algo similar que incluye 3.11, 95, 2000, XP, CDE, Mac OS 9 y sus respectivas paletas de colores predeterminadas: https://nielssp.github.io/classic-stylesheets/?theme=win9x&s...
El foco no era una reproducción perfecta píxel por píxel, sino que funcionara bien y se viera bien también en entornos modernos, como monitores de alta resolución.
Por eso rehíce todos los íconos y símbolos en SVG, y cuando agregué XP y Mac OS 9 lo publiqué en Show HN, pero no recibió mucha atención.
Personalmente, Windows 2000 fue la cúspide del diseño de UI.
Algo adicional que me gustaría ver es un tema para tablas de datos, e idealmente tablas interactivas que funcionen como listas y grillas.
https://nielssp.github.io/classic-stylesheets/?theme=win3x&s...
Soy quien lo creó. Me alegra verlo aparecer de nuevo.
Este fue mi proyecto para recuperarme del burnout, y hace poco escribí algunas reflexiones relacionadas: https://notes.jordanscales.com/98-css-reflections
[0]: https://www.mathsheets.net/
Es interesante cómo la computación retro, como juegos o sistemas operativos antiguos, puede resultar reconfortante e incluso terapéutica.
Sentí algo parecido al jugar en emuladores juegos de Gameboy y Nintendo de mi infancia, o al ejecutar Macintosh System 9; también me vienen a la mente Pico-8, SerenityOS y TempleOS.
Tienen en común ser entornos de computación de estilo retro que el usuario puede entender y controlar por completo, y quizá también haya dinámicas psicológicas más profundas, como la de un sandbox seguro como herramienta terapéutica.
Hoy la tecnología y la sociedad tienen demasiados dark patterns hostiles, así que encontrar espacios físicos y mentales diseñados para la comodidad del usuario resulta un gran alivio.
Me gustaría que también hubiera versiones para Windows 2000 y Windows XP.
Cosas que tengo recopiladas:
The Sims https://thesimscss.inbn.dev/
Windows 98 https://jdan.github.io/98.css/
Windows XP https://botoxparty.github.io/XP.css/
Windows 7 https://khang-nd.github.io/7.css/
Edward Tufte https://edwardtufte.github.io/tufte-css/
98.css se convirtió en un clásico de HN por buenas razones.
Discusiones anteriores:
https://news.ycombinator.com/item?id=33310554 - octubre de 2022, 179 comentarios
https://news.ycombinator.com/item?id=22940564 - abril de 2020, 211 comentarios
También vale la pena ver HyperCard Simulator y Decker.
https://hn.algolia.com/?q=hypercard
Recuerdo que a fines de los 90 Microsoft tenía nombres de colores integrados en CSS que se ajustaban al tema y los colores del escritorio de Windows.
No sé si todavía funcionan; en los IDE aparecen todos en rojo, así que parece que no.
Se podían usar valores como
windowtext,appworkspace,menutext,threedlightshadow,threedshadow,threedfacepara crear una UI web que coincidiera con el look and feel del escritorio del usuario.En 1998 los usé en una app de intranet basada en navegador, y gracias a eso se veía un poco más nativa.
https://drafts.csswg.org/css-color/#css-system-colors
Todos los colores antiguos quedaron marcados como obsoletos:
https://drafts.csswg.org/css-color/#deprecated-system-colors
Este estilo no se lleva bien con DPI no predeterminado.
Por ejemplo, si configuras la escala del monitor en 150%, para intentar ajustarlo a los píxeles físicos puedes ejecutar algo así en la consola del navegador:
with(document.documentElement.style){ transform = \scale(${ 1 / devicePixelRatio })`; transformOrigin = 'top left'; }`Si multiplicas la escala por un número entero, puedes obtener una ampliación que se siente más nítida; aunque no sea 100% perfecta, se ve mucho más cerca del renderizado previsto.
withasí da miedo y a la vez se siente muy fresco.Me gusta y lo odio al mismo tiempo.
Parece que usaron un poco de esto en crowdwave: https://www.crowdwave.com
Cosas relacionadas para ver: https://botoxparty.github.io/XP.css y https://khang-nd.github.io/7.css
Hoy en día casi es un mantra que se necesita espacio para respirar, como entre las opciones de un grupo de radio buttons, pero el espaciado estrecho de las UI antiguas se siente más honesto, más respetuoso con el usuario final y con mayor densidad de información.
No quiero tirar por la borda toda la innovación, pero a menudo extraño las UI viejas.
No me gustaba la decoración de ventanas de Windows 7, pero el resto no estaría nada mal para usarlo en una app Electron.
La UI de Windows XP fue la mejor de todas las UI de Windows: lo bastante moderna como para sentirse refinada, pero con contraste, fácil de ver, leer y entender.
La UI de Windows 7 era demasiado brillante y priorizaba la apariencia por encima de la legibilidad; Windows 98 era demasiado anticuada y casi toda gris, así que también tenía falta de contraste.
https://git.sr.ht/~q3cpma/website/tree/master/item/src/resou...
https://world-playground-deceit.net/
Ver cosas así me dan ganas de llevarlo hasta el final.
A simple vista no parece ser MS Sans Serif, como se renderizaba en Windows 95 y Windows 98.
https://web.archive.org/web/20230603234837/https://vistaserv...
La hoja de estilos de XP enlazada en otro comentario[1] dibuja el texto y las formas en alta resolución, reduciendo las limitaciones pero manteniendo la sensación de la UI.
La razón por la que me gustan las UI tipo 98 no es la baja resolución, sino la claridad y simplicidad.
[1] https://news.ycombinator.com/item?id=42056921
Creo que esto es mucho mejor que lo que salió después de años de “investigación” y “mejoras” de UX/UI.
En 1998 tenía un año, así que no es porque sea de una generación vieja.
Simplemente odio los botones que no parecen botones, las pestañas que no parecen pestañas y los campos de texto en los que solo sabes que puedes editar cuando haces clic.
Apple seguramente investigó algo para MacOSX, pero durante los últimos 20 años, especialmente en mobile, se sintió como si las funciones simplemente se arrojaran ahí sin conceptos de descubribilidad ni consistencia.
Sobre todo, parece que muchos problemas vinieron de que las empresas querían “branding consistente” o una “apariencia propia”.
Y en ese sitio web también hay un botón “show code” disfrazado de texto común.