تقدّم هذه الصفحة نظرة عامة أساسية حول طريقة إنشاء شريط تحميل متكيف اللون وسهل الاستخدام باستخدام العنصر <progress>
.
أود في هذه المشاركة أن أشارككم التفكير حول كيفية إنشاء ألوان تكييفية
شريط تحميل يمكن الوصول إليه باستخدام عنصر <progress>
جرّب
العرض التوضيحي وعرض
المصدر!
إليك نسخة من هذه المشاركة على YouTube إذا كنت تفضّل ذلك:
نظرة عامة
تشير رسالة الأشكال البيانية
<progress>
يقدم ملاحظات مرئية وصوتية للمستخدمين حول الإكمال. هذا النمط
تعد الملاحظات المرئية ذات قيمة لسيناريوهات مثل: التقدم من خلال نموذج،
أو عرض تنزيل أو تحميل معلومات، أو حتى إظهار أن
مستوى التقدم غير معروف ولكن لا يزال العمل نشطًا.
نجح تحدي واجهة المستخدم الرسومية هذا مع
عنصر HTML <progress>
الحالي لتوفير بعض الجهد في تسهيل إمكانية الوصول. تشير رسالة الأشكال البيانية
تدفع الألوان والتخطيطات حدود التخصيص للعنصر المضمن،
تحديث المكون وجعله يتناسب بشكل أفضل مع أنظمة التصميم.
Markup
اخترتُ التفاف العنصر <progress>
في
<label>
لذلك
يمكنني تخطي سمات العلاقة الصريحة لصالح إشارة ضمنية
العلاقة
لقد وصفت أيضًا عنصرًا رئيسيًا متأثرًا بحالة التحميل، لذا فإن الشاشة
يمكن لتقنيات القارئ من نقل هذه المعلومات إلى المستخدم.
<progress></progress>
إذا لم يتوفر value
، يصبح تقدم العنصر
غير محدد.
يتم ضبط السمة max
تلقائيًا على 1، وبالتالي يتراوح مستوى التقدّم بين 0 و1. إعداد max
على 100، على سبيل المثال، يتم تعيين النطاق على 0-100. اخترتُ البقاء في المنزل
و 1، مما يؤدي إلى ترجمة قيم التقدم إلى 0.5 أو 50٪.
مستوى التقدم المحرز في تصنيف
في العلاقة الضمنية، يتم التفاف عنصر التقدم بتصنيف مثل هذا:
<label>Loading progress<progress></progress></label>
اخترت في العرض التوضيحي تضمين تصنيف قارئات الشاشة
فقط.
ويتم ذلك من خلال التفاف نص التصنيف في <span>
وتطبيق بعض الأنماط.
بحيث يكون خارج الشاشة بشكل فعال:
<label>
<span class="sr-only">Loading progress</span>
<progress></progress>
</label>
مع CSS المصاحب التالي من WebAIM:
.sr-only {
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
height: 1px;
width: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
}
المنطقة المتأثرة بتقدم التحميل
إذا كانت لديك رؤية صحية، قد يكون من السهل ربط مؤشر للتقدّم
مع العناصر ومناطق الصفحة ذات الصلة، ولكن بالنسبة للمستخدمين ذوي العجز البصري،
واضح للغاية. يمكنك تحسين ذلك من خلال إسناد
aria-busy
إلى العنصر الأعلى الذي يتغير عند اكتمال التحميل.
بالإضافة إلى ذلك، يجب توضيح العلاقة بين مستوى التقدّم ومنطقة التحميل.
مع
aria-describedby
<main id="loading-zone" aria-busy="true">
…
<progress aria-describedby="loading-zone"></progress>
</main>
من JavaScript، يمكنك التبديل بين aria-busy
وtrue
في بداية المهمة
false
بمجرد الانتهاء.
إضافات سمات Aria
على الرغم من أنّ الدور الضمني لعنصر <progress>
هو
progressbar
، لقد أشرت إلى ذلك بشكلٍ صريح
في المتصفحات التي تفتقر إلى هذا الدور الضمني لقد أضفتُ أيضًا السمة
indeterminate
لوضع العنصر بشكل صريح في حالة غير معروفة، وهي
أكثر وضوحًا من ملاحظة أنّ العنصر لا يحتوي على مجموعة value
.
<label>
Loading
<progress
indeterminate
role="progressbar"
aria-describedby="loading-zone"
tabindex="-1"
>unknown</progress>
</label>
استخدام
tabindex="-1"
لجعل عنصر التقدم قابلاً للتركيز من JavaScript. هذا مهم
قارئ الشاشة، نظرًا لأن إعطاء تركيز التقدم كتغييرات في التقدم،
سيُعلن للمستخدم عن مدى التقدم الذي تم تحديثه.
الأنماط
يكون عنصر التقدم معقدًا بعض الشيء عندما يتعلق الأمر بالأنماط. HTML مدمج تحتوي العناصر على أجزاء مخفية خاصة قد يصعب تحديدها تقدم فقط مجموعة محدودة من الخصائص التي سيتم إعدادها.
التنسيق
تهدف أنماط التنسيق إلى توفير بعض المرونة في التقدّم لحجم العنصر وموضع التصنيف. تتم إضافة حالة إكمال خاصة يمكنها إشارة مرئية إضافية مفيدة ولكن غير مطلوبة.
تنسيق <progress>
يتم ترك عرض عنصر التقدم دون تغيير بحيث يمكن أن يتقلص ويزداد
مع المساحة المطلوبة في التصميم. يتم تجريد الأنماط المضمنة من خلال
إعداد appearance
وborder
على none
. يتم ذلك حتى يمكن تمييز
عبر المتصفحات، حيث إن كل متصفح له أنماطه الخاصة
العنصر.
progress {
--_track-size: min(10px, 1ex);
--_radius: 1e3px;
/* reset */
appearance: none;
border: none;
position: relative;
height: var(--_track-size);
border-radius: var(--_radius);
overflow: hidden;
}
تستخدم قيمة 1e3px
لـ _radius
الرقم العلمي
العلامة للتعبير عن
رقم كبير ولذلك يتم تقريب border-radius
دائمًا. تعادل
1000px
أحب استخدام هذا لأن هدفي هو استخدام قيمة كبيرة بما يكفي
يمكنني ضبط السياسة ونسيانها (وتكون الكتابة أقصر من 1000px
). من المهم أيضًا
من السهل تكبيره أكثر إذا لزم الأمر: ما عليك سوى تغيير الرقم 3 إلى 4، وبالتالي فإن قيمة 1e4px
ما يعادل 10000px
.
يُستخدم overflow: hidden
وكان أسلوبًا خلابيًا. لقد صنع بعض
الأمور سهلة، مثل عدم الحاجة إلى تمرير قيم border-radius
إلى
وتتبع عناصر التعبئة وتتبعها؛ ولكنه يعني أيضًا عدم وجود أي أطفال للتقدم
يمكن أن تعيش خارج العنصر. تكرار آخر لهذا التقدّم المخصّص
بدون overflow: hidden
وقد يؤدي ذلك إلى فتح بعض
فرص الرسوم المتحركة أو حالات إكمال أفضل.
اكتمل مستوى التقدم
تؤدي أدوات اختيار لغة CSS العمل الشاق في هذه الحالة، وذلك من خلال مقارنة الحد الأقصى بالقيمة، وفي حال تطابُقها، تكتمل عملية التقدّم. عند الانتهاء، يتم إنشاء عنصر زائف وإلحاقه بنهاية عنصر التقدم، مما يوفر إشارة مرئية إضافية لطيفة للاكتمال.
progress:not([max])[value="1"]::before,
progress[max="100"][value="100"]::before {
content: "✓";
position: absolute;
inset-block: 0;
inset-inline: auto 0;
display: flex;
align-items: center;
padding-inline-end: max(calc(var(--_track-size) / 4), 3px);
color: white;
font-size: calc(var(--_track-size) / 1.25);
}
اللون
يجلب المتصفح ألوانه الخاصة لعنصر التقدم، ويتكيف مع مضيئة وداكنة باستخدام خاصية CSS واحدة فقط. يمكن بناء ذلك مع بعض محددات خاصة خاصة بالمتصفح.
أنماط المتصفح الفاتحة والداكنة
لتفعيل أحد عناصر <progress>
التكيُّفية ذات اللونَين الداكن والفاتح على موقعك الإلكتروني،
color-scheme
هو كل ما هو مطلوب.
progress {
color-scheme: light dark;
}
لون معبأ لمستوى التقدّم في موقع واحد
لتلوين عنصر <progress>
، استخدِم accent-color
.
progress {
accent-color: rebeccapurple;
}
لاحظ تغير لون خلفية المقطع الصوتي من فاتح إلى داكن حسب
accent-color
يضمن المتصفح تباينًا مناسبًا وأنيقًا.
ألوان فاتحة وغامقة مخصّصة بالكامل
ضبط خاصيتين مخصّصتين في العنصر <progress>
، واحدة للون المسار
والآخر للون تقدم المسار. داخل
prefers-color-scheme
استعلام وسائط، قم بتوفير قيم لون جديدة للمسار وتتبع التقدم.
progress {
--_track: hsl(228 100% 90%);
--_progress: hsl(228 100% 50%);
}
@media (prefers-color-scheme: dark) {
progress {
--_track: hsl(228 20% 30%);
--_progress: hsl(228 100% 75%);
}
}
أنماط التركيز
أعطينا العنصر في وقت سابق فهرس علامة تبويب سالبة بحيث يمكن
التركيز. استخدام
:focus-visible
إلى
يمكنك تخصيص التركيز لتفعيل نمط حلقة التركيز الأذكى. باستخدام هذا، الماوس
النقر والتركيز على حلقة التركيز، ولكن ستظهر نقرات لوحة المفاتيح. تشير رسالة الأشكال البيانية
يتطرق فيديو YouTube إلى هذا الموضوع بشكل أكثر تعمقًا
يستحق المراجعة.
progress:focus-visible {
outline-color: var(--_progress);
outline-offset: 5px;
}
الأنماط المخصّصة على المتصفّحات المختلفة
يمكنك تخصيص الأنماط عن طريق تحديد أجزاء عنصر <progress>
التي
الكشف عن الصور في المتصفح. استخدام عنصر التقدم هو علامة واحدة، لكنها تتكون من
بعض العناصر الثانوية التي يتم عرضها عبر محددات CSS الزائفة. أدوات مطوري البرامج في Chrome
سيعرض لك هذه العناصر في حال تفعيل الإعداد:
- انقر بزر الماوس الأيمن على صفحتك واختَر فحص العنصر لإظهار "أدوات مطوّري البرامج".
- النقر على رمز ترس "الإعدادات" (Settings) في أعلى يسار نافذة "أدوات مطوّري البرامج"
- ضمن العنوان Elements، ابحث عن الخيار إظهار ظل وكيل المستخدم وفعِّله DOM.
نمطا Safari وChromium
تعرض المتصفحات المستندة إلى WebKit مثل Safari وChromium
::-webkit-progress-bar
و::-webkit-progress-value
، ويسمحان لمجموعة فرعية من
خدمة مقارنة الأسعار (CSS) التي سيتم استخدامها. في الوقت الحالي، يمكنك ضبط background-color
باستخدام السمات المخصّصة.
أنشأناها سابقًا، والتي تتكيّف مع الإضاءة والظلام.
/* Safari/Chromium */
progress[value]::-webkit-progress-bar {
background-color: var(--_track);
}
progress[value]::-webkit-progress-value {
background-color: var(--_progress);
}
أنماط Firefox
لا يعرض Firefox سوى أداة الاختيار الصورية ::-moz-progress-bar
على
العنصر <progress>
هذا يعني أيضًا أننا لا نستطيع تلوين المسار مباشرةً.
/* Firefox */
progress[value]::-moz-progress-bar {
background-color: var(--_progress);
}
يُرجى ملاحظة أنّ Firefox يحتوي على مجموعة لون مسار من accent-color
بينما iOS Safari
له مسار أزرق فاتح. وينطبق الأمر نفسه في الوضع الداكن، لأنّ فايرفوكس يتضمّن مسارًا مظلمًا ولكن
وليس اللون المخصص الذي قمنا بتعيينه، كما أنها تعمل في المتصفحات المستندة إلى Webkit.
Animation
أثناء العمل باستخدام محددات زائفة مدمجة في المتصفح، غالبًا ما يكون مع مجموعة من خصائص CSS المسموح بها.
تحريك المقطع الصوتي بملء الشاشة
إن إضافة انتقال إلى
inline-size
من إجمالي
يعمل عنصر التقدم مع Chromium ولكن ليس مع Safari. يفعل فايرفوكس أيضًا
لا تستخدم خاصية النقل على ::-moz-progress-bar
.
/* Chromium Only 😢 */
progress[value]::-webkit-progress-value {
background-color: var(--_progress);
transition: inline-size .25s ease-out;
}
جارٍ تحريك حالة :indeterminate
أصبحت هنا أكثر إبداعًا حتى أتمكن من تقديم رسوم متحركة. عنصر زائف في Chromium ويتم تطبيق تدرج يظهر بشكل متحرك المقدمة لجميع المتصفحات الثلاثة.
الخصائص المخصصة
تناسب الخصائص المخصصة العديد من الأمور، ولكن أحد تفضيلاتي هو ببساطة
إعطاء اسم لقيمة CSS ذات مظهر سحري. تعد المتابعة نوعًا ما
معقد
linear-gradient
،
ولكن باسم لطيف. ويمكن فهم الغرض من هذه الميزة وحالات استخدامها بوضوح.
progress {
--_indeterminate-track: linear-gradient(to right,
var(--_track) 45%,
var(--_progress) 0%,
var(--_progress) 55%,
var(--_track) 0%
);
--_indeterminate-track-size: 225% 100%;
--_indeterminate-track-animation: progress-loading 2s infinite ease;
}
ستساعد الخصائص المخصصة أيضًا في بقاء التعليمات البرمجية غير مكتملة لأنه لا يمكننا تجميع أدوات الاختيار هذه الخاصة بالمتصفح معًا.
الإطارات الرئيسية
الهدف هو رسم متحرك غير محدود يتنقل ذهابًا وإيابًا. البداية والنهاية
الإطارات الرئيسية في CSS. ولن تحتاج سوى إلى إطار رئيسي واحد، أي الإطار الرئيسي الأوسط
في 50%
، لإنشاء صورة متحركة تعود إلى حيث بدأت مرة أخرى
وتكرارًا!
@keyframes progress-loading {
50% {
background-position: left;
}
}
استهداف كل متصفح
هناك بعض المتصفحات التي لا تسمح بإنشاء عناصر زائفة على <progress>
العنصر نفسه أو يسمح بتحريك شريط التقدم. توافق المزيد من المتصفحات
مقطعًا متحركًا بدلاً من عنصر زائف، لذلك قمت بالترقية من العناصر الزائفة
قاعدة وإلى أشرطة متحركة.
عنصر زائف في Chromium
لا يسمح Chromium بالعنصر الزائف: ::after
المستخدم مع موضع لتغطية
العنصر. يتم استخدام الخصائص المخصصة غير المحددة،
تعمل الرسوم المتحركة للأمام بشكل جيد للغاية.
progress:indeterminate::after {
content: "";
inset: 0;
position: absolute;
background: var(--_indeterminate-track);
background-size: var(--_indeterminate-track-size);
background-position: right;
animation: var(--_indeterminate-track-animation);
}
شريط التقدّم في متصفّح Safari
وبالنسبة إلى Safari، يتمّ تطبيق الخصائص المخصّصة والرسوم المتحركة على شريط التقدّم لعنصر زائف:
progress:indeterminate::-webkit-progress-bar {
background: var(--_indeterminate-track);
background-size: var(--_indeterminate-track-size);
background-position: right;
animation: var(--_indeterminate-track-animation);
}
شريط التقدّم في Firefox
بالنسبة إلى فايرفوكس، تنطبق أيضًا الخصائص المخصصة والرسوم المتحركة على شريط التقدّم لعنصر زائف:
progress:indeterminate::-moz-progress-bar {
background: var(--_indeterminate-track);
background-size: var(--_indeterminate-track-size);
background-position: right;
animation: var(--_indeterminate-track-animation);
}
JavaScript
تؤدي لغة JavaScript دورًا مهمًا مع العنصر <progress>
. يتحكم في هذه الميزة
القيمة المرسلة إلى العنصر وتضمن وجود معلومات كافية في
مستند لقارئات الشاشة.
const state = {
val: null
}
يعرض العرض التوضيحي أزرارًا للتحكم في التقدم؛ تم تعديل state.val
ثم استدعينا دالة لتحديث
نموذج كائن المستند (DOM)
document.querySelector('#complete').addEventListener('click', e => {
state.val = 1
setProgress()
})
setProgress()
هذه الدالة هي المكان الذي يتم فيه تنسيق تجربة المستخدم/واجهة المستخدم. يمكنك البدء بإنشاء
setProgress()
. لا حاجة إلى أي معلَمات نظرًا لأن بإمكانه الوصول إلى
كائن state
وعنصر التقدّم ومنطقة <main>
.
const setProgress = () => {
}
ضبط حالة التحميل في منطقة <main>
استنادًا إلى ما إذا كان مستوى التقدّم مكتملاً أم لا، تتوفّر <main>
ذات الصلة
يحتاج إلى تعديل
aria-busy
السمة:
const setProgress = () => {
zone.setAttribute('aria-busy', state.val < 1)
}
محو السمات إذا كان مقدار التحميل غير معروف
في حال كانت القيمة غير معروفة أو بدون ضبط، null
في هذا الاستخدام، أزِل value
aria-valuenow
. سيؤدي ذلك إلى تحويل <progress>
إلى قيمة غير محددة.
const setProgress = () => {
zone.setAttribute('aria-busy', state.val < 1)
if (state.val === null) {
progress.removeAttribute('aria-valuenow')
progress.removeAttribute('value')
progress.focus()
return
}
}
إصلاح المسائل الحسابية الأعداد العشرية في JavaScript
نظرًا لأنني اخترت الالتزام بحد أقصى افتراضي للتقدم 1، فإن العرض التوضيحي
تستخدم دوال زيادة القيم والتناقص العمليات الحسابية العشرية. وغير ذلك
اللغات، ليست دائمًا رائعة في
ذلك.
إليك دالة roundDecimals()
التي ستزيل المبالغ الزائدة من العملية الحسابية.
النتيجة:
const roundDecimals = (val, places) =>
+(Math.round(val + "e+" + places) + "e-" + places)
تقريب القيمة بحيث يمكن تقديمها وتكون واضحة:
const setProgress = () => {
zone.setAttribute('aria-busy', state.val < 1)
if (state.val === null) {
progress.removeAttribute('aria-valuenow')
progress.removeAttribute('value')
progress.focus()
return
}
const val = roundDecimals(state.val, 2)
const valPercent = val * 100 + "%"
}
ضبط قيمة لبرامج قراءة الشاشة وحالة المتصفّح
يتم استخدام القيمة في ثلاثة مواقع في DOM:
- السمة
value
للعنصر<progress>
. - السمة
aria-valuenow
. - محتوى النص الداخلي لـ
<progress>
const setProgress = () => {
zone.setAttribute('aria-busy', state.val < 1)
if (state.val === null) {
progress.removeAttribute('aria-valuenow')
progress.removeAttribute('value')
progress.focus()
return
}
const val = roundDecimals(state.val, 2)
const valPercent = val * 100 + "%"
progress.value = val
progress.setAttribute('aria-valuenow', valPercent)
progress.innerText = valPercent
}
إعطاء تركيز التقدم
من خلال تعديل القيم، سيرى المستخدمون المبصرون التغيير في مستوى التقدّم، ولكن شاشتهم
لم يتم بعد إعلان التغيير لمستخدمي القرّاء. ركِّز
<progress>
وسيعلن المتصفّح عن التحديث.
const setProgress = () => {
zone.setAttribute('aria-busy', state.val < 1)
if (state.val === null) {
progress.removeAttribute('aria-valuenow')
progress.removeAttribute('value')
progress.focus()
return
}
const val = roundDecimals(state.val, 2)
const valPercent = val * 100 + "%"
progress.value = val
progress.setAttribute('aria-valuenow', valPercent)
progress.innerText = valPercent
progress.focus()
}
الخاتمة
الآن بعد أن تعرّفت على كيفية إجراء ذلك، كيف يمكنك‽ 🙂
هناك بالتأكيد بعض التغييرات التي أود إجراؤها إذا توفرت فرصة أخرى. أعتقد أنّ هناك مجالاً لحذف المكوِّن الحالي، وهناك مجال لمحاولة إنشاء مكوّن بدون قيود النمط الصورية الخاصة بعنصر <progress>
. الأمر يستحق الاستكشاف!
يمكننا تنويع أساليبنا وتعلُّم جميع طرق إنشاء المحتوى على الويب.
أنشئ عرضًا توضيحيًا وأضيف روابط تغريدة إليّ. انتقِل إلى قسم الريمكسات في المنتدى أدناه.