- 98.css é um sistema de design em CSS que implementa interfaces web com aparência do Windows 98 com base em HTML semântico e acessibilidade
- Como apenas aplica estilos ao HTML sem usar JavaScript, pode ser usado em diversos ambientes de frontend, incluindo React e JavaScript vanilla
- Oferece uma ampla variedade de componentes de UI do Windows 98, de botões, campos de entrada e controles de seleção até janelas, abas, árvores, tabelas e barras de progresso
- Suporta associação de rótulos,
aria-label e papéis ARIA, além de permitir redefinir estilos como espaçamento e cores mantendo a aparência padrão
- Pode ser instalado via unpkg, npm e GitHub Releases, e é distribuído sob a licença MIT, permitindo modificações e contribuições open source
Estrutura do projeto e instalação
- 98.css é uma biblioteca CSS que recria fielmente a interface do Windows 98
- Baseia-se em HTML semântico, usando
<button> para botões, <label> para elementos de entrada e aria-label para botões com ícone
- Um dos principais objetivos inclui acessibilidade, considerando navegação por teclado e uso de tecnologias assistivas
- Como estiliza HTML apenas com CSS, sem JavaScript, não depende de nenhum framework específico de frontend
- A forma mais rápida de usar é carregar a folha de estilos pelo unpkg
<link rel="stylesheet" href="https://unpkg.com/98.css">
npm install 98.css
- É possível redefinir livremente estilos individuais, como espaçamento de botões ou cor dos rótulos de entrada, mantendo a aparência básica
Controles básicos de seleção
-
Botões
- O botão padrão tem tamanho 75×23px, com bordas externas e internas em relevo e espaçamento horizontal padrão de 12px
- Suporta
<button>, input[type=submit] e input[type=reset]
- A classe
default indica a ação padrão executada ao pressionar Enter na janela ativa
- Ao clicar, muda para um formato com borda em baixo-relevo, e botões desativados mantêm a borda com o rótulo esmaecido
- O foco é indicado por uma borda pontilhada a 4px do conteúdo interno do botão
-
Checkboxes e botões de opção
- Checkboxes representam seleções independentes ou não exclusivas e, quando marcadas, exibem um ícone de check dentro de um painel rebaixado
- Depois do checkbox, é obrigatório usar um
<label> com o atributo for apontando para o id do input
- Essa associação permite que tecnologias assistivas reconheçam o input
- Suporta navegação com a tecla Tab e clique em toda a área do rótulo
- Os estados selecionado e desativado são definidos com os atributos padrão
checked e disabled
- Vários inputs devem ser envolvidos por um contêiner
field-row para aplicar espaçamento consistente
- Botões de opção são controles para selecionar apenas um item em um conjunto limitado e são criados com
input[type=radio]
- Use o mesmo atributo
name para agrupá-los como grupo mutuamente exclusivo e, assim como nos checkboxes, use rótulos e field-row
-
Caixa de grupo
fieldset agrupa vários controles em uma moldura retangular, criando uma aparência de caixa gravada com borda externa rebaixada e borda interna em relevo
- Ao colocar
legend dentro dele, é possível exibir o rótulo do grupo
Entrada de texto e seleção de valores
-
Caixa de texto
- Entradas de uma linha usam
input[type=text] e entradas de várias linhas usam textarea
- O input e o rótulo corretamente associado devem ser envolvidos juntos por
field-row para um layout horizontal
- Com
field-row-stacked, o rótulo pode ser colocado verticalmente acima do elemento de entrada
- Os atributos padrão do HTML
disabled e value definem o estado desativado e o valor inicial
-
Slider
- O slider mostra a faixa de ajuste e o valor atual, sendo renderizado com
input[type=range]
- A classe
has-box-indicator substitui o indicador padrão por um indicador em forma de caixa
- Se o slider for envolvido por uma
div com a classe is-vertical, ele pode ser exibido na vertical
- O comprimento do slider vertical é ajustado pela largura do
input e pela altura da div contêiner
-
Dropdown
- Use
select e option para criar um dropdown que seleciona um item de uma lista
- O primeiro item é selecionado por padrão, e é possível mudar a seleção inicial definindo o atributo
selected em outro option
Janelas no estilo Windows 98
-
Barra de título
- A barra de título ocupa toda a largura da parte superior da janela, identifica o conteúdo e inclui os botões de comando comuns
- É composta pelas três classes
title-bar, title-bar-text e title-bar-controls
- No
aria-label dos botões de comando, podem ser usados Minimize, Maximize, Restore, Help e Close
- O
aria-label transmite a intenção do botão para tecnologias assistivas e também aplica o estilo de ícone correspondente ao comando
- Também são fornecidas classes separadas
minimize, maximize, restore, help e close
- Isso separa o texto de
aria-label do estilo visual para evitar problemas de renderização ou acessibilidade durante processos de multilíngue e localização
- Para janelas que não podem ser maximizadas, defina
disabled no botão Maximize
title-bar inactive representa uma barra de título inativa entre várias janelas
-
Corpo da janela e barra de status
- A classe
window fornece bordas externas e internas em relevo e espaçamento, e o tamanho da janela pode ser alterado definindo a largura do contêiner
- O conteúdo real abaixo da barra de título fica em
window-body
- A barra de status na parte inferior da janela mostra informações contextuais, como estado atual ou estado do teclado
- Use
status-bar para o contêiner inteiro e status-bar-field para cada área de texto
- A barra de status pode ser usada para montar interfaces como Task Manager, Notepad e File Explorer
Interfaces de hierarquia, abas e tabelas
-
Visualização em árvore
ul.tree-view representa a hierarquia lógica entre objetos como uma lista recuada
- Ao aninhar
ul filhos, são aplicados bordas pontilhadas e recuo, e qualquer conteúdo desejado pode ser colocado nos li internos
- Hierarquias expansíveis e recolhíveis são compostas colocando a lista filha dentro do elemento
details
-
Abas
- A lista de abas é escrita como
menu[role=tablist] e cada aba como li[role=tab]
- A aba ativa deve receber
aria-selected="true"
- Como o 98.css não inclui lógica de troca de abas, a mudança de estado deve ser gerenciada com JavaScript do usuário
- O conteúdo das abas deve ser colocado em uma área de janela com
role="tabpanel"
- Adicione a classe
multirows ao menu para criar abas em várias linhas
-
Visualização em tabela
- Envolva uma
table HTML com div.sunken-panel para criar uma área com bordas apropriadas e rolagem
table.interactive mostra o cursor de ponteiro ao passar o mouse sobre as linhas do corpo
- Aplique a classe
highlighted à linha selecionada; o comportamento real de seleção deve ser implementado com script separado
Progresso e bordas genéricas
-
Barra de progresso
- A taxa de conclusão de tarefas longas é indicada colocando
progress-indicator-bar dentro de progress-indicator e definindo sua largura
- A forma padrão é uma barra sólida; ao adicionar a classe
segmented, ela se torna uma barra de progresso segmentada
-
Bordas de campo
- Caixas de texto, checkboxes, dropdowns, spin boxes e list boxes usam o estilo de campo com bordas externas e internas rebaixadas
- Campos normais usam internamente a cor de destaque de botão, enquanto campos de texto somente leitura ou desativados usam a cor da superfície do botão
- Campos de status usam apenas a borda externa rebaixada e podem ser usados em barras de status ou conteúdo somente leitura alterado dinamicamente
- Também são fornecidas três classes genéricas para áreas de trabalho e conteúdo dinâmico fora de formulários
field-border: área de trabalho normal
field-border-disabled: área de trabalho desativada
status-field-border: conteúdo de status dinâmico
- Como essas classes definem apenas borda, cor de fundo e espaçamento mínimo, normalmente é preciso definir
padding adicional manualmente
Licença e contribuição
- O 98.css é distribuído sob a licença MIT
- Verificação e reporte de bugs podem ser feitos em GitHub Issues
- Pull requests são bem-vindos e há code review disponível, especialmente para quem está contribuindo com open source pela primeira vez
1 comentários
Opiniões do Hacker News
Este projeto foi criado durante um processo de recuperação de burnout, e até hoje tenho um carinho especial por ele
https://notes.jordanscales.com/98-css-reflections
O equilíbrio entre usabilidade e nostalgia é tão preciso que dá vontade de usá-lo mais em outros projetos
Durante a pesquisa, também encontrei o portfólio do criador do 98.css, e até o gosto musical dele era exatamente igual ao meu; fiquei me perguntando se todas as pessoas que criam bibliotecas retrô têm gostos parecidos
O flat design é ridículo, mas rendeu muito dinheiro a alguém e depois todo mundo passou a segui-lo como um rebanho
Já nem surpreende que quase 20 anos depois ainda não tenhamos conseguido escapar dele; a forma como as abas em várias linhas funcionavam naturalmente nas UIs antigas era realmente excelente
O problema é que a filosofia de “menos é mais” entra em conflito com as UIs super saturadas, parecidas com massinha de brinquedo, da Apple, do Google e de seus imitadores
Elas ocupavam um espaço vertical precioso e, a cada clique, a posição das linhas mudava, o que era confuso; se um botão indica estado, ele não deveria se mover depois de clicado
Mesmo tendo monitores e placas de vídeo capazes de exibir milhões de cores, não tiramos proveito disso; não precisa parecer um livro de colorir, mas Windows 10 e 11 passam uma sensação deprimente
O que sempre me incomodou na família do 98.css era que a MS Sans Serif era sutilmente imprecisa, então acabei decidindo corrigir isso por conta própria
https://github.com/jdan/98.css/pull/230
Este projeto já viralizou várias vezes antes: 2024, 471 pontos e 93 comentários https://news.ycombinator.com/item?id=42056918, 2022, 606 pontos e 182 comentários https://news.ycombinator.com/item?id=33310554, 2020, 838 pontos e 211 comentários https://news.ycombinator.com/item?id=22940564
Windows 95: https://alexbsoft.github.io/win95.css/, sites dos anos 1980: https://bootstra386.com/, Windows XP: https://botoxparty.github.io/XP.css/, GeoCities: https://code.divshot.com/geo-bootstrap/, Counter-Strike 1.6: https://cs16.samke.me/, Edward Tufte: https://edwardtufte.github.io/tufte-css/, Windows 98: https://jdan.github.io/98.css/, Windows 7: https://khang-nd.github.io/7.css/, PlayStation: https://micah5.github.io/PSone.css/, NES: https://nostalgic-css.github.io/NES.css/, Apple System: https://sakofchit.github.io/system.css/, SNES: https://snes-css.sadlative.com/, The Sims: https://thesimscss.inbn.dev/
Quero criar um site ao qual eu possa aplicar esse estilo, mas não consigo imaginar onde ele se encaixaria
O XFCE-winxp-tc, que deixa o Linux com aparência de Windows XP, também é excelente. O Chicago95 é bastante conhecido, mas, se você quiser uma vibe de 2004, https://github.com/rozniak/xfce-winxp-tc combina bem
Não sei se é por preocupações legais
A prática de remover botões desativados e simplesmente não mostrá-los é uma das tendências de UI mais confusas de hoje; ver um botão cinza, na verdade, me deixa mais tranquilo
Eles só deveriam ser desativados quando o usuário esperasse que fossem aplicáveis e conseguisse inferir facilmente o motivo da desativação; se não houvesse uma forma de ativá-los, ou se o usuário não esperasse que se aplicassem, deveriam ser removidos. Se fosse difícil entender o motivo, era melhor mantê-los ativos e mostrar uma mensagem de erro útil quando fossem usados incorretamente
https://learn.microsoft.com/en-us/windows/win32/uxguide/top-...
Mas as diretrizes modernas https://learn.microsoft.com/en-us/windows/apps/develop/ui/co... não tratam nem dessa distinção sutil nem dos próprios botões desativados
Por outro lado, se ele tem permissão para executar, mas não pode por causa do modo ou estado atual, deve-se mostrar um botão cinza. Em formulários, também é preciso permitir clicar no botão cinza e informar o que está errado. Em uma grande companhia aérea, não consegui concluir o check-in por falta dessa orientação
Dicas ao passar o mouse e pequenos ícones de
?desapareceram, e parece que todo software assume que você já sabe usá-lo desde o primeiro diahttps://ka.ge é um site pessoal feito com 98.css que recria, em menos de 1 MB, um ambiente de desktop Windows 98 preciso pixel a pixel e realmente funcional
É uma pena que, no exemplo de abas em várias linhas, as abas não mudem de posição aleatoriamente ao clicar, como no Windows original
A cada nova versão do sistema operacional, designers de UI tiveram que vender como melhoria até mudanças funcionalmente desnecessárias, que consomem mais recursos, são mais lentas e instáveis
less faster, parece que esses designers de UI também mexeram neste comentárioÉ difícil entender por que se concentrar nesse tipo de recriação, já que a UI do Windows 98 nem foi o ápice da experiência do usuário
O inchaço de hoje é resultado de camadas e mais camadas de tecnologia e abstração, então o essencial é entender quais elementos são necessários para uma boa experiência do usuário e encontrar o conjunto mínimo de componentes tecnológicos
Cantos arredondados e espaços flutuantes são exemplos típicos, e a influência do macOS e dos designers web prejudicou a usabilidade