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

มาร์กอัป 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>
รูปแบบ Mini 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);
    }
  }
}

บทสรุป

ตอนนี้คุณก็รู้แล้วว่าฉันทำท่านั้นได้อย่างไร คุณจะทำยังไงบ้างคะ‽ 🙂

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

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

รีมิกซ์ในชุมชน

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

แหล่งข้อมูล