Compare commits

..

12 commits

Author SHA1 Message Date
592eb87c9e feat: .button 2026-05-13 01:29:09 +02:00
Jordan Scales
b1d7a90737 make badges in docs/ 29px tall so the screen doesn't jank 2025-09-07 09:40:26 -04:00
Jordan Scales
7240fe4bcc add heights to github badges so the screen doesn't jank 2025-09-07 09:34:38 -04:00
Jordan Scales
e8302a52ba
I don't use twitter anymore 2025-09-07 09:28:04 -04:00
Jordan Scales
517d174b30 bump to 0.1.21 2025-04-28 17:58:50 -04:00
Juani Garay
dc3b4488d6
Merge pull request #204 from frankier/add-field-borders
Add classes for generic usages of (status) field borders
2024-11-30 12:42:48 -03:00
Juani Garay
880ac4ffa0
Merge pull request #206 from OverflowCat/patch-1
Add support for input type url
2024-11-30 12:38:59 -03:00
Juani Garay
ec6b394eeb
Merge pull request #208 from henrik2000/patch-1
Disable text selection on form labels
2024-11-27 00:03:58 -03:00
Jordan Scales
82ba586bc3
Remove username/password from docs
Password managers do weird things for these :(
2024-11-06 08:40:34 -05:00
henrik2000
d5e607a73c
Disable text selection on form labels
When double-clicking on a form label it currently gets a text selection which can be confusing. This is not the Windows 98 behaviour. Fixed with this change.
2024-11-06 08:42:44 +01:00
ᡥᠠᡳᡤᡳᠶᠠ ᡥᠠᠯᠠ·ᠨᡝᡴᠣ 猫
c28706f265
Add support for input type url 2024-09-13 12:21:57 +08:00
Frankie Robertson
4674ef949f Add classes for generic usages of (status) field borders 2024-08-07 14:24:55 +03:00
6 changed files with 116 additions and 72 deletions

View file

@ -1,23 +0,0 @@
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
name: Publish to NPM
on:
workflow_dispatch:
release:
types: [published]
jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm run release
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

View file

@ -1,7 +1,7 @@
## 98.css ## 98.css
[![npm](https://98badges.now.sh/api/version)](http://npm.im/98.css) <a href="https://npm.im/98.css"><img height="29" alt="npm" src="https://98badges.now.sh/api/version" /></a>
[![gzip size](https://98badges.now.sh/api/size)](https://unpkg.com/98.css) <a href="https://unpkg.com/98.css"><img height="29" alt="gzip size" src="https://98badges.now.sh/api/size" /></a>
A design system for building faithful recreations of old UIs. A design system for building faithful recreations of old UIs.
@ -63,7 +63,7 @@ You can run a build manually with `npm run build`. This will write to the `dist/
Refer to [the GitHub issues page](https://github.com/jdan/98.css/issues) to see bugs in my CSS or report new ones. I'd really like to see your pull requests (especially those new to open-source!) and will happily provide code review. 98.css is a fun, silly project and I'd like to make it a fun place to build your open-source muscle. Refer to [the GitHub issues page](https://github.com/jdan/98.css/issues) to see bugs in my CSS or report new ones. I'd really like to see your pull requests (especially those new to open-source!) and will happily provide code review. 98.css is a fun, silly project and I'd like to make it a fun place to build your open-source muscle.
Thank you for checking my little project out, I hope it brought you some joy today. Consider [starring/following along on GitHub](https://github.com/jdan/98.css/stargazers) and maybe subscribing to more fun things on [my twitter](https://twitter.com/jdan). 👋 Thank you for checking my little project out, I hope it brought you some joy today. Consider [starring/following along on GitHub](https://github.com/jdan/98.css/stargazers) and maybe reading my posts on [Bluesky](https://bsky.app/profile/jdan.me). 👋
### Publishing ### Publishing

View file

@ -44,6 +44,7 @@
<li><a href="#tabs">Tabs</a></li> <li><a href="#tabs">Tabs</a></li>
<li><a href="#table-view">TableView</a></li> <li><a href="#table-view">TableView</a></li>
<li><a href="#progress-indicator">Progress Indicator</a></li> <li><a href="#progress-indicator">Progress Indicator</a></li>
<li><a href="#field-borders">Field borders</a></li>
</ul> </ul>
</li> </li>
<li><a href="#issues-contributing-etc">Issues, Contributing, etc.</a></li> <li><a href="#issues-contributing-etc">Issues, Contributing, etc.</a></li>
@ -57,10 +58,10 @@
<p> <p>
<a href="http://npm.im/98.css" rel="nofollow" style="text-decoration: none"> <a href="http://npm.im/98.css" rel="nofollow" style="text-decoration: none">
<img alt="npm" src="https://98badges.now.sh/api/version" style="max-width:100%;"> <img height="29" alt="npm" src="https://98badges.now.sh/api/version" style="max-width:100%;">
</a> </a>
<a href="https://unpkg.com/98.css" rel="nofollow" style="text-decoration: none"> <a href="https://unpkg.com/98.css" rel="nofollow" style="text-decoration: none">
<img alt="gzip size" src="https://98badges.now.sh/api/size" style="max-width:100%;"> <img height="29" alt="gzip size" src="https://98badges.now.sh/api/size" style="max-width:100%;">
</a> </a>
</p> </p>
@ -146,8 +147,8 @@
<input type="reset" /> `)%> <input type="reset" /> `)%>
<p> <p>
You can add the class <code>default</code> to any button to apply additional styling, You can add the class <code>default</code> to any button to apply additional styling,
useful when communicating to the user what default action would happen in the active window if useful when communicating to the user what default action would happen in the active window if
the <kbd>Enter</kbd> key was pressed on Windows 98. the <kbd>Enter</kbd> key was pressed on Windows 98.
</p> </p>
@ -413,34 +414,6 @@
<input id="text${getCurrentId()}" disabled type="text" value="Windows Green"/> <input id="text${getCurrentId()}" disabled type="text" value="Windows Green"/>
</div> </div>
`) %> `) %>
<p>
Other types of HTML5 text inputs are also supported.
</p>
<%- example(`
<div class="field-row-stacked" style="width: 200px">
<label for="text${getNewId()}">Email</label>
<input id="text${getCurrentId()}" type="email" value="admin@contoso.com"/>
</div>
<div class="field-row-stacked" style="width: 200px">
<label for="text${getNewId()}">Phone</label>
<input id="text${getCurrentId()}" type="tel" value="636-555-3226"/>
</div>
<div class="field-row-stacked" style="width: 200px">
<label for="text${getNewId()}">Password</label>
<input id="text${getCurrentId()}" type="password" value="hunter2"/>
</div>
<div class="field-row-stacked" style="width: 200px">
<label for="text${getNewId()}">Favorite Number</label>
<input id="text${getCurrentId()}" type="number" value="98"/>
</div>
<div class="field-row-stacked" style="width: 200px">
<label for="text${getNewId()}">Search</label>
<input id="text${getCurrentId()}" type="search" value="98 css"/>
</div>
`) %>
</div> </div>
@ -1073,6 +1046,66 @@
</div> </div>
</section> </section>
<section class="component">
<h3 id="field-borders">Field borders</a></li></h3>
<div>
<blockquote>
Text boxes, check boxes, drop-down list boxes, spin boxes and list
boxes use the <em>field border style</em>. You can also use the style
for define the work area within a window. It uses the sunken outer and
sunken inner basic border styles.
For most controls, the interior of the field uses the button highlight
color. For text fields, such as text boxes and combo boxes, the
interior uses the button face color when the field is read-only or
disabled.
<footer>
&mdash; Microsoft Windows User Experience p. 421
</footer>
</blockquote>
<blockquote>
Status fields use the <em>status field border style</em>. This style
uses only the sunken outer basic border style. You use the status
field style in status bars and other read-only fields where the
content of the file can change dynamically.
<footer>
&mdash; Microsoft Windows User Experience p. 422
</footer>
</blockquote>
As mentioned in these guidelines, these styles are used in other
contexts than just form elements and status fields such as to indicate
work areas and dynamic content. For that reason, we provide three
classes for these generic usages, <code>field-border</code>,
<code>field-border-disabled</code>, and
<code>status-field-border</code>. These classes only define the border
and background color and minimal padding, so you will typically need to
at least provide some extra padding yourself.
<%- example(`
<div class="field-border" style="padding: 8px">
Work area
</div>
`) %>
<%- example(`
<div class="field-border-disabled" style="padding: 8px">
Disabled work area
</div>
`) %>
<%- example(`
<div class="status-field-border" style="padding: 8px">
Dynamic content
</div>
`) %>
</div>
</section>
<h2 id="issues-contributing-etc">Issues, Contributing, etc.</h2> <h2 id="issues-contributing-etc">Issues, Contributing, etc.</h2>
<p> <p>

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{ {
"name": "98.css", "name": "98.css",
"version": "0.1.20", "version": "0.1.21",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "98.css", "name": "98.css",
"version": "0.1.20", "version": "0.1.21",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"chokidar": "^3.3.1", "chokidar": "^3.3.1",

View file

@ -1,6 +1,6 @@
{ {
"name": "98.css", "name": "98.css",
"version": "0.1.20", "version": "0.1.21",
"description": "A design system for building faithful recreations of old UIs", "description": "A design system for building faithful recreations of old UIs",
"main": "dist/98.css", "main": "dist/98.css",
"directories": { "directories": {

View file

@ -73,6 +73,7 @@
--border-field: inset -1px -1px var(--button-highlight), --border-field: inset -1px -1px var(--button-highlight),
inset 1px 1px var(--button-shadow), inset -2px -2px var(--button-face), inset 1px 1px var(--button-shadow), inset -2px -2px var(--button-face),
inset 2px 2px var(--window-frame); inset 2px 2px var(--window-frame);
--border-status-field: inset -1px -1px var(--button-face), inset 1px 1px var(--button-shadow);
/* Tabs */ /* Tabs */
--border-tab: inset -1px 0 var(--window-frame), --border-tab: inset -1px 0 var(--window-frame),
@ -104,6 +105,7 @@ body {
} }
button, button,
.button,
label, label,
input, input,
legend, legend,
@ -142,6 +144,7 @@ u {
} }
button, button,
.button,
input[type="submit"], input[type="submit"],
input[type="reset"] { input[type="reset"] {
box-sizing: border-box; box-sizing: border-box;
@ -158,6 +161,7 @@ input[type="reset"] {
} }
button.default, button.default,
.button.default,
input[type="submit"].default, input[type="submit"].default,
input[type="reset"].default { input[type="reset"].default {
box-shadow: var(--default-button-border-raised-outer), var(--default-button-border-raised-inner); box-shadow: var(--default-button-border-raised-outer), var(--default-button-border-raised-inner);
@ -171,27 +175,30 @@ input[type="reset"].default {
} }
button:not(:disabled):active, button:not(:disabled):active,
button:not(:disabled).active,
.button:not(:disabled):active,
.button:not(:disabled).active,
input[type="submit"]:not(:disabled):active, input[type="submit"]:not(:disabled):active,
input[type="reset"]:not(:disabled):active { input[type="submit"]:not(:disabled).active,
input[type="reset"]:not(:disabled):active,
input[type="reset"]:not(:disabled).active {
box-shadow: var(--border-sunken-outer), var(--border-sunken-inner); box-shadow: var(--border-sunken-outer), var(--border-sunken-inner);
text-shadow: 1px 1px var(--text-color); text-shadow: 1px 1px var(--text-color);
} }
button.default:not(:disabled):active, button.default:not(:disabled):active,
.button.default:not(:disabled):active,
input[type="submit"].default:not(:disabled):active, input[type="submit"].default:not(:disabled):active,
input[type="reset"].default:not(:disabled):active { input[type="reset"].default:not(:disabled):active,
button.default:not(:disabled).active,
.button.default:not(:disabled).active,
input[type="submit"].default:not(:disabled).active,
input[type="reset"].default:not(:disabled).active {
box-shadow: var(--default-button-border-sunken-outer), var(--default-button-border-sunken-inner); box-shadow: var(--default-button-border-sunken-outer), var(--default-button-border-sunken-inner);
} }
@media (not(hover)) {
button:not(:disabled):hover,
input[type="submit"]:not(:disabled):hover,
input[type="reset"]:not(:disabled):hover {
box-shadow: var(--border-sunken-outer), var(--border-sunken-inner);
}
}
button:focus, button:focus,
.button:focus,
input[type="submit"]:focus, input[type="submit"]:focus,
input[type="reset"]:focus { input[type="reset"]:focus {
outline: 1px dotted #000000; outline: 1px dotted #000000;
@ -199,6 +206,7 @@ input[type="reset"]:focus {
} }
button::-moz-focus-inner, button::-moz-focus-inner,
.button::-moz-focus-inner,
input[type="submit"]::-moz-focus-inner, input[type="submit"]::-moz-focus-inner,
input[type="reset"]::-moz-focus-inner { input[type="reset"]::-moz-focus-inner {
border: 0; border: 0;
@ -212,6 +220,7 @@ input[readonly] + label {
} }
button:disabled, button:disabled,
.button:disabled,
input[type="submit"]:disabled, input[type="submit"]:disabled,
input[type="reset"]:disabled, input[type="reset"]:disabled,
:disabled + label { :disabled + label {
@ -320,7 +329,7 @@ input[type="reset"]:disabled,
} }
.status-bar-field { .status-bar-field {
box-shadow: inset -1px -1px #dfdfdf, inset 1px 1px #808080; box-shadow: var(--border-status-field);
flex-grow: 1; flex-grow: 1;
padding: 2px 3px; padding: 2px 3px;
margin: 0; margin: 0;
@ -366,6 +375,7 @@ legend {
label { label {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
user-select: none;
} }
input[type="radio"], input[type="radio"],
@ -474,6 +484,7 @@ input[type="checkbox"][disabled]:checked + label::after {
input[type="text"], input[type="text"],
input[type="password"], input[type="password"],
input[type="email"], input[type="email"],
input[type="url"],
input[type="tel"], input[type="tel"],
input[type="number"], input[type="number"],
input[type="search"], input[type="search"],
@ -493,6 +504,7 @@ textarea {
input[type="text"], input[type="text"],
input[type="password"], input[type="password"],
input[type="email"], input[type="email"],
input[type="url"],
input[type="tel"], input[type="tel"],
input[type="search"], input[type="search"],
select { select {
@ -514,6 +526,7 @@ input[type="search"]::-webkit-search-results-decoration { display: none; }
input[type="text"], input[type="text"],
input[type="password"], input[type="password"],
input[type="email"], input[type="email"],
input[type="url"],
input[type="tel"], input[type="tel"],
input[type="number"], input[type="number"],
input[type="search"] { input[type="search"] {
@ -522,12 +535,14 @@ input[type="search"] {
} }
input[type="email"]:disabled, input[type="email"]:disabled,
input[type="url"]:disabled,
input[type="tel"]:disabled, input[type="tel"]:disabled,
input[type="password"]:disabled, input[type="password"]:disabled,
input[type="text"]:disabled, input[type="text"]:disabled,
input[type="number"]:disabled, input[type="number"]:disabled,
input[type="search"]:disabled, input[type="search"]:disabled,
input[type="email"]:read-only, input[type="email"]:read-only,
input[type="url"]:read-only,
input[type="tel"]:read-only, input[type="tel"]:read-only,
input[type="password"]:read-only, input[type="password"]:read-only,
input[type="text"]:read-only, input[type="text"]:read-only,
@ -553,6 +568,7 @@ select:focus,
input[type="text"]:focus, input[type="text"]:focus,
input[type="password"]:focus, input[type="password"]:focus,
input[type="email"]:focus, input[type="email"]:focus,
input[type="url"]:focus,
input[type="tel"]:focus, input[type="tel"]:focus,
input[type="number"]:focus, input[type="number"]:focus,
input[type="search"]:focus, input[type="search"]:focus,
@ -966,3 +982,21 @@ table > tbody > tr > * {
background-repeat: repeat; background-repeat: repeat;
background-size: 18px 100%; background-size: 18px 100%;
} }
.field-border {
background: var(--button-highlight);
box-shadow: var(--border-field);
padding: 2px;
}
.field-border-disabled {
background: var(--surface);
box-shadow: var(--border-field);
padding: 2px;
}
.status-field-border {
background: var(--surface);
box-shadow: var(--border-status-field);
padding: 1px;
}