องค์ประกอบ <progress> เป็นวิธีเชิงความหมายในการแสดงความคืบหน้าของงาน เช่น การดาวน์โหลดหรืออัปโหลดข้อมูล หรือการดำเนินการบางส่วนของกระบวนการที่มีหลายขั้นตอนให้เสร็จสมบูรณ์ การใช้องค์ประกอบแบบเนทีฟจะช่วยในเรื่องการช่วยเหลือพิเศษ เนื่องจากโปรแกรมอ่านหน้าจอมี role="progressbar" โดยนัยและสามารถอ่านค่าได้
คู่มือนี้จะใช้แถบความคืบหน้าแนวนอนที่มีการจัดรูปแบบอย่างสมบูรณ์พร้อมการปรับแต่งสไตล์
แถบความคืบหน้าหรือวงกลมแสดงความคืบหน้า
- หากมีพื้นที่จำกัดหรือต้องการสัดส่วนภาพแบบสี่เหลี่ยมจัตุรัส ให้พิจารณาใช้แถบความคืบหน้าแบบวงกลม (วงกลมแสดงความคืบหน้า): วงกลมแสดงความคืบหน้า
- ใช้ไอคอนหมุนสำหรับสถานการณ์ส่วนใหญ่ที่ความคืบหน้าไม่แน่นอน (ไอคอนหมุนแสดงการโหลด) ใช้แถบความคืบหน้าแบบไม่ระบุเวลาเมื่อสถานะไม่ระบุเวลาเป็นแบบชั่วคราว และจะถูกแทนที่ด้วยแถบความคืบหน้าแบบระบุเวลาในเร็วๆ นี้ (เช่น การรอข้อมูลเมตาเกี่ยวกับการอัปโหลดก่อนที่จะแสดง % ความคืบหน้า)
Markup
- ใช้องค์ประกอบ
<progress>แบบเนทีฟ: ซึ่งจะให้การช่วยเหลือพิเศษในตัวและลักษณะการทำงานที่สอดคล้องกันในแพลตฟอร์ม - ใช้
maxหากต้องการใช้ระดับคะแนนที่แตกต่างจากระดับคะแนน 0-1 เริ่มต้น - หากต้องการค่าความคืบหน้าที่เฉพาะเจาะจง ให้ตั้งค่าแอตทริบิวต์
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) จะปิดใช้การจัดรูปแบบแถบความคืบหน้าเริ่มต้นโดยไม่มีการแจ้งเตือน หากต้องการจัดรูปแบบนอกเหนือจากพร็อพเพอร์ตี้ข้างต้น คุณต้องใช้การจัดรูปแบบที่กำหนดเองทั้งหมดตามที่อธิบายไว้ในส่วนถัดไป อย่าใช้การจัดรูปแบบที่ครอบคลุมมากขึ้น "เผื่อว่าจะได้ผล"
การจัดรูปแบบที่กำหนดเองอย่างเต็มรูปแบบ
1. การตั้งค่าพื้นฐาน
- บังคับ: ใช้
appearance: noneเพื่อเปิดใช้การจัดรูปแบบที่กำหนดเอง - รีเซ็ตขอบเขต UA ด้วย
border: 0 solid - หากต้องการคลิปแถบที่ใช้งานอยู่กับรัศมีเส้นขอบขององค์ประกอบ ให้ใช้
overflow: clipหรือใช้border-radiusเดียวกันกับแถบ อย่าใช้border-radius: inheritในแถบ ซึ่งขึ้นอยู่กับโครงสร้างเฉพาะขององค์ประกอบใน Shadow DOM
progress {
/* Reset default browser styles */
appearance: none;
border: 0 solid;
/* Clip bar to element’s border-radius */
overflow: clip;
}
2. การจัดรูปแบบ
- จัดสไตล์แทร็กในองค์ประกอบ
progressเอง - ใช้องค์ประกอบเทียมที่กำหนดเป้าหมายเบราว์เซอร์ที่เหมาะสมเพื่อกำหนดเป้าหมายแถบความคืบหน้าเอง:
::-webkit-progress-valueสำหรับ WebKit/Blink และ::-moz-progress-barสำหรับ Firefox - บังคับ: อย่าจัดกลุ่มองค์ประกอบจำลอง
-webkit-และ-moz-ไว้ในกฎเดียวกัน ระบบจะถือว่ากฎไม่ถูกต้องและจะละเว้นกฎดังกล่าว: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;
}
3. การจัดรูปแบบสถานะไม่แน่นอน
เพิ่มภาพเคลื่อนไหวที่กำหนดเองสำหรับสถานะไม่แน่นอน: เปลี่ยนองค์ประกอบจำลองการเติมให้เป็นส่วนสั้นๆ แล้วเลื่อนไปตามแทร็ก
- จัดรูปแบบการเติมสีเอง อย่าสร้างใหม่เป็นพื้นหลังใน
progress - การเติมแบบไม่แน่นอนจะเกิดขึ้นผ่านภาพเคลื่อนไหวเท่านั้น โดยคีย์เฟรมจะกำหนดความยาวด้วย
inline-sizeจริง (ซึ่งจะแทนที่inline-sizeในบรรทัดของ UA ของ Chromium) และย้ายด้วยtranslateอย่าใช้scaleสำหรับความยาว เนื่องจากจะทำให้ลวดลายที่วาดบนการเติมบิดเบี้ยว - เปอร์เซ็นต์
translateจะเทียบกับความกว้างของเส้นเติมเอง ดังนั้นให้แสดงตำแหน่งในหน่วยแทร็กแทน โดยทำให้progressเป็นคอนเทนเนอร์ขนาดในบรรทัดและใช้cqiในคีย์เฟรม รวมmargin-right: autoไว้ในfrom, toเพื่อให้ Chromium วางการเติมที่ด้านซ้ายจริงใน RTL ด้วย - ใช้การเปลี่ยนรูปแบบ ไม่ใช่ระยะขอบ เพื่อย้ายการเติม
- การเปลี่ยนรูปแบบจะเก็บภาพเคลื่อนไหวไว้ในคอมโพสิเตอร์ (เว้นแต่ว่า
inline-sizeจะเคลื่อนไหวด้วย) - ระยะขอบจะแบ่งออกเป็น RTL ด้วยเหตุผล 2 ประการแยกกัน ดังนี้
- Firefox จะวางตำแหน่งการเติมที่ไม่แน่นอนโดยใช้เฉพาะระยะขอบด้านซ้ายจริง ดังนั้น
margin-inline-startจึงไม่มีผลใน RTL และการเติมจะไม่เคลื่อนที่ - ใน Chromium และ WebKit ซึ่งจัดวางการเติมเป็นบล็อกปกติ เมื่อระยะขอบดันการเติมให้เลยจุดสิ้นสุดของแทร็ก ระยะขอบจะรวมกันมากกว่าแทร็ก CSS มาตรฐานจะแก้ไขปัญหานี้โดยละเว้น
margin-leftใน RTL เพื่อให้ส่วนดังกล่าวข้ามไปยังขอบแทนที่จะเลื่อนออกไป translateจะมีผลหลังจากเลย์เอาต์ ดังนั้นจึงไม่มีปัญหาใดๆ
- การเปลี่ยนรูปแบบจะเก็บภาพเคลื่อนไหวไว้ในคอมโพสิเตอร์ (เว้นแต่ว่า
- หากต้องการมิเรอร์การเคลื่อนไหวใน RTL (เหมือนกับแถบเนทีฟของ 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เป็นภาพเคลื่อนไหวที่เกิดขึ้นพร้อมกัน 2 รายการ โดยรายการหนึ่งมีคีย์เฟรมที่ทำให้translateเคลื่อนไหวในcqi(ตำแหน่ง) และอีกรายการหนึ่งมีคีย์เฟรมที่ทำให้inline-sizeเคลื่อนไหว (ความยาว) เพื่อให้แต่ละรายการมีคีย์เฟรมและการค่อยๆ เปลี่ยนของตัวเอง อย่าพยายามปรับรูปร่างขอบทั้ง 2 ด้านในรายการคีย์เฟรมเดียว เนื่องจากanimation-timing-functionต่อคีย์เฟรมจะมีผลกับพร็อพเพอร์ตี้ทุกรายการในคีย์เฟรมนั้น --progress-bar-animationจะมีผลในทั้ง 2 สถานะและใช้สำหรับเอฟเฟกต์ต่างๆ ได้ เช่น ชิมเมอร์แบบกำหนดได้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 เป็นการเพิ่มประสิทธิภาพแบบต่อเนื่อง
เบราว์เซอร์ที่ไม่รองรับพร็อพเพอร์ตี้นี้จะละเว้นและใช้สี UI เริ่มต้น
หากไม่รองรับ accent-color และจำเป็นต้องจัดรูปแบบแถบความคืบหน้า ให้ใช้วิธีการจัดรูปแบบที่กำหนดเองเพื่อใช้การจัดรูปแบบที่ต้องการกับแถบความคืบหน้า
การสำรองและการรองรับเบราว์เซอร์สำหรับ revert-rule
หากไม่รองรับ revert-rule animation: var(--progress-bar-animation, revert-rule) จะเปลี่ยนกลับไปใช้ animation-name: revert-rule โดยมีระยะเวลา 0s เมื่อไม่ได้ตั้งค่า --progress-bar-animation ซึ่งเป็นการดำเนินการที่ไม่มีผลเมื่อไม่มี @keyframes revert-rule