عنصر <progress> روشی معنایی برای نمایش پیشرفت تکمیل یک تکلیف است، مانند بارگیری یا بارگذاری اطلاعات یا تکمیل بخشی از یک فرایند چندمرحلهای. استفاده از عنصر بومی به دسترسپذیری کمک میکند، زیرا صفحهخوانها دارای role="progressbar" ضمنی هستند و میتوانند مقادیر را اعلام کنند.
این راهنما یک نوار پیشرفت افقی کاملاً سبکدار با سفارشیسازیهای سبک را پیادهسازی میکند.
نوار پیشرفت یا حلقه پیشرفت؟
- اگر فضا محدود است یا نسبت ابعادی مربعی ترجیح داده میشود، از نوار پیشرفت دایرهای (حلقه پیشرفت) استفاده کنید: حلقه پیشرفت
- برای اکثر سناریوهای پیشرفت نامشخص، گردونهها را ترجیح دهید (گردونه بار کردن). از نوار پیشرفت نامعین زمانی استفاده کنید که وضعیت نامعین موقتی باشد و بهزودی با نوار پیشرفت معین جایگزین شود (مثلاً انتظار برای فراداده مربوط به بارگذاری قبلاز اینکه درصد پیشرفت نشان داده شود)
نشانهگذاری
- از عنصر
<progress>بومی استفاده کنید: این عنصر دسترسپذیری داخلی و رفتار سازگار با پلاتفرم را ارائه میدهد. - اگر مقیاسی متفاوت از مقیاس پیشفرض ۰-۱ نیاز است، از
maxاستفاده کنید. - برای مقدار پیشرفت خاص، مشخصه
valueرا تنظیم کنید. برای حالت نامشخص (مثلاً قبلاز شروع بازخورد ملموستر)،valueرا حذف کنید. - از
<label for="...">،aria-labelledby، یاaria-labelبرای مرتبط کردن عنصر پیشرفت با برچسب استفاده کنید.
چه نوع سفارشیسازیای لازم است؟
برای سبکبندی محدود، این ویژگیها کافی است:
-
accent-colorبرای تغییر رنگ نوار پیشرفت width/inline-sizeبرای تغییر عرض نوار پیشرفت-
height/block-sizeبهطور ناهماهنگ اعمال میشود — ابتدا آزمایش کنید writing-mode: vertical-lrبرای میلههای عمودی.- جلوههایی که پساز رنگآمیزی اعمال میشوند:
opacity،filter،clip-path، ماسکها، تبدیلها،box-shadow، و غیره.
اگر سبکبندی محدود کافی است، از بخش بعدی رد شوید.
هشدار: برخیاز ویژگیها (مثلاً border-radius، background، border) سبک پیشفرض نوار پیشرفت را بدون اطلاع غیرفعال میکنند. اگر به سبکی فراتر از ویژگیهای بالا نیاز دارید، باید سبک کاملاً سفارشی را همانطور که در بخش بعدی توضیح داده شده است پیادهسازی کنید. سبکبندی گستردهتری را «فقط برای اینکه شاید کار کند» اعمال نکنید.
سبکپردازی کاملاً سفارشی
۱. راهاندازی پایه
- MANDATORY: Use
appearance: noneto enable custom styling. - بازنشانی مرزهای UA با
border: 0 solid - برای برش دادن نوار فعال به شعاع حاشیه عنصر، از
overflow: clipاستفاده کنید یا همانborder-radiusرا روی نوار اعمال کنید. ازborder-radius: inheritدر نوار استفاده نکنید، زیرا به ساختار خاص عناصر در DOM سایه بستگی دارد.
progress {
/* Reset default browser styles */
appearance: none;
border: 0 solid;
/* Clip bar to element’s border-radius */
overflow: clip;
}
۲. سبکپردازی
- سبک قطعه را در خود عنصر
progressتنظیم کنید. - از شبهعنصر مناسب هدفگذاریشده در مرورگر برای هدفگذاری خود نوار پیشرفت استفاده کنید:
::-webkit-progress-valueبرای WebKit/Blink و::-moz-progress-barبرای Firefox. - MANDATORY: Do NOT group
-webkit-and-moz-pseudo-elements in the same rule. قانون نامعتبر تلقی خواهد شد و نادیده گرفته میشود. :is()و:where()در اینجا کمکی نمیکنند، زیرا از شبهعناصر پشتیبانی نمیکنند. - هر شبهعنصر هدف مرورگر باید دقیقاً یکبار نشان داده شود. سفارشیسازیهای مختص وضعیت (مثل اندازه بخش نامشخص و پویانمایی) باید ازطریق ویژگیهای سفارشی تنظیمشده در خود عنصر
progressهدایت شوند. - اختیاری:
inline-sizeرا روی پر کردن انتقال دهید تا تغییرات مقدار تعیینشده بهجای پریدن، پویانمایی شود. Firefox اندازه پر کردن را در چیدمان تعیین میکند و آن را نادیده میگیرد که بیضرر است.
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;
}
۳. سبکپردازی وضعیت نامشخص
افزودن پویانمایی سفارشی برای حالت نامشخص: شبهعنصر پر کردن را به یک بخش کوتاه تبدیل کنید و آن را درطول قطعه بلغزانید.
- خودِ پر کردن را سبکبندی کنید؛ آن را بهعنوان پسزمینه در
progressبازآفرینی نکنید. - پر کردن نامشخص فقط ازطریق پویانمایی آن وجود دارد: فریمهای کلیدی طول آن را با
inline-sizeواقعی تنظیم میکنند (این مقدار ازinline-sizeدرونخطی UA در Chromium بهتر است) و آن را باtranslateجابهجا میکنند. ازscaleبرای طول استفاده نکنید؛ این کار هر الگویی را که روی رنگآمیزی کشیده شده است مخدوش میکند. - درصدهای
translateنسبت به عرض خود پرکننده حل میشوند، بنابراین موقعیتها را در واحدهای قطعه بیان کنید:progressرا به محفظه اندازه درونخطی تبدیل کنید و ازcqiدر فریمهای کلیدی استفاده کنید.margin-right: autoرا بهfrom, toاضافه کنید تا Chromium در زبانهای راستبهچپ نیز پر کردن را در سمت چپ فیزیکی قرار دهد. - برای جابهجا کردن پر کردن، از تبدیلها استفاده کنید، نه حاشیهها.
- تبدیلها پویانمایی را در ترکیبکننده نگه میدارند (مگر اینکه
inline-sizeنیز پویانمایی شود) - حاشیهها در زبانهای راست به چپ به دو دلیل جداگانه بههم میریزند:
- Firefox موقعیت پر کردن نامشخص را فقط بااستفاده از حاشیه فیزیکی سمت چپ آن تعیین میکند، بنابراین
margin-inline-startدر RTL تأثیری ندارد و پر کردن هرگز حرکت نمیکند. - در Chromium و WebKit، که پر کردن را بهعنوان یک بلوک عادی قرار میدهند، وقتی حاشیه پر کردن را از انتهای قطعه فراتر میبرد، حاشیهها بیشتر از قطعه میشوند. CSS استاندارد این مشکل را با نادیده گرفتن
margin-leftدر حالت راستبهچپ حل میکند، بنابراین بخش بهجای لغزیدن از لبه، به لبه میپرد. -
translateپساز چیدمان اعمال میشود، بنابراین هیچکدام از مشکلات اعمال نمیشود.
- تبدیلها پویانمایی را در ترکیبکننده نگه میدارند (مگر اینکه
- برای قرینهسازی حرکت در زبانهای راستبهچپ (همانطور که نوار بومی Chrome انجام میدهد)، پویانمایی را در
:dir(rtl)معکوس کنید:
progress:dir(rtl) {
--progress-bar-indeterminate-animation: progress-bar-indeterminate var(--progress-bar-indeterminate-animation-duration) infinite linear reverse;
}
- ویژگیهای عمومی
--progress-bar-indeterminate-*را درprogressتعریف کنید (نام آنها ازقبل آنها را به وضعیت محدود میکند) تا مصرفکنندگان بتوانند بدون اطلاع از:indeterminateآنها را لغو کنند. - برای تغییر دادن طول بخش (مثلاً لبه جلویی سریعتر حرکت میکند و لبه عقبی به آن میرسد)،
--progress-bar-indeterminate-animationرا روی دو پویانمایی همزمان تنظیم کنید: یکی که فریمهای کلیدی آنtranslateرا درcqi(موقعیت) پویانمایی میکند و دیگری که فریمهای کلیدی آنinline-size(طول) را پویانمایی میکند، بهطوریکه هرکدام فریمهای کلیدی و هموارسازی خود را داشته باشند. سعی نکنید هر دو لبه را در یک فهرست قاب کلیدی شکل دهید؛animation-timing-functionهر قاب کلیدی برای هر ویژگی در آن قاب کلیدی اعمال میشود. --progress-bar-animationدر هر دو حالت اعمال میشود و میتوان از آن برای جلوههایی مثل درخشش معین استفاده کرد.revert-ruleفقط برای لغو کردن در زمان تنظیم استفاده میشود تا ترکیبپذیری به حداکثر برسد.- هرگز پویانمایی نامشخص را غیرفعال نکنید (
animation: noneیک پرکننده با عرض صفر در Chromium باقی میگذارد). برای کاهش حرکت، سرعت آن را کم کنید.
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 */
}
ملاحظات دسترسپذیری بیشتر
علاوهبر دستورالعملهای ذکرشده در بالا:
- اعلام تکمیل بدون جلب تمرکز:
tabindexرا تنظیم نکنید یا.focus()را در<progress>فراخوانی نکنید، زیرا غیرتعاملی است و انتقال تمرکز به آن باعث اختلال در کار کاربران صفحهکلید میشود. برای اعلام زمان پایان یافتن تکلیف پسزمینه، عنصر وضعیت مؤدبانه (role="status"یاaria-live="polite") را بهروز کنید. - نوشتار جایگزین را داخل
<progress>اضافه نکنید: نوشتار داخل<progress>توسط مرورگرهای مدرن نادیده گرفته میشود و فناوریهای کمکی از آن استفاده نمیکنند. - از
aria-busy+aria-describedbyدر<div>عمومی بدون برچسب اجتناب کنید.aria-busyپشتیبانی صفحهخوان ناسازگار دارد وaria-describedbyدر<div>بینام بدون نقش توسط فناوریهای کمکی نادیده گرفته میشود. اگر محتوای منطقهای درحین بار شدن آماده نیست، آن را باhiddenیاaria-hidden="true"پنهان کنید. - باید هنگام افزودن سبکهای سفارشی، کنتراست مناسبی بین نوار پیشرفت و قطعه وجود داشته باشد.
- جایگزینهایی برای نمایش وضعیت نامشخص درنظر بگیرید: پویانماییهای نوار پیشرفت نامشخص که بهطور موازی با محتوای دیگر نمایش داده میشوند ممکن است برای برخی کاربران حواسپرتکننده باشند.
راهبردهای جایگزین
پشتیبانی مرورگر و جایگزینها برای accent-color
خصوصیت accent-color ارتقای پیشرو است.
مرورگرهایی که از این ویژگی پشتیبانی نمیکنند آن را نادیده میگیرند و از رنگهای واسط کاربر پیشفرض خود استفاده میکنند.
اگر accent-color پشتیبانی نمیشود و سبکبندی نوار پیشرفت لازم است، از روش سبکبندی سفارشیشده برای اعمال سبکبندی ترجیحی به نوار پیشرفت استفاده کنید.
جایگزینها و پشتیبانی مرورگر برای revert-rule
اگر revert-rule پشتیبانی نشود، animation: var(--progress-bar-animation, revert-rule) به animation-name: revert-rule با مدت 0s برمیگردد وقتی --progress-bar-animation تنظیم نشده باشد، که یک عملیات بیضرر و بدون تأثیر است وقتی هیچ @keyframes revert-rule وجود نداشته باشد.