04Thanh vô định
Khi chưa biết % tiến độ, một thanh ngắn chạy qua lại để báo vẫn đang xử lý.
Dùng choTrước khi upload file, thanh tiến độ đầu trang
가로 100%1.5초ease-in-out

<main class="stage">
<div class="bar" role="progressbar" aria-label="Đang xử lý">
<span class="bar__fill" aria-hidden="true"></span>
</div>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: 1.5s; // 막대가 한 번 오가는 시간
$easing: ease-in-out;
$color: $subject-blue; // 막대 색
@include stage($stage-paper);
.bar {
position: relative;
width: clamp(180px, 60vw, 280px);
height: 6px;
border-radius: 999px;
background: rgba($subject-ink, .12);
overflow: hidden;
}
.bar__fill {
position: absolute;
inset: 0;
border-radius: inherit;
background: $color;
transform-origin: left center; // width 대신 transform 으로만 움직인다
animation: sweep $duration $easing infinite;
}
@keyframes sweep {
0% { transform: translateX(-100%) scaleX(.3); }
50% { transform: translateX(20%) scaleX(.6); }
100% { transform: translateX(100%) scaleX(.3); }
}
@media (prefers-reduced-motion: reduce) {
.bar__fill { animation: none; transform: translateX(0) scaleX(.55); opacity: .7; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #ffffff;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.bar {
position: relative;
width: clamp(180px, 60vw, 280px);
height: 6px;
border-radius: 999px;
background: rgba(23, 20, 26, 0.12);
overflow: hidden;
}
.bar__fill {
position: absolute;
inset: 0;
border-radius: inherit;
background: #2f6df6;
transform-origin: left center;
animation: sweep 1.5s ease-in-out infinite;
}
@keyframes sweep {
0% {
transform: translateX(-100%) scaleX(0.3);
}
50% {
transform: translateX(20%) scaleX(0.6);
}
100% {
transform: translateX(100%) scaleX(0.3);
}
}
@media (prefers-reduced-motion: reduce) {
.bar__fill {
animation: none;
transform: translateX(0) scaleX(0.55);
opacity: 0.7;
}
}import type { CSSProperties } from "react";
import styles from "./IndeterminateBar.module.scss";
export type IndeterminateBarProps = {
/** 막대가 한 번 오가는 시간 (기본 1500ms) */
duration?: number;
/** 막대 색 */
color?: string;
/** 트랙 너비 */
width?: number;
label?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--color"?: string; "--width"?: string };
export default function IndeterminateBar({
duration = 1500,
color = "#2f6df6",
width = 220,
label = "Processing",
}: IndeterminateBarProps) {
const vars: Vars = {
"--duration": `${duration}ms`,
"--color": color,
"--width": `${width}px`,
};
return (
<div className={styles.bar} style={vars} role="progressbar" aria-label={label}>
<span className={styles.fill} aria-hidden="true" />
</div>
);
}04 Thanh vô định — Diện tích đo được 1.164% · khung hình chuyển động 15/23Nguyên tác GODRICH · SCSS và React nằm trong tệp zip · 9 hiệu ứng css loading spinner animation gọn nhẹ
Bài viết chứa demo này
9 hiệu ứng css loading spinner animation gọn nhẹCSS loading spinner animation là một khối nhỏ tự xoay, tự nảy hoặc tự đổi độ sáng bằng thuần CSS để báo cho người dùng b Xem tất cả demo trong bài này


