ภาพรวมพื้นฐานเกี่ยวกับวิธีสร้างคอมโพเนนต์ FAB ที่ปรับสีตามอุปกรณ์ ตอบสนองได้ และเข้าถึงได้
ในโพสต์นี้ เราต้องการแชร์ความคิดเห็นเกี่ยวกับวิธีสร้างคอมโพเนนต์ FAB ที่ปรับสีตามอุปกรณ์ ปรับเปลี่ยนตามพื้นที่โฆษณา และเข้าถึงได้ ลองใช้ตัวอย่างและดูซอร์สโค้ด
หากต้องการดูวิดีโอ โปรดดูโพสต์เวอร์ชัน YouTube ที่นี่
ภาพรวม
FAB พบในอุปกรณ์เคลื่อนที่มากกว่าในเดสก์ท็อป แต่ก็พบได้ทั้งสองแพลตฟอร์ม แสดงการดำเนินการหลักให้เห็นอยู่เสมอ ทำให้การดำเนินการสะดวกและเข้าถึงได้ทุกที่ สไตล์ประสบการณ์ของผู้ใช้นี้ทำให้ Material UI โด่งดัง และดูคำแนะนำเกี่ยวกับการใช้งานและตำแหน่งได้ที่นี่
องค์ประกอบและสไตล์
HTML สําหรับตัวควบคุมเหล่านี้ประกอบด้วยองค์ประกอบคอนเทนเนอร์และชุดปุ่มอย่างน้อย 1 ชุด คอนเทนเนอร์จะจัดตําแหน่ง FAB ภายในวิวพอร์ตและจัดการช่องว่างระหว่างปุ่ม ปุ่มอาจเป็นปุ่มขนาดเล็กหรือปุ่มเริ่มต้นก็ได้ ซึ่งช่วยให้การดําเนินการหลักและรองมีความหลากหลาย
คอนเทนเนอร์ FAB
องค์ประกอบนี้อาจเป็น <div>
ธรรมดา แต่เรามาช่วยผู้ใช้ที่ตาบอดด้วยการติดแท็กองค์ประกอบนี้ด้วยแอตทริบิวต์ที่เป็นประโยชน์เพื่ออธิบายวัตถุประสงค์และเนื้อหาของคอนเทนเนอร์นี้
มาร์กอัป FAB
เริ่มต้นด้วยคลาส .fabs
เพื่อให้ CSS ฮุกเพื่อจัดสไตล์ จากนั้นเพิ่ม role="group"
และ aria-label
เพื่อให้คอนเทนเนอร์ไม่ใช่แค่คอนเทนเนอร์ทั่วไป แต่มีชื่อและมีวัตถุประสงค์
<div class="fabs" role="group" aria-label="Floating action buttons">
<!-- buttons will go here -->
</div>
สไตล์ของ FAB
FAB จะติดอยู่ในวิวพอร์ตตลอดเวลาเพื่อให้ใช้งานสะดวก
นี่เป็นกรณีการใช้งานที่ยอดเยี่ยมสําหรับตําแหน่ง
fixed
ในตำแหน่งวิวพอร์ตนี้ เราเลือกที่จะใช้ inset-block
และ inset-inline
เพื่อให้ตำแหน่งเสริมโหมดเอกสารของผู้ใช้ เช่น ขวาไปซ้ายหรือซ้ายไปขวา นอกจากนี้ ระบบยังใช้พร็อพเพอร์ตี้ที่กำหนดเองเพื่อป้องกันการซ้ำและตรวจสอบว่าชิ้นงานอยู่ห่างจากขอบด้านล่างและขอบด้านข้างของวิวพอร์ตเท่าๆ กัน
.fabs {
--_viewport-margin: 2.5vmin;
position: fixed;
z-index: var(--layer-1);
inset-block: auto var(--_viewport-margin);
inset-inline: auto var(--_viewport-margin);
}
ต่อไปฉันจะตั้งค่าการแสดงผลของคอนเทนเนอร์เป็น flex
และเปลี่ยนการวางแนวเป็น column-reverse
ซึ่งจะวางรายการย่อยซ้อนกัน (คอลัมน์) และกลับลำดับการแสดงผลด้วย ซึ่งจะส่งผลให้องค์ประกอบที่โฟกัสได้รายการแรกเป็นองค์ประกอบด้านล่างแทนที่จะเป็นด้านบน ซึ่งเป็นตำแหน่งที่โฟกัสจะไปโดยปกติตามเอกสาร HTML การเปลี่ยนลำดับภาพกลับหัวจะช่วยให้ผู้ใช้ที่มองเห็นและผู้ใช้แป้นพิมพ์ได้รับประสบการณ์การใช้งานแบบเดียวกัน เนื่องจากการจัดรูปแบบของการดำเนินการหลักให้ใหญ่กว่าปุ่มขนาดเล็กจะบ่งบอกให้ผู้ใช้ที่มองเห็นทราบว่าเป็นการดำเนินการหลัก และผู้ใช้แป้นพิมพ์จะโฟกัสการดำเนินการดังกล่าวเป็นรายการแรกในแหล่งที่มา
.fabs {
…
display: flex;
flex-direction: column-reverse;
place-items: center;
gap: var(--_viewport-margin);
}
การจัดตำแหน่งกึ่งกลางจะจัดการด้วย place-items
และ gap
จะเพิ่มระยะห่างระหว่างปุ่ม FAB ที่วางไว้ในคอนเทนเนอร์
ปุ่ม FAB
ถึงเวลาจัดสไตล์ปุ่มบางปุ่มให้ดูเหมือนลอยอยู่เหนือสิ่งอื่นๆ
FAB เริ่มต้น
ปุ่มแรกที่จัดสไตล์จะเป็นปุ่มเริ่มต้น ซึ่งจะเป็นฐานสำหรับปุ่ม FAB ทั้งหมด เราจะสร้างตัวแปรที่มีลักษณะอื่นในภายหลังโดยแก้ไขสไตล์พื้นฐานเหล่านี้ให้น้อยที่สุด
มาร์กอัป FAB
องค์ประกอบ <button>
คือตัวเลือกที่ถูกต้อง เราจะเริ่มต้นด้วยเวอร์ชันนี้เนื่องจากมีฟีเจอร์ที่ยอดเยี่ยมสำหรับผู้ใช้เมาส์ หน้าจอสัมผัส และแป้นพิมพ์ สิ่งที่สําคัญที่สุดของมาร์กอัปนี้คือซ่อนไอคอนจากผู้ใช้โปรแกรมอ่านหน้าจอด้วย aria-hidden="true"
และเพิ่มข้อความป้ายกำกับที่จําเป็นลงในมาร์กอัป <button>
เอง เมื่อเพิ่มป้ายกำกับในกรณีเหล่านี้ เรายังชอบเพิ่ม title
ด้วยเพื่อให้ผู้ใช้ที่เลื่อนเมาส์ดูข้อมูลเกี่ยวกับสิ่งที่ไอคอนต้องการสื่อ
<button data-icon="plus" class="fab" title="Add new action" aria-label="Add new action">
<svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>
สไตล์ FAB
ก่อนอื่นมาเปลี่ยนปุ่มให้เป็นปุ่มกลมที่มีขอบหนาและมีเงาเข้มกัน เพราะเป็นลักษณะเด่นแรกของปุ่ม
.fab {
--_size: 2rem;
padding: calc(var(--_size) / 2);
border-radius: var(--radius-round);
aspect-ratio: 1;
box-shadow: var(--shadow-4);
}
ถัดไป มาเพิ่มสีกัน เราจะใช้กลยุทธ์ที่เคยใช้ในโจทย์ GUI มาก่อน สร้างชุดพร็อพเพอร์ตี้ที่กำหนดเองที่มีชื่อชัดเจนซึ่งเก็บสีสว่างและสีเข้มไว้แบบคงที่ จากนั้นสร้างพร็อพเพอร์ตี้ที่กำหนดเองแบบปรับเปลี่ยนได้ซึ่งจะตั้งค่าเป็นตัวแปรสีสว่างหรือสีเข้มโดยขึ้นอยู่กับค่ากำหนดของระบบสำหรับสีของผู้ใช้
.fab {
…
/* light button and button hover */
--_light-bg: var(--pink-6);
--_light-bg-hover: var(--pink-7);
/* dark button and button hover */
--_dark-bg: var(--pink-4);
--_dark-bg-hover: var(--pink-3);
/* adaptive variables set to light by default */
--_bg: var(--_light-bg);
/* static icon colors set to the adaptive foreground variable */
--_light-fg: white;
--_dark-fg: black;
--_fg: var(--_light-fg);
/* use the adaptive properties on some styles */
background: var(--_bg);
color: var(--_fg);
&:is(:active, :hover, :focus-visible) {
--_bg: var(--_light-bg-hover);
@media (prefers-color-scheme: dark) {
--_bg: var(--_dark-bg-hover);
}
}
/* if users prefers dark, set adaptive props to dark */
@media (prefers-color-scheme: dark) {
--_bg: var(--_dark-bg);
--_fg: var(--_dark-fg);
}
}
จากนั้นเพิ่มสไตล์เพื่อช่วยให้ไอคอน SVG เข้ากับพื้นที่
.fab {
…
& > svg {
inline-size: var(--_size);
block-size: var(--_size);
stroke-width: 3px;
}
}
สุดท้าย ให้นำไฮไลต์การแตะออกจากปุ่มเนื่องจากเราได้เพิ่มการตอบกลับด้วยภาพของเราเองสำหรับการโต้ตอบแล้ว
.fab {
-webkit-tap-highlight-color: transparent;
}
FAB ขนาดเล็ก
เป้าหมายของส่วนนี้คือการสร้างตัวแปรสําหรับปุ่ม FAB การทำ FAB บางรายการให้เล็กกว่าการดำเนินการเริ่มต้นจะช่วยให้เราโปรโมตการดำเนินการที่ผู้ใช้ทำบ่อยที่สุดได้
มาร์กอัป FAB ขนาดเล็ก
HTML เหมือนกับ FAB แต่เราเพิ่มคลาส ".mini" เพื่อให้ CSS เข้าถึงตัวแปรได้
<button data-icon="heart" class="fab mini" title="Like action" aria-label="Like action">
<svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>
สไตล์ FAB ขนาดเล็ก
การใช้พร็อพเพอร์ตี้ที่กําหนดเองทําให้การเปลี่ยนแปลงเพียงอย่างเดียวที่จําเป็นคือการปรับตัวแปร --_size
.fab.mini {
--_size: 1.25rem;
}
การช่วยเหลือพิเศษ
สิ่งสำคัญที่สุดที่ควรจำไว้สำหรับการช่วยเหลือพิเศษด้วย FAB คือตําแหน่งภายในโฟลว์แป้นพิมพ์ของหน้า การสาธิตนี้มีเพียง FAB เท่านั้น ไม่มีลำดับและขั้นตอนของแป้นพิมพ์ที่จะแข่งขันได้ ซึ่งหมายความว่าไม่มีโอกาสที่จะสาธิตขั้นตอนของแป้นพิมพ์ที่มีความหมาย ในกรณีที่มีองค์ประกอบที่แย่งโฟกัสกัน เราขอแนะนำให้พิจารณาอย่างละเอียดว่าผู้ใช้ควรเข้าสู่ขั้นตอนของปุ่ม FAB ตรงจุดใดในขั้นตอนนั้น
เมื่อผู้ใช้โฟกัสไปที่คอนเทนเนอร์ FAB เราได้เพิ่ม role="group"
และ aria-label="floating action buttons"
ไว้แล้ว ซึ่งจะแจ้งให้ผู้ใช้โปรแกรมอ่านหน้าจอทราบเกี่ยวกับเนื้อหาที่โฟกัส เราวาง FAB เริ่มต้นไว้ก่อนเพื่อช่วยให้ผู้ใช้เห็นการดําเนินการหลักก่อน จากนั้นใช้ flex-direction: column-reverse;
เพื่อจัดลำดับปุ่มหลักที่ด้านล่างซึ่งอยู่ใกล้กับนิ้วของผู้ใช้เพื่อให้เข้าถึงได้ง่าย นี่เป็นการเปลี่ยนแปลงที่ยอดเยี่ยมเนื่องจากปุ่มเริ่มต้นจะโดดเด่นและแสดงเป็นปุ่มแรกสำหรับผู้ใช้แป้นพิมพ์ ซึ่งทำให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่คล้ายกันมาก
สุดท้าย อย่าลืมซ่อนไอคอนจากผู้ใช้โปรแกรมอ่านหน้าจอและตรวจสอบว่าคุณได้ระบุป้ายกำกับสำหรับปุ่มเพื่อให้ผู้ใช้ทราบถึงฟังก์ชันของปุ่ม การดำเนินการนี้ทำใน HTML เรียบร้อยแล้วโดยใช้ aria-hidden="true"
ใน <svg>
และ aria-label="Some action"
ใน <button>
แอนิเมชัน
คุณสามารถเพิ่มภาพเคลื่อนไหวประเภทต่างๆ เพื่อปรับปรุงประสบการณ์ของผู้ใช้ เช่นเดียวกับใน GUI Challenge อื่นๆ เราจะตั้งค่าพร็อพเพอร์ตี้ที่กำหนดเอง 2 รายการเพื่อเก็บไว้สำหรับประสบการณ์แบบลดการเคลื่อนไหวและแบบการเคลื่อนไหวเต็มรูปแบบ โดยค่าเริ่มต้น สไตล์จะถือว่าผู้ใช้ต้องการลดการเคลื่อนไหว จากนั้นจะใช้ prefers-reduced-motion
Media Query เพื่อเปลี่ยนค่าการเปลี่ยนเป็นการเคลื่อนไหวแบบเต็ม
กลยุทธ์การเคลื่อนไหวลดลงที่มีพร็อพเพอร์ตี้ที่กำหนดเอง
ระบบจะสร้างพร็อพเพอร์ตี้ที่กำหนดเอง 3 รายการใน CSS ต่อไปนี้ --_motion-reduced
,
--_motion-ok
และ --_transition
2 รายการแรกจะเก็บการเปลี่ยนที่เหมาะสมตามค่ากําหนดของผู้ใช้ และระบบจะตั้งค่าตัวแปร --_transition
สุดท้ายเป็น --_motion-reduced
หรือ --_motion-ok
ตามลําดับ
.fab {
/* box-shadow and background-color can safely be transitioned for reduced motion users */
--_motion-reduced:
box-shadow .2s var(--ease-3),
background-color .3s var(--ease-3);
/* add transform and outline-offset for users ok with motion */
--_motion-ok:
var(--_motion-reduced),
transform .2s var(--ease-3),
outline-offset 145ms var(--ease-2);
/* default the transition styles to reduced motion */
--_transition: var(--_motion-reduced);
/* set the transition to our adaptive transition custom property*/
transition: var(--_transition);
/* if motion is ok, update the adaptive prop to the respective transition prop */
@media (prefers-reduced-motion: no-preference) {
--_transition: var(--_motion-ok);
}
}
เมื่อทำตามขั้นตอนข้างต้นแล้ว คุณจะเปลี่ยน box-shadow
, background-color
,
transform
และ outline-offset
ได้ ซึ่งจะช่วยให้ผู้ใช้ได้รับฟีดแบ็ก UI ที่ดีว่าระบบได้รับข้อมูลที่โต้ตอบแล้ว
ถัดไป ให้เพิ่มลูกเล่นเล็กน้อยให้กับสถานะ :active
โดยปรับ
translateY
เล็กน้อย ซึ่งจะทำให้ปุ่มมีเอฟเฟกต์การกดที่ดูดี
.fab {
…
&:active {
@media (prefers-reduced-motion: no-preference) {
transform: translateY(2%);
}
}
}
สุดท้าย ให้เปลี่ยนไอคอน SVG ในปุ่มตามการเปลี่ยนแปลงต่อไปนี้
.fab {
…
&[data-icon="plus"]:hover > svg {
transform: rotateZ(.25turn);
}
& > svg {
@media (prefers-reduced-motion: no-preference) {
will-change: transform;
transition: transform .5s var(--ease-squish-3);
}
}
}
บทสรุป
ตอนนี้คุณรู้วิธีที่เราทำแล้ว คุณจะทำอย่างไรบ้าง 🙂
มาลองใช้แนวทางที่หลากหลายและดูวิธีทั้งหมดในการสร้างบนเว็บกัน
สร้างเดโม แล้วทวีตลิงก์มาหาเรา เราจะเพิ่มลงในส่วนรีมิกซ์ของชุมชนด้านล่าง
รีมิกซ์ของชุมชน
ยังไม่มีข้อมูลใดๆ
แหล่งข้อมูล
- ซอร์สโค้ดใน GitHub