12 CSS Retro UI Designs 12 / 12
Retro Desktop Portfolio Website Template
A classic desktop-OS portfolio: a System-style menu bar with live clock, desktop folder icons, and stacked windows (about / projects / contact) you can drag and bring-to-focus.
The code
<div class="ret-12">
<div class="ret-12__menubar">
<span class="apple">❖</span>
<span>File</span><span>Edit</span><span>View</span><span>Special</span>
<span class="spacer"><span>◐ 88%</span><span class="clock" id="ret-12-clock">12:00 PM</span></span>
</div>
<div class="ret-12__desk" id="ret-12-desk">
<div class="ret-12__shortcuts">
<div class="ret-12__sc"><i>📁</i><span>Work</span></div>
<div class="ret-12__sc"><i>📄</i><span>Resume</span></div>
<div class="ret-12__sc"><i>🗑️</i><span>Trash</span></div>
</div>
<div class="ret-12__window ret-12__about is-focus" data-win>
<div class="ret-12__titlebar" data-drag><span class="dot r"></span><span class="dot"></span><b>about_me.txt</b><span class="x">▢</span></div>
<div class="ret-12__content">
<div class="ret-12__avatar">🧑💻</div>
<h2>Hi, I'm Mara.<small>// CREATIVE DEVELOPER</small></h2>
<p>I build playful interfaces with a soft spot for old machines. Drag these windows around — focus & drag are tiny vanilla JS, everything else is pure CSS.</p>
<div class="ret-12__tags"><span>CSS</span><span>Motion</span><span>WebGL</span><span>Type</span><span>Pixels</span></div>
</div>
</div>
<div class="ret-12__window ret-12__projects" data-win>
<div class="ret-12__titlebar" data-drag><span class="dot r"></span><span class="dot"></span><b>projects</b><span class="x">▢</span></div>
<div class="ret-12__content">
<h2 style="font-size:16px">Selected Work</h2>
<hr class="ret-12__divider">
<div class="ret-12__proj"><i>🎨</i><div class="meta"><b>Pixel Painter</b><small>Canvas · 2025</small></div><span class="arrow">→</span></div>
<div class="ret-12__proj"><i>🎹</i><div class="meta"><b>Synth Web Toy</b><small>WebAudio · 2024</small></div><span class="arrow">→</span></div>
<div class="ret-12__proj"><i>🌀</i><div class="meta"><b>CRT Shader Lab</b><small>GLSL · 2024</small></div><span class="arrow">→</span></div>
</div>
</div>
<div class="ret-12__window ret-12__contact" data-win>
<div class="ret-12__titlebar" data-drag><span class="dot r"></span><span class="dot"></span><b>contact</b><span class="x">▢</span></div>
<div class="ret-12__content">
<a href="#">→ [email protected]</a>
<a href="#">→ github.com/mara</a>
<a href="#">→ dribbble.com/mara</a>
<a href="#">→ read.cv/mara</a>
</div>
</div>
<div class="ret-12__hint">▲ drag any title bar · click to focus ▲</div>
</div>
</div> <div class="ret-12">
<div class="ret-12__menubar">
<span class="apple">❖</span>
<span>File</span><span>Edit</span><span>View</span><span>Special</span>
<span class="spacer"><span>◐ 88%</span><span class="clock" id="ret-12-clock">12:00 PM</span></span>
</div>
<div class="ret-12__desk" id="ret-12-desk">
<div class="ret-12__shortcuts">
<div class="ret-12__sc"><i>📁</i><span>Work</span></div>
<div class="ret-12__sc"><i>📄</i><span>Resume</span></div>
<div class="ret-12__sc"><i>🗑️</i><span>Trash</span></div>
</div>
<div class="ret-12__window ret-12__about is-focus" data-win>
<div class="ret-12__titlebar" data-drag><span class="dot r"></span><span class="dot"></span><b>about_me.txt</b><span class="x">▢</span></div>
<div class="ret-12__content">
<div class="ret-12__avatar">🧑💻</div>
<h2>Hi, I'm Mara.<small>// CREATIVE DEVELOPER</small></h2>
<p>I build playful interfaces with a soft spot for old machines. Drag these windows around — focus & drag are tiny vanilla JS, everything else is pure CSS.</p>
<div class="ret-12__tags"><span>CSS</span><span>Motion</span><span>WebGL</span><span>Type</span><span>Pixels</span></div>
</div>
</div>
<div class="ret-12__window ret-12__projects" data-win>
<div class="ret-12__titlebar" data-drag><span class="dot r"></span><span class="dot"></span><b>projects</b><span class="x">▢</span></div>
<div class="ret-12__content">
<h2 style="font-size:16px">Selected Work</h2>
<hr class="ret-12__divider">
<div class="ret-12__proj"><i>🎨</i><div class="meta"><b>Pixel Painter</b><small>Canvas · 2025</small></div><span class="arrow">→</span></div>
<div class="ret-12__proj"><i>🎹</i><div class="meta"><b>Synth Web Toy</b><small>WebAudio · 2024</small></div><span class="arrow">→</span></div>
<div class="ret-12__proj"><i>🌀</i><div class="meta"><b>CRT Shader Lab</b><small>GLSL · 2024</small></div><span class="arrow">→</span></div>
</div>
</div>
<div class="ret-12__window ret-12__contact" data-win>
<div class="ret-12__titlebar" data-drag><span class="dot r"></span><span class="dot"></span><b>contact</b><span class="x">▢</span></div>
<div class="ret-12__content">
<a href="#">→ [email protected]</a>
<a href="#">→ github.com/mara</a>
<a href="#">→ dribbble.com/mara</a>
<a href="#">→ read.cv/mara</a>
</div>
</div>
<div class="ret-12__hint">▲ drag any title bar · click to focus ▲</div>
</div>
</div>@import url('https://fonts.googleapis.com/css2?family=Chicago&family=Pixelify+Sans:wght@400;700&family=Space+Mono:wght@400;700&display=swap');
.ret-12, .ret-12 *, .ret-12 *::before, .ret-12 *::after { box-sizing: border-box; margin: 0; padding: 0; }
.ret-12 ::selection{background:#000;color:#d6f5e3}
.ret-12{
--bg:#3a6b5e;
--win:#e8e4d8;
--ink:#1a1a1a;
--bar:#1a1a1a;
--accent:#ff5a3c;
--accent2:#3c7dff;
--line:#1a1a1a;
font-family:'Space Mono',monospace;
background:var(--bg);
background-image:radial-gradient(rgba(255,255,255,.06) 1px,transparent 1px);
background-size:6px 6px;
min-height:100vh;position:relative;overflow:hidden;color:var(--ink);
padding:10px;
}
/* menu bar */
.ret-12__menubar{display:flex;align-items:center;gap:18px;background:var(--win);border:2px solid var(--ink);padding:5px 14px;
box-shadow:3px 3px 0 var(--ink);font-family:'Pixelify Sans';font-size:15px;position:relative;z-index:100}
.ret-12__menubar .apple{font-weight:700}
.ret-12__menubar span{cursor:default}
.ret-12__menubar .spacer{margin-left:auto;font-size:13px;display:flex;gap:14px;align-items:center}
.ret-12__menubar .clock{font-family:'Space Mono';font-size:12px}
.ret-12__desk{position:relative;height:calc(100vh - 70px);margin-top:10px}
/* desktop folder icons */
.ret-12__shortcuts{position:absolute;top:6px;right:6px;display:flex;flex-direction:column;gap:18px;z-index:1}
.ret-12__sc{width:74px;text-align:center;cursor:pointer;color:var(--win);text-shadow:1px 1px 0 #000}
.ret-12__sc i{display:block;font-size:30px;filter:drop-shadow(2px 2px 0 rgba(0,0,0,.4))}
.ret-12__sc span{font-size:11px;font-family:'Pixelify Sans';display:inline-block;margin-top:3px;padding:1px 4px}
.ret-12__sc:hover span{background:var(--ink);color:var(--win)}
/* windows */
.ret-12__window{position:absolute;background:var(--win);border:2px solid var(--ink);box-shadow:5px 5px 0 rgba(0,0,0,.5);
display:flex;flex-direction:column;min-width:240px}
.ret-12__window.is-focus{box-shadow:7px 7px 0 var(--ink);z-index:50}
.ret-12__titlebar{display:flex;align-items:center;gap:8px;background:var(--bar);color:var(--win);padding:5px 8px;cursor:grab;user-select:none}
.ret-12__titlebar.is-drag{cursor:grabbing}
.ret-12__titlebar .dot{width:13px;height:13px;border:2px solid var(--win);border-radius:50%;flex:0 0 auto}
.ret-12__titlebar .dot.r{background:var(--accent)}
.ret-12__titlebar b{font-family:'Pixelify Sans';font-size:14px;letter-spacing:.02em;flex:1;
background:repeating-linear-gradient(var(--win) 0 1px,transparent 1px 3px);padding:2px 8px;text-align:center;color:var(--win)}
.ret-12__titlebar .x{margin-left:auto}
.ret-12__content{padding:16px;font-size:12px;line-height:1.55}
.ret-12__content h2{font-family:'Pixelify Sans';font-size:20px;margin-bottom:4px}
.ret-12__content h2 small{display:block;font-family:'Space Mono';font-size:11px;color:#5a6b64;letter-spacing:.1em;margin-top:4px}
.ret-12__content p{color:#3a3a3a}
.ret-12__divider{border:0;border-top:2px dashed var(--ink);margin:12px 0}
/* about window */
.ret-12__about{width:300px;top:18px;left:14px}
.ret-12__avatar{width:64px;height:64px;border:2px solid var(--ink);float:left;margin:0 14px 8px 0;
background:repeating-conic-gradient(var(--accent) 0 90deg,var(--accent2) 0 180deg) 0 0/16px 16px;display:grid;place-items:center;font-size:30px;background-blend-mode:multiply}
.ret-12__tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px;clear:both}
.ret-12__tags span{font-size:10px;border:1.5px solid var(--ink);padding:3px 7px;font-family:'Pixelify Sans'}
/* projects window */
.ret-12__projects{width:330px;top:120px;left:230px}
@media(max-width:680px){.ret-12__projects{left:14px;top:300px}}
.ret-12__proj{display:flex;align-items:center;gap:10px;border:1.5px solid var(--ink);padding:9px;margin-bottom:8px;cursor:pointer;transition:transform .1s,background .1s}
.ret-12__proj:hover{transform:translate(-2px,-2px);background:#fff;box-shadow:3px 3px 0 var(--ink)}
.ret-12__proj i{font-size:22px}
.ret-12__proj .meta b{font-family:'Pixelify Sans';font-size:13px;display:block}
.ret-12__proj .meta small{font-size:10px;color:#5a6b64}
.ret-12__proj .arrow{margin-left:auto;font-weight:700}
/* contact window */
.ret-12__contact{width:248px;top:330px;left:30px}
@media(max-width:680px){.ret-12__contact{display:none}}
.ret-12__contact a{display:block;color:var(--accent2);text-decoration:none;border-bottom:1px dotted var(--accent2);padding:4px 0;font-size:12px}
.ret-12__contact a:hover{background:var(--accent2);color:#fff;padding-left:6px}
.ret-12__hint{position:absolute;bottom:6px;left:50%;transform:translateX(-50%);font-size:10px;color:rgba(255,255,255,.7);letter-spacing:.1em;z-index:1}
@media(max-width:680px){.ret-12__about{left:14px;width:calc(100% - 60px);max-width:300px}.ret-12__shortcuts{display:none}}
@media (prefers-reduced-motion: reduce){.ret-12 *{transition:none !important}} @import url('https://fonts.googleapis.com/css2?family=Chicago&family=Pixelify+Sans:wght@400;700&family=Space+Mono:wght@400;700&display=swap');
.ret-12, .ret-12 *, .ret-12 *::before, .ret-12 *::after { box-sizing: border-box; margin: 0; padding: 0; }
.ret-12 ::selection{background:#000;color:#d6f5e3}
.ret-12{
--bg:#3a6b5e;
--win:#e8e4d8;
--ink:#1a1a1a;
--bar:#1a1a1a;
--accent:#ff5a3c;
--accent2:#3c7dff;
--line:#1a1a1a;
font-family:'Space Mono',monospace;
background:var(--bg);
background-image:radial-gradient(rgba(255,255,255,.06) 1px,transparent 1px);
background-size:6px 6px;
min-height:100vh;position:relative;overflow:hidden;color:var(--ink);
padding:10px;
}
/* menu bar */
.ret-12__menubar{display:flex;align-items:center;gap:18px;background:var(--win);border:2px solid var(--ink);padding:5px 14px;
box-shadow:3px 3px 0 var(--ink);font-family:'Pixelify Sans';font-size:15px;position:relative;z-index:100}
.ret-12__menubar .apple{font-weight:700}
.ret-12__menubar span{cursor:default}
.ret-12__menubar .spacer{margin-left:auto;font-size:13px;display:flex;gap:14px;align-items:center}
.ret-12__menubar .clock{font-family:'Space Mono';font-size:12px}
.ret-12__desk{position:relative;height:calc(100vh - 70px);margin-top:10px}
/* desktop folder icons */
.ret-12__shortcuts{position:absolute;top:6px;right:6px;display:flex;flex-direction:column;gap:18px;z-index:1}
.ret-12__sc{width:74px;text-align:center;cursor:pointer;color:var(--win);text-shadow:1px 1px 0 #000}
.ret-12__sc i{display:block;font-size:30px;filter:drop-shadow(2px 2px 0 rgba(0,0,0,.4))}
.ret-12__sc span{font-size:11px;font-family:'Pixelify Sans';display:inline-block;margin-top:3px;padding:1px 4px}
.ret-12__sc:hover span{background:var(--ink);color:var(--win)}
/* windows */
.ret-12__window{position:absolute;background:var(--win);border:2px solid var(--ink);box-shadow:5px 5px 0 rgba(0,0,0,.5);
display:flex;flex-direction:column;min-width:240px}
.ret-12__window.is-focus{box-shadow:7px 7px 0 var(--ink);z-index:50}
.ret-12__titlebar{display:flex;align-items:center;gap:8px;background:var(--bar);color:var(--win);padding:5px 8px;cursor:grab;user-select:none}
.ret-12__titlebar.is-drag{cursor:grabbing}
.ret-12__titlebar .dot{width:13px;height:13px;border:2px solid var(--win);border-radius:50%;flex:0 0 auto}
.ret-12__titlebar .dot.r{background:var(--accent)}
.ret-12__titlebar b{font-family:'Pixelify Sans';font-size:14px;letter-spacing:.02em;flex:1;
background:repeating-linear-gradient(var(--win) 0 1px,transparent 1px 3px);padding:2px 8px;text-align:center;color:var(--win)}
.ret-12__titlebar .x{margin-left:auto}
.ret-12__content{padding:16px;font-size:12px;line-height:1.55}
.ret-12__content h2{font-family:'Pixelify Sans';font-size:20px;margin-bottom:4px}
.ret-12__content h2 small{display:block;font-family:'Space Mono';font-size:11px;color:#5a6b64;letter-spacing:.1em;margin-top:4px}
.ret-12__content p{color:#3a3a3a}
.ret-12__divider{border:0;border-top:2px dashed var(--ink);margin:12px 0}
/* about window */
.ret-12__about{width:300px;top:18px;left:14px}
.ret-12__avatar{width:64px;height:64px;border:2px solid var(--ink);float:left;margin:0 14px 8px 0;
background:repeating-conic-gradient(var(--accent) 0 90deg,var(--accent2) 0 180deg) 0 0/16px 16px;display:grid;place-items:center;font-size:30px;background-blend-mode:multiply}
.ret-12__tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px;clear:both}
.ret-12__tags span{font-size:10px;border:1.5px solid var(--ink);padding:3px 7px;font-family:'Pixelify Sans'}
/* projects window */
.ret-12__projects{width:330px;top:120px;left:230px}
@media(max-width:680px){.ret-12__projects{left:14px;top:300px}}
.ret-12__proj{display:flex;align-items:center;gap:10px;border:1.5px solid var(--ink);padding:9px;margin-bottom:8px;cursor:pointer;transition:transform .1s,background .1s}
.ret-12__proj:hover{transform:translate(-2px,-2px);background:#fff;box-shadow:3px 3px 0 var(--ink)}
.ret-12__proj i{font-size:22px}
.ret-12__proj .meta b{font-family:'Pixelify Sans';font-size:13px;display:block}
.ret-12__proj .meta small{font-size:10px;color:#5a6b64}
.ret-12__proj .arrow{margin-left:auto;font-weight:700}
/* contact window */
.ret-12__contact{width:248px;top:330px;left:30px}
@media(max-width:680px){.ret-12__contact{display:none}}
.ret-12__contact a{display:block;color:var(--accent2);text-decoration:none;border-bottom:1px dotted var(--accent2);padding:4px 0;font-size:12px}
.ret-12__contact a:hover{background:var(--accent2);color:#fff;padding-left:6px}
.ret-12__hint{position:absolute;bottom:6px;left:50%;transform:translateX(-50%);font-size:10px;color:rgba(255,255,255,.7);letter-spacing:.1em;z-index:1}
@media(max-width:680px){.ret-12__about{left:14px;width:calc(100% - 60px);max-width:300px}.ret-12__shortcuts{display:none}}
@media (prefers-reduced-motion: reduce){.ret-12 *{transition:none !important}}(() => {
const root = document.querySelector('.ret-12');
if (!root) return;
const desk = root.querySelector('#ret-12-desk');
const wins = Array.from(root.querySelectorAll('[data-win]'));
let z = 50;
function focus(win){
wins.forEach(w => w.classList.remove('is-focus'));
win.classList.add('is-focus');
win.style.zIndex = ++z;
}
wins.forEach(win => {
win.addEventListener('mousedown', () => focus(win), true);
const bar = win.querySelector('[data-drag]');
let sx, sy, ox, oy, dragging = false;
const start = (cx, cy) => {
dragging = true; focus(win);
const r = win.getBoundingClientRect();
const d = desk.getBoundingClientRect();
ox = r.left - d.left; oy = r.top - d.top; sx = cx; sy = cy;
win.style.left = ox + 'px'; win.style.top = oy + 'px'; win.style.right = 'auto';
bar.classList.add('is-drag');
};
const move = (cx, cy) => {
if (!dragging) return;
let nx = ox + (cx - sx), ny = oy + (cy - sy);
const d = desk.getBoundingClientRect();
nx = Math.max(0, Math.min(nx, d.width - 60));
ny = Math.max(0, Math.min(ny, d.height - 30));
win.style.left = nx + 'px'; win.style.top = ny + 'px';
};
const end = () => { dragging = false; bar.classList.remove('is-drag'); };
bar.addEventListener('mousedown', e => { e.preventDefault(); start(e.clientX, e.clientY); });
window.addEventListener('mousemove', e => move(e.clientX, e.clientY));
window.addEventListener('mouseup', end);
bar.addEventListener('touchstart', e => { start(e.touches[0].clientX, e.touches[0].clientY); }, {passive:true});
window.addEventListener('touchmove', e => { if(dragging){ move(e.touches[0].clientX, e.touches[0].clientY); } }, {passive:true});
window.addEventListener('touchend', end);
});
const clock = root.querySelector('#ret-12-clock');
const tick = () => {
const d = new Date();
let h = d.getHours(), m = String(d.getMinutes()).padStart(2,'0');
const ap = h >= 12 ? 'PM' : 'AM'; h = h % 12 || 12;
clock.textContent = `${h}:${m} ${ap}`;
};
tick(); setInterval(tick, 10000);
})(); (() => {
const root = document.querySelector('.ret-12');
if (!root) return;
const desk = root.querySelector('#ret-12-desk');
const wins = Array.from(root.querySelectorAll('[data-win]'));
let z = 50;
function focus(win){
wins.forEach(w => w.classList.remove('is-focus'));
win.classList.add('is-focus');
win.style.zIndex = ++z;
}
wins.forEach(win => {
win.addEventListener('mousedown', () => focus(win), true);
const bar = win.querySelector('[data-drag]');
let sx, sy, ox, oy, dragging = false;
const start = (cx, cy) => {
dragging = true; focus(win);
const r = win.getBoundingClientRect();
const d = desk.getBoundingClientRect();
ox = r.left - d.left; oy = r.top - d.top; sx = cx; sy = cy;
win.style.left = ox + 'px'; win.style.top = oy + 'px'; win.style.right = 'auto';
bar.classList.add('is-drag');
};
const move = (cx, cy) => {
if (!dragging) return;
let nx = ox + (cx - sx), ny = oy + (cy - sy);
const d = desk.getBoundingClientRect();
nx = Math.max(0, Math.min(nx, d.width - 60));
ny = Math.max(0, Math.min(ny, d.height - 30));
win.style.left = nx + 'px'; win.style.top = ny + 'px';
};
const end = () => { dragging = false; bar.classList.remove('is-drag'); };
bar.addEventListener('mousedown', e => { e.preventDefault(); start(e.clientX, e.clientY); });
window.addEventListener('mousemove', e => move(e.clientX, e.clientY));
window.addEventListener('mouseup', end);
bar.addEventListener('touchstart', e => { start(e.touches[0].clientX, e.touches[0].clientY); }, {passive:true});
window.addEventListener('touchmove', e => { if(dragging){ move(e.touches[0].clientX, e.touches[0].clientY); } }, {passive:true});
window.addEventListener('touchend', end);
});
const clock = root.querySelector('#ret-12-clock');
const tick = () => {
const d = new Date();
let h = d.getHours(), m = String(d.getMinutes()).padStart(2,'0');
const ap = h >= 12 ? 'PM' : 'AM'; h = h % 12 || 12;
clock.textContent = `${h}:${m} ${ap}`;
};
tick(); setInterval(tick, 10000);
})();More from 12 CSS Retro UI Designs
ASCII Art Web Interface CodeRetro Windows 95 UI (CSS Template)Retro Futuristic Terminal UI Code8 Bit Pixel Art UI Elements & ButtonsNeo Brutalist UI Components ExamplesRetro Cassette Player UI Web ComponentVaporwave Aesthetic Website Theme DesignRetro Arcade Game UI Kit90s Website Guestbook WidgetY2K Style Web UI KitRetro Clothing Store Web UI Design
View the full collection →