@vstyler96/7.css
v2.0.0
Published
A design system for building faithful recreations of the Windows 7 UI.
Maintainers
Readme
7.css
7.css is a CSS framework that takes semantic HTML and styles them to the Windows 7 design. It is built on top of XP.css, which is an extension of 98.CSS.
It does not ship with any JavaScript, so it is compatible with your frontend framework of choice.
📦 Installation / Usage
Directly via unpkg:
<!DOCTYPE html>
<html>
<head>
<title>7.css example</title>
<meta charset="UTF-8" />
<link rel="stylesheet" href="https://unpkg.com/@vstyler96/7.css" />
</head>
<body>
<div class="window" style="margin: 32px; width: 250px">
<div class="title-bar">
<div class="title-bar-text">My First Program</div>
</div>
<div class="window-body">
<p>Hello, world!</p>
</div>
</div>
</body>
</html>Via npm:
npm install @vstyler96/7.cssThen import it as below:
import "@vstyler96/7.css/dist/7.css";The library does not style body. Set the page font yourself if you want it, e.g. body { font: var(--w7-font); }.
📁 Dist files
| File | What it is |
| --- | --- |
| dist/7.css | Full library. Styles bare elements (button, input, table, a, …) globally, CSS variables stay live. |
| dist/7.scoped.css | Same, but every selector is prefixed with .win7, so only content inside a .win7 wrapper is styled. |
| dist/7.inline.css | Same as 7.css with all CSS variables resolved to their values (for environments without custom properties). |
| dist/gui/<component>.css | One file per component, variables resolved, to pick only what you need. |
.win7 scope
Use 7.scoped.css when 7.css has to coexist with other styles. Selectors become descendant selectors, so put .win7 on a wrapper, not on the element itself:
<div class="win7">
<button>Styled</button>
</div>
<button>Not styled</button>The variables are defined on .win7 instead of :root in this build. @keyframes names (pulse-anim, progressbar, dialog-open, dialog-close) remain global.
--w7- variables
All theming goes through CSS custom properties prefixed --w7-, named --w7-<component>-<property>-<state>, e.g. --w7-el-bd-h (element border, hovered), --w7-el-grad-a (element gradient, active), --w7-lv-bg-alt (listview alternate row). Override them on :root (or on .win7 with the scoped build):
:root {
--w7-font: 10pt "Segoe UI", sans-serif;
--w7-lv-bg-alt: #eef3fa;
}🧩 Components
Most components are classless. Modifiers use is-* / has-* classes.
| Component | Markup | Modifiers / states |
| --- | --- | --- |
| Window | <div class="window"><div class="title-bar"><div class="title-bar-text">Title</div><div class="title-bar-controls"><button aria-label="Close"></button></div></div><div class="window-body">…</div><div class="status-bar"><p class="status-bar-field">…</p></div></div> | .active, .glass, .is-bright (white body), .window-body.has-space, .window-footer |
| Title-bar controls | <button aria-label="Minimize"> or <button class="is-minimize"> | Minimize, Maximize, Restore, Help, Close (aria-label or .is-*), :disabled |
| Dialog | <div class="window" role="dialog" id="dlg">…</div>, opened with <a href="#dlg"> | Shown via :target, with open/close animation |
| Button | <button>OK</button> | .default, .focused, .active, :disabled; also [role=button] and input[type=file] |
| Checkbox | <input type="checkbox" id="c"><label for="c">Label</label> | checked, disabled |
| Option button | <input type="radio" id="r" name="g"><label for="r">Label</label> | checked, disabled |
| Text box | <input type="text"> / <textarea> | Also url, email, number, password; disabled |
| Search box | <input type="search"> or <div class="searchbox"><input type="search"><button aria-label="search"></button></div> | |
| Combo box | <div class="combobox"><input type="text"><button></button><ul role="listbox"><li role="option">…</li></ul></div> | |
| Drop-down | <select><option>…</option></select> | disabled |
| List box | <select multiple> or <ul role="listbox"><li role="option" aria-selected="true">…</li></ul> | .has-shadow, .has-hover |
| ListView (table) | <table><thead><tr><th>…</th></tr></thead><tbody><tr><td>…</td></tr></tbody></table> | .has-shadow, .is-striped, .has-hover, .is-full; th.highlighted, th.indicator(.up), tr.highlighted; th.is-center / td.is-center |
| Tree view | <ul class="tree-view"><li>…<ul><li>…</li></ul></li></ul> (collapsible: <details><summary>) | .has-container, .has-connector, .has-collapse-button |
| Collapse | <details><summary>Title</summary>…</details> | open |
| Group box | <fieldset><legend>Title</legend>…</fieldset> | .group (stacked label + field) |
| Tabs | <menu role="tablist"><button aria-selected="true">Tab</button><button>Tab</button></menu><div role="tabpanel">…</div> | .justified, :disabled |
| Menu bar | <ul role="menubar"><li role="menuitem" tabindex="0">File</li></ul> | |
| Menu | <ul role="menu"><li role="menuitem"><a href="#">Item</a></li></ul> | aria-haspopup, aria-disabled, .has-divider, .can-hover (open submenus on hover), nested ul[role=menu] |
| Progress bar | <div role="progressbar"><div style="width: 40%"></div></div> | .paused, .error, .animate, .marquee (no inner div) |
| Slider | <input type="range"> | .has-box-indicator, wrapper .is-vertical, disabled |
| Spinner | <span class="spinner"></span> / <span class="loader"></span> | .animate |
| Balloon | <div role="tooltip">…</div> | .is-top, .is-bottom, .is-left, .is-right |
| Start button | <button class="start-button" aria-label="Start"></button> | .is-vista (orb without the glow), [aria-expanded="true"] (pressed) |
| Scrollbar | <div class="has-scrollbar" style="overflow: auto">…</div> | WebKit/Blink only |
| Typography | <a>, <h1 class="header-document">, <p class="instruction instruction-primary"> | .header-group, .instruction |
See the documentation page for live examples of each.
🛠 Developing
The core styles live in gui/ (PostCSS with nesting, .scss extension only). Common tasks go through make:
| Command | What it does |
| --- | --- |
| make build | Install dependencies if package-lock.json changed, then build dist/ and the docs |
| make preview | Build, then watch for changes and live-reload at http://localhost:3000 |
| make publish | Build and npm publish |
| make deploy | Build and push the docs (dist/) to GitHub Pages |
| make clean | Remove dist/ |
The underlying npm scripts (npm run build, npm run release, npm run deploy) still work.
📝 Changes since 0.17
2.0.0:
- The package moved from
7.cssto@vstyler96/7.css. - ListView modifiers:
table.is-striped,table.has-hover,table.is-full,th.is-center/td.is-center, with new variables--w7-lv-bg-alt,--w7-lv-bg-h,--w7-lv-bd-h. - Dialog open/close animation for
.window[role=dialog]. - Title-bar control icons render with
image-rendering: pixelated(no more blurry buttons). Makefilefor build / preview / publish / deploy / clean.
Since 0.18–0.21 (breaking if you come from 0.17):
- All CSS variables were renamed to the
--w7-*scheme (e.g.--font→--w7-font,--surface→--w7-surface,--button-*→--w7-el-*). Overrides written against 0.17 variables no longer apply. .field-row/.field-row-stackedwere replaced by.group..surfaceand the globalbody/heading/code/prestyles were removed.
📝 Issues, Contributing, etc.
You are so welcome to report issues, help out with contributions or whatever you could think of to improve this lovely UI framework.
⚙ Integrations
7.css has been seen adopted in the following JS framework projects by the community:
- Vue - win7-ui
- Svelte - svelte-7.css (work in progress)
📜 Changelog
Refer to Releases.
