98.css — это CSS-библиотека, которая позволяет собирать интерфейсы в стиле Windows 98. Никакого JavaScript внутри нет, только стилизация семантического HTML, поэтому библиотека работает с любым фронтенд-фреймворком и не мешает добавлять свои стили поверх. Главная установка — доступность: каждая кнопка требует тега <button>, поля ввода — <label> с атрибутом for, иконки полагаются на aria-label.
Подключить библиотеку проще всего через unpkg одним тегом <link> или забрать с GitHub releases и npm (npm install 98.css).
Основа интерфейса — компоненты. Кнопки шириной 75px и высотой 23px получают выпуклые границы, а при нажатии становятся вдавленными. Класс default подсвечивает действие по умолчанию, disabled делает кнопку блёклой, а фокус отображается пунктирной рамкой. Чекбоксы и радио-кнопки (radio) обязательно оборачиваются в контейнер с классом field-row, чтобы сохранить отступы, и используют стандартные атрибуты checked и disabled. GroupBox собирается через тег <fieldset> с <legend> — получается рамка с заголовком.
TextBox — это <input type="text"> или <textarea>. Для размещения подписи над полем вместо field-row применяют field-row-stacked. Slider делается через <input type="range">, класс has-box-indicator меняет ползунок на прямоугольный, а обёртка is-vertical разворачивает его вертикально. Dropdown рендерится обычным <select> с <option>, выбранный пункт задаётся атрибутом selected.
Окна строятся из нескольких слоёв. Title Bar использует классы title-bar, title-bar-text и title-bar-controls. Кнопки сворачивания, разворачивания, восстановления, справки и закрытия можно задавать либо через aria-label (Minimize, Maximize, Restore, Help, Close), либо через соответствующие CSS-классы на кнопке (minimize, maximize, restore, help, close). Добавив класс inactive, заголовок делается неактивным, а disabled на кнопке максимизации блокирует её. Контейнер окна — <div class="window">, а содержимое кладётся в <div class="window-body">. Снизу можно добавить Status Bar с классом status-bar и дочерними status-bar-field.
Для вывода иерархий есть TreeView — <ul class="tree-view">. Вложенные списки автоматически получают отступы и пунктир. Чтобы ветки сворачивались, достаточно обернуть дочерний <ul> в <details> с <summary>. Tabs строятся на элементе <menu role="tablist">, каждый пункт получает role="tab". Активная вкладка помечается aria-selected="true"; переключение нужно дописывать на JavaScript. Класс multirows создаёт многострочные табы. TableView — обычная <table>, помещённая в sunken-panel для бордюра и прокрутки. Класс interactive добавляет курсор-указатель, а highlighted подсвечивает строку. В статье приведён пример скрипта для выделения строк по клику.
Progress Indicator бывает сплошным и сегментированным (класс segmented). Ширина заполнения задаётся через вложенный span.progress-indicator-bar со стилем width.
Отдельно выделены field-border, field-border-disabled и status-field-border — это минимальные стили границ и фона для рабочих областей, неактивных полей и динамического контента. Всё вместе даёт верстальщику готовый набор кирпичиков для ностальгического интерфейса под MIT-лицензией, а примеры использования с React и чистым JavaScript лежат на GitHub.