Part of the Webcore kit
60% · about 2 minutes left
HTML
<div class="tv-webcore-progress" style="--tv-webcore-progress-value: 60%">
<div class="tv-webcore-progress-bar">
<span class="tv-webcore-progress-label">installing cuteness.exe</span>
<span class="tv-webcore-progress-close" aria-hidden="true"></span>
</div>
<div class="tv-webcore-progress-track" role="progressbar" aria-label="Installing cuteness.exe" aria-valuemin="0" aria-valuemax="100" aria-valuenow="60">
<span class="tv-webcore-progress-fill"></span>
</div>
<p class="tv-webcore-progress-note">60% · about 2 minutes left</p>
</div>
CSS
/* A pastel pop-up with a segmented block bar. Set the fill with --tv-webcore-progress-value. */
.tv-webcore-progress {
--tv-webcore-progress-face: var(--tv-webcore-pink, #f7b5e4);
--tv-webcore-progress-block: color-mix(in srgb, var(--tv-webcore-lilac, #a49bf3) 70%, var(--tv-webcore-navy, #2c2b9f));
box-sizing: border-box;
width: 100%;
max-width: 24rem;
margin: 0 auto;
padding: 4px 14px 12px;
border: 2px solid var(--tv-webcore-lilac, #a49bf3);
background: var(--tv-webcore-progress-face, #f7b5e4);
color: var(--tv-webcore-navy, #2c2b9f);
font-family: "Lucida Console", "Courier New", ui-monospace, monospace;
box-shadow: 4px 4px 0 color-mix(in srgb, var(--tv-webcore-navy, #2c2b9f) 25%, transparent);
}
.tv-webcore-progress-bar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
min-height: 28px;
}
.tv-webcore-progress-label {
overflow: hidden;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.1em;
text-overflow: ellipsis;
text-transform: uppercase;
white-space: nowrap;
}
.tv-webcore-progress-close {
position: relative;
flex-shrink: 0;
box-sizing: border-box;
width: 18px;
height: 16px;
border: 1px solid var(--tv-webcore-navy, #2c2b9f);
background: var(--tv-webcore-paper, #ffffff);
}
.tv-webcore-progress-close::before,
.tv-webcore-progress-close::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 10px;
height: 2px;
background: var(--tv-webcore-navy, #2c2b9f);
transform: translate(-50%, -50%) rotate(45deg);
}
.tv-webcore-progress-close::after {
transform: translate(-50%, -50%) rotate(-45deg);
}
.tv-webcore-progress-track {
box-sizing: border-box;
height: 24px;
margin-top: 6px;
padding: 3px;
overflow: hidden;
border: 1px solid var(--tv-webcore-navy, #2c2b9f);
background: color-mix(in srgb, var(--tv-webcore-lilac, #a49bf3) 22%, var(--tv-webcore-paper, #ffffff));
}
/* Blocks with gaps: each 10px block is followed by a 3px gap. */
.tv-webcore-progress-fill {
display: block;
width: var(--tv-webcore-progress-value, 60%);
height: 100%;
background: repeating-linear-gradient(90deg, var(--tv-webcore-progress-block, #7b72d4) 0 10px, transparent 10px 13px);
}
.tv-webcore-progress-note {
margin: 8px 0 0;
font-size: 12px;
letter-spacing: 0.05em;
text-align: right;
}
.tv-webcore-progress--lilac {
--tv-webcore-progress-face: var(--tv-webcore-lilac, #a49bf3);
--tv-webcore-progress-block: var(--tv-webcore-navy, #2c2b9f);
}
/* Busy: no known end, so a short run of blocks marches across the track. */
.tv-webcore-progress--busy .tv-webcore-progress-fill {
width: 35%;
animation: tv-webcore-progress-march 1.8s steps(14) infinite;
}
@keyframes tv-webcore-progress-march {
from { transform: translateX(-100%); }
to { transform: translateX(290%); }
}
@media (prefers-reduced-motion: reduce) {
.tv-webcore-progress--busy .tv-webcore-progress-fill {
animation: none;
}
}
Usage & credits
- Use when
- Fake installers, loading screens, uploads and quest or level progress on Y2K pages.
- Avoid when
- Precise progress people rely on, or long tasks with no other feedback.
- Requires
- Set --tv-webcore-progress-value (0% to 100%) and aria-valuenow together. · For the Busy loop, remove aria-valuenow since there is no known end.
- From
- Luna UI