Elemen <progress> adalah cara semantik untuk merepresentasikan progres penyelesaian tugas, seperti mendownload atau mengupload informasi atau menyelesaikan bagian dari proses multi-langkah. Penggunaan elemen native membantu aksesibilitas, karena pembaca layar memiliki role="progressbar" implisit dan dapat mengumumkan nilai.
Panduan ini menerapkan status progres horizontal yang sepenuhnya bergaya dengan penyesuaian gaya.
Status progres atau diagram progres?
- Jika ruang terbatas atau rasio aspek persegi lebih disukai, pertimbangkan untuk menggunakan status progres melingkar (diagram progres): Diagram progres
- Pilih indikator lingkaran berputar untuk sebagian besar skenario progres yang tidak tentu (Indikator lingkaran berputar). Gunakan status progres tidak tentu jika status tidak tentu bersifat sementara dan akan segera digantikan oleh status progres tentu (misalnya, menunggu metadata terkait upload sebelum % progres dapat ditampilkan)
Markup
- Gunakan elemen
<progress>native: Elemen ini memberikan aksesibilitas bawaan dan perilaku yang konsisten dengan platform. - Gunakan
maxjika diperlukan skala yang berbeda dari skala default 0-1. - Untuk nilai progres tertentu, tetapkan atribut
value. Hilangkanvalueuntuk status yang tidak pasti (misalnya, sebelum masukan yang lebih konkret dimulai). - Gunakan
<label for="...">,aria-labelledby, atauaria-labeluntuk mengaitkan elemen progres dengan label.
Apa jenis penyesuaian yang diperlukan?
Untuk gaya visual terbatas, properti berikut sudah cukup:
accent-coloruntuk mengubah warna status progreswidth/inline-sizeuntuk mengubah lebar status progresheight/block-sizeberlaku secara tidak konsisten — uji terlebih dahuluwriting-mode: vertical-lruntuk batang vertikal.- Efek yang diterapkan setelah penggambaran:
opacity,filter,clip-path, mask, transformasi,box-shadow, dll.
Jika gaya visual terbatas sudah cukup, lewati bagian berikutnya.
PERINGATAN: Properti tertentu (misalnya border-radius, background, border) akan menonaktifkan gaya visual status progres default secara otomatis. Jika memerlukan gaya selain properti di atas, Anda harus menerapkan gaya kustom sepenuhnya seperti yang dijelaskan di bagian berikutnya. JANGAN menerapkan gaya yang lebih ekstensif "untuk berjaga-jaga jika berhasil".
Gaya kustom sepenuhnya
1. Penyiapan dasar
- WAJIB: Gunakan
appearance: noneuntuk mengaktifkan gaya kustom. - Reset batas UA dengan
border: 0 solid - Untuk memotong panel aktif ke radius batas elemen, gunakan
overflow: clipATAU terapkanborder-radiusyang sama ke panel. JANGAN gunakanborder-radius: inheritpada panel, yang bergantung pada struktur elemen tertentu di shadow DOM.
progress {
/* Reset default browser styles */
appearance: none;
border: 0 solid;
/* Clip bar to element’s border-radius */
overflow: clip;
}
2. Gaya visual
- Atur gaya trek pada elemen
progressitu sendiri. - Gunakan elemen semu yang ditargetkan browser yang sesuai untuk menargetkan status progres itu sendiri:
::-webkit-progress-valueuntuk WebKit/Blink dan::-moz-progress-baruntuk Firefox. - WAJIB: JANGAN mengelompokkan elemen semu
-webkit-dan-moz-dalam aturan yang sama. Aturan tersebut akan dianggap tidak valid dan akan diabaikan.:is()dan:where()tidak membantu di sini, karena tidak mendukung elemen semu. - Setiap elemen semu yang ditargetkan browser harus muncul tepat satu kali. Penyesuaian khusus status (seperti ukuran dan animasi segmen yang tidak tentu) harus dirutekan melalui properti kustom yang ditetapkan pada elemen
progressitu sendiri. - Opsional: Transisikan
inline-sizepada pengisian sehingga perubahan nilai determinat dianimasikan, bukan melompat. Firefox mengukur pengisian dalam tata letak dan mengabaikannya, yang tidak berbahaya.
progress {
--progress-bar-radius: 1e5px;
border-radius: var(--progress-bar-radius);
/* Apply color for custom progress track (background) */
background: var(--progress-bar-track, var(--color-neutral-90));
/* Subtle depth on the empty part of the track */
box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.1);
}
/* Let <progress> styling show through */
progress::-webkit-progress-bar {
background: transparent;
}
/* Webkit, Chrome */
progress::-webkit-progress-value {
background: var(--progress-bar-fill, var(--accent-color));
border-radius: var(--progress-bar-radius);
transition: inline-size 0.3s;
}
/* Firefox */
progress::-moz-progress-bar {
background: var(--progress-bar-fill, var(--accent-color));
border-radius: var(--progress-bar-radius);
transition: inline-size 0.3s;
}
3. Gaya status tidak tentu
Menambahkan animasi kustom untuk status tidak tentu: Ubah elemen semu pengisian menjadi segmen pendek dan geser di sepanjang trek.
- Atur gaya isian itu sendiri; JANGAN buat ulang sebagai latar belakang di
progress. - Isian tidak tentu hanya ada melalui animasinya: keyframe menetapkan panjangnya dengan
inline-sizeyang sebenarnya (ini mengalahkaninline-sizeinline UA Chromium) dan memindahkannya dengantranslate. JANGAN gunakanscaleuntuk panjang; hal ini akan mendistorsi pola apa pun yang digambar pada isian. - Persentase
translatedihitung berdasarkan lebar isian itu sendiri, jadi nyatakan posisi dalam unit trek: jadikanprogresssebagai penampung ukuran inline dan gunakancqidalam keyframe. Sertakanmargin-right: autodifrom, toagar Chromium juga meletakkan pengisian di sisi kiri fisik dalam RTL. - Gunakan transformasi, bukan margin, untuk memindahkan pengisian.
- Transformasi mempertahankan animasi di compositor (kecuali jika
inline-sizejuga dianimasikan) - Margin rusak di RTL, karena dua alasan terpisah:
- Firefox memosisikan isian tidak tentu hanya menggunakan margin kiri fisiknya, sehingga
margin-inline-starttidak berpengaruh dalam RTL dan isian tidak pernah bergerak. - Di Chromium dan WebKit, yang meletakkan isian sebagai blok normal, setelah margin mendorong isian melewati akhir jalur, margin akan bertambah menjadi lebih besar dari jalur. CSS standar mengatasi hal tersebut dengan mengabaikan
margin-leftdalam RTL, sehingga segmen akan melompat ke tepi, bukan bergeser dari tepi. translatediterapkan setelah tata letak, sehingga kedua masalah tersebut tidak berlaku.
- Transformasi mempertahankan animasi di compositor (kecuali jika
- Untuk mencerminkan gerakan dalam RTL (seperti yang dilakukan panel native Chrome), balikkan animasi di bagian
:dir(rtl):
progress:dir(rtl) {
--progress-bar-indeterminate-animation: progress-bar-indeterminate var(--progress-bar-indeterminate-animation-duration) infinite linear reverse;
}
- Tentukan properti
--progress-bar-indeterminate-*publik diprogress(namanya sudah mencakup status) sehingga konsumen dapat menggantinya tanpa mengetahui:indeterminate. - Untuk memvariasikan panjang segmen (misalnya, tepi depan bergerak lebih cepat dan tepi belakang mengejar), tetapkan
--progress-bar-indeterminate-animationke dua animasi serentak: satu yang keyframe-nya menganimasikantranslatedicqi(posisi) dan satu yang keyframe-nya menganimasikaninline-size(panjang), sehingga masing-masing mendapatkan keyframe dan easing-nya sendiri. JANGAN mencoba membentuk kedua tepi dalam satu daftar keyframe;animation-timing-functionper keyframe berlaku untuk setiap properti dalam keyframe tersebut. --progress-bar-animationberlaku dalam kedua status dan dapat digunakan untuk efek seperti shimmer yang pasti.revert-ruledigunakan untuk mengganti hanya jika ditetapkan, guna memaksimalkan composability.- Jangan pernah menonaktifkan animasi yang tidak tentu (
animation: nonemenyisakan pengisian lebar nol di Chromium). Untuk mengurangi gerakan, perlambat saja.
progress {
/* Lets the fill position itself in track units (cqi) */
container-type: inline-size;
/* Segment length relative to the track */
--progress-bar-indeterminate-size: 30%;
--progress-bar-indeterminate-animation-duration: 1.5s;
/* Respect prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
--progress-bar-indeterminate-animation-duration: 10s;
}
}
progress:indeterminate {
--progress-bar-animation: var(
--progress-bar-indeterminate-animation,
progress-bar-indeterminate var(--progress-bar-indeterminate-animation-duration) infinite linear
);
}
/* Add to the existing pseudo-element rules */
progress::-webkit-progress-value {
animation: var(--progress-bar-animation, revert-rule);
}
progress::-moz-progress-bar {
animation: var(--progress-bar-animation, revert-rule);
}
/* Physical: left to right regardless of direction (reverse under :dir(rtl) to mirror). */
@keyframes progress-bar-indeterminate {
from, to {
inline-size: var(--progress-bar-indeterminate-size);
/* Pin to the physical left; Chromium would otherwise lay the fill out at the inline start */
margin-right: auto;
}
from { translate: -100%; } /* Own width: fully outside the left edge */
to { translate: 100cqi; } /* Track width: fully outside the right edge */
}
Pertimbangan Aksesibilitas Tambahan
Selain panduan yang disebutkan di atas:
- Umumkan penyelesaian tanpa mengalihkan fokus: Jangan tetapkan
tabindexatau panggil.focus()di<progress>, karena tidak interaktif dan memindahkan fokus ke sana akan mengganggu pengguna keyboard. Untuk mengumumkan saat tugas latar belakang selesai, perbarui elemen status sopan (role="status"atauaria-live="polite"). - Jangan tambahkan teks pengganti di dalam
<progress>: Teks di dalam<progress>diabaikan oleh browser modern dan tidak digunakan oleh teknologi pendukung. - Hindari
aria-busy+aria-describedbypada<div>generik tanpa label.aria-busymemiliki dukungan pembaca layar yang tidak konsisten, danaria-describedbypada<div>tanpa nama tanpa peran akan diabaikan oleh teknologi pendukung. Jika konten suatu region belum siap saat dimuat, sembunyikan denganhiddenatauaria-hidden="true". - LAKUKAN pastikan kontras yang tepat antara status progres dan trek saat menambahkan gaya kustom.
- Pertimbangkan alternatif untuk merepresentasikan status tidak tentu: Animasi status progres tidak tentu yang ditampilkan secara paralel dengan konten lain dapat dianggap mengganggu bagi sebagian pengguna.
Strategi penggantian
Penggantian & dukungan browser untuk accent-color
Properti accent-color adalah progressive enhancement.
Browser yang tidak mendukung properti ini akan mengabaikannya dan menggunakan warna UI default.
Jika accent-color tidak didukung dan penataan gaya status progres diperlukan, gunakan metode penataan gaya kustom untuk menerapkan gaya yang diinginkan ke status progres.
Penggantian & dukungan browser untuk revert-rule
Jika revert-rule tidak didukung, animation: var(--progress-bar-animation, revert-rule) akan kembali ke animation-name: revert-rule dengan durasi 0s saat --progress-bar-animation tidak ditetapkan, yang merupakan no-op yang tidak berbahaya jika tidak ada @keyframes revert-rule.