การสร้างคอมโพเนนต์ปุ่มการทำงานแบบลอย (FAB)

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

ปุ่ม FAB 2 ปุ่มแสดงขึ้นโดยมี DevTools วางซ้อนทับเลย์เอาต์ตารางกริด แสดงช่องว่างระหว่างองค์ประกอบด้วยลายทาง และแสดงความสูงและความกว้างที่คำนวณแล้ว

.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 2 ปุ่มซ้อนกัน โดยปุ่มด้านบนมีขนาดเล็กกว่าปุ่มด้านล่าง

การช่วยเหลือพิเศษ

สิ่งสำคัญที่สุดที่ควรจำไว้สำหรับการช่วยเหลือพิเศษด้วย 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);
    }
  }
}

บทสรุป

ตอนนี้คุณรู้วิธีที่เราทำแล้ว คุณจะทำอย่างไรบ้าง 🙂

มาลองใช้แนวทางที่หลากหลายและดูวิธีทั้งหมดในการสร้างบนเว็บกัน

สร้างเดโม แล้วทวีตลิงก์มาหาเรา เราจะเพิ่มลงในส่วนรีมิกซ์ของชุมชนด้านล่าง

รีมิกซ์ของชุมชน

ยังไม่มีข้อมูลใดๆ

แหล่งข้อมูล