Created Jun 2025
Popover à la Windows 95
HTML
<main>
<button popovertarget="window-exe" popovertargetaction="show">
In the manner of Windows 95, as one does.
</button>
<aside id="window-exe" popover>
<section>
<h2>window.exe</h2>
<form>
<label aria-label="Regular Size">
<input type="radio" name="state" value="normal" checked>
<span>Regular</span>
</label>
<label aria-label="Fullscreen">
<input type="radio" name="state" value="fullscreen">
<span>Fullscreen</span>
</label>
<button aria-label="Close" onclick="document.querySelector('#window-exe').hidePopover();return false;">Close</button>
</form>
</section>
<div>
<p>
I don't necessarily feel nostalgic about
Windows 95, but I do appreciate the aesthetic of the thing. I'm stunned that it's 30 years old.
</p>
<p>
It's fun to replicate some of the features
of the interface using current (2025) web techniques.
The Popover API (<a href="https://developer.mozilla.org/en-US/docs/Web/API/Popover_API">MDN</a>) is worth a look.
I don't believe I could articulate the number of times I created popovers of different sorts
using HTML and JavaScript and "Dynamic HTML" and now we can have it with nearly zero JavaScript.
<p>
<p>
I also like using Sass (<a href="https://sass-lang.com/">Sass</a>) to create stylesheets I can read logically. And playing with
CSS gradients is one of my greatest joys.
</p>
<p>Thanks for reading,<br>
<a href="https://artlung.com/">Joe (ArtLung)</a>
</p>
</div>
</aside>
</main>
SCSS
[popovertarget="window-exe"][popovertargetaction="show"] {
--size: 1.1;
color: #000;
border: none;
box-sizing: border-box;
height: 6.5lh;
padding: 5lh 0 0 0;
line-height: 1;
font-size: calc(var(--size) * 1rem);
text-wrap: nowrap;
image-rendering: pixelated;
justify-content: end;
align-items: end;
background: url("data:image/gif;base64,R0lGODlhIAAbAKIAAP//AMDAwP///wAAAICAgICAAP///wAAACH5BAUAAAYALAAAAAAgABsAAAN5aGrU7ivKGYm4GBPKpQUBKIbB1nEfOY7mWQVwLM9PXQ9Mpu88PwyplWooFBaAAqKyuDwGl1CmM8msRqfWrHIa7Rax3jCIqy2HwGYtWexFs63r9BUpVyPfbToefq/Pn35GfXtNeoFbQAWKi4yNjo+KOD+TlJWWl5MGCQA7")
50% 0 / 5lh 5lh no-repeat;
font-family: "-apple-system", BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
cursor: pointer;
&::first-line {
background: rgba(255,255,255,.5);
}
}
#window-exe {
--gradient-color-1: #02046a;
--gradient-color-2: #2182bf;
--title-color: #fff;
--text-color: #282828;
--window-color: #bfbfc1;
max-width: 80ch;
&:has(input[value="fullscreen"]:checked) {
max-width: unset;
width: 98vw;
height: 98vh;
}
font-family: "-apple-system", BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 1rem;
border: 2px solid;
border-color: var(--title-color) var(--text-color) var(--text-color)
var(--title-color);
background: var(--window-color);
> section {
background: linear-gradient(
90deg,
var(--gradient-color-1),
var(--gradient-color-2)
);
display: flex;
align-items: center;
h2 {
margin: 0;
flex-grow: 1;
padding: 0 0 0.1ch 0.5ch;
color: var(--title-color);
}
form {
font-size: 1rem;
display: flex;
gap: 0;
> * {
cursor: pointer;
margin: 4px 2px;
font-size: 1rem;
border: 2px solid;
border-color: var(--title-color) var(--text-color) var(--text-color)
var(--title-color);
display: flex;
justify-content: center;
align-items: center;
background: var(--window-color);
max-width: 3ch;
color: #0000;
overflow: hidden;
&:has(input:checked) {
cursor: not-allowed;
}
&:has(input[value="normal"]) {
background: linear-gradient(
to top,
var(--text-color) 4px,
#0000 0
) 50% 50% / 2ch 2ch no-repeat var(--window-color);
}
&:has(input[value="fullscreen"]) {
background: linear-gradient(
to top,
var(--text-color) 2px,
#0000 0
) 50% 50% / 2ch 2ch no-repeat,
linear-gradient(
to bottom,
var(--text-color) 4px,
#0000 0
) 50% 50% / 2ch 2ch no-repeat,
linear-gradient(
90deg,
var(--text-color) 2px,
#0000 0
) 50% 50% / 2ch 2ch no-repeat,
linear-gradient(
-90deg,
var(--text-color) 2px,
#0000 0
) 50% 50% / 2ch 2ch no-repeat var(--window-color);
}
&:is(button) {
background: linear-gradient(
45deg,
#0000 43%,
var(--text-color) 0 57%,
#0000 0
)
50% 50% / 2ch 2ch no-repeat,
linear-gradient(-45deg,
#0000 43%,
var(--text-color) 0 57%,
#0000 0
) 50% 50% / 2ch 2ch no-repeat var(--window-color);
}
}
input[type="radio"] {
display: none;
}
}
}
div {
padding: 0 1ch;
color: var(--text-color);
overflow: auto;
}
}
main {
background: #008080;
width: 100%;
height: 60vh;
box-sizing: border-box;
padding: 3lh;
}
CSS (compiled)
[popovertarget=window-exe][popovertargetaction=show]{--size: 1.1;color:#000;border:none;box-sizing:border-box;height:6.5lh;padding:5lh 0 0 0;line-height:1;font-size:calc(var(--size)*1rem);text-wrap:nowrap;image-rendering:pixelated;justify-content:end;align-items:end;background:url("data:image/gif;base64,R0lGODlhIAAbAKIAAP//AMDAwP///wAAAICAgICAAP///wAAACH5BAUAAAYALAAAAAAgABsAAAN5aGrU7ivKGYm4GBPKpQUBKIbB1nEfOY7mWQVwLM9PXQ9Mpu88PwyplWooFBaAAqKyuDwGl1CmM8msRqfWrHIa7Rax3jCIqy2HwGYtWexFs63r9BUpVyPfbToefq/Pn35GfXtNeoFbQAWKi4yNjo+KOD+TlJWWl5MGCQA7") 50% 0/5lh 5lh no-repeat;font-family:"-apple-system",BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";cursor:pointer}
[popovertarget=window-exe][popovertargetaction=show]::first-line{background:rgba(255,255,255,.5)}
#window-exe{--gradient-color-1: #02046a;--gradient-color-2: #2182bf;--title-color: #fff;--text-color: #282828;--window-color: #bfbfc1;max-width:80ch;font-family:"-apple-system",BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;border:2px solid;border-color:var(--title-color) var(--text-color) var(--text-color) var(--title-color);background:var(--window-color)}
#window-exe:has(input[value=fullscreen]:checked){max-width:unset;width:98vw;height:98vh}
#window-exe>section{background:linear-gradient(90deg, var(--gradient-color-1), var(--gradient-color-2));display:flex;align-items:center}
#window-exe>section h2{margin:0;flex-grow:1;padding:0 0 .1ch .5ch;color:var(--title-color)}
#window-exe>section form{font-size:1rem;display:flex;gap:0}
#window-exe>section form>*{cursor:pointer;margin:4px 2px;font-size:1rem;border:2px solid;border-color:var(--title-color) var(--text-color) var(--text-color) var(--title-color);display:flex;justify-content:center;align-items:center;background:var(--window-color);max-width:3ch;color:rgba(0,0,0,0);overflow:hidden}
#window-exe>section form>*:has(input:checked){cursor:not-allowed}
#window-exe>section form>*:has(input[value=normal]){background:linear-gradient(to top, var(--text-color) 4px, rgba(0, 0, 0, 0) 0) 50% 50%/2ch 2ch no-repeat var(--window-color)}
#window-exe>section form>*:has(input[value=fullscreen]){background:linear-gradient(to top, var(--text-color) 2px, rgba(0, 0, 0, 0) 0) 50% 50%/2ch 2ch no-repeat,linear-gradient(to bottom, var(--text-color) 4px, rgba(0, 0, 0, 0) 0) 50% 50%/2ch 2ch no-repeat,linear-gradient(90deg, var(--text-color) 2px, rgba(0, 0, 0, 0) 0) 50% 50%/2ch 2ch no-repeat,linear-gradient(-90deg, var(--text-color) 2px, rgba(0, 0, 0, 0) 0) 50% 50%/2ch 2ch no-repeat var(--window-color)}
#window-exe>section form>*:is(button){background:linear-gradient(45deg, rgba(0, 0, 0, 0) 43%, var(--text-color) 0 57%, rgba(0, 0, 0, 0) 0) 50% 50%/2ch 2ch no-repeat,linear-gradient(-45deg, rgba(0, 0, 0, 0) 43%, var(--text-color) 0 57%, rgba(0, 0, 0, 0) 0) 50% 50%/2ch 2ch no-repeat var(--window-color)}
#window-exe>section form input[type=radio]{display:none}
#window-exe div{padding:0 1ch;color:var(--text-color);overflow:auto}
main{background:teal;width:100%;height:60vh;box-sizing:border-box;padding:3lh}