ภาพรวมพื้นฐานของวิธีสร้างคอมโพเนนต์ FAB ที่ปรับเปลี่ยนสี ปรับเปลี่ยนตามอุปกรณ์ และเข้าถึงได้
ในโพสต์นี้ ผมอยากแชร์ความคิดเห็นเกี่ยวกับวิธีสร้างคอมโพเนนต์ FAB ที่ปรับเปลี่ยนสี ปรับเปลี่ยนตามอุปกรณ์ และเข้าถึงได้ ลองดูการสาธิตและดูแหล่งที่มา
หากชอบวิดีโอ นี่คือโพสต์นี้เวอร์ชัน YouTube
ภาพรวม
FAB พบในอุปกรณ์เคลื่อนที่มากกว่าเดสก์ท็อป แต่ก็พบเห็นได้บ่อยในทั้ง 2 สถานการณ์ โดยจะแสดงการกระทำหลักอยู่เสมอ ทำให้เข้าถึงได้อย่างสะดวกสบาย รูปแบบประสบการณ์ของผู้ใช้นี้มีชื่อเสียงจาก 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 บางรายการมีขนาดเล็กกว่าการกระทำเริ่มต้น เราสามารถส่งเสริมการดำเนินการที่ผู้ใช้ทำบ่อยที่สุดได้
มาร์กอัป Mini 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 อื่นๆ เราจะกำหนดคุณสมบัติที่กำหนดเอง 2 รายการเพื่อคงประสบการณ์การเคลื่อนไหวที่ลดลงและมอบประสบการณ์การเคลื่อนไหวเต็มรูปแบบ โดยค่าเริ่มต้น
สไตล์จะถือว่าผู้ใช้ต้องการลดการเคลื่อนไหว จากนั้นการใช้
คิวรี่สื่อ prefers-reduced-motion
จะสับเปลี่ยนค่าการเปลี่ยนไปเป็นแบบเต็มการเคลื่อนไหว
กลยุทธ์การเคลื่อนไหวที่ลดลงพร้อมคุณสมบัติที่กำหนดเอง
ระบบจะสร้างพร็อพเพอร์ตี้ที่กำหนดเอง 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