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

ภาพรวมพื้นฐานเกี่ยวกับวิธีสร้างคอมโพเนนต์ FAB ที่ปรับสีตามธีม ตอบสนอง และเข้าถึงได้

ในโพสต์นี้ ผมอยากจะแชร์ความคิดเห็นเกี่ยวกับวิธีสร้างคอมโพเนนต์ FAB ที่ปรับสีได้ ตอบสนอง และเข้าถึงได้ ลองใช้ เดโมและดู แหล่งที่มา

หากต้องการดูวิดีโอ โปรดดูโพสต์นี้ใน YouTube

ภาพรวม

FAB พบในอุปกรณ์เคลื่อนที่มากกว่าเดสก์ท็อป แต่ก็พบได้ทั้ง 2 กรณี ปุ่มเหล่านี้จะแสดงการกระทำหลักอยู่เสมอ ทำให้สะดวกและ ใช้งานได้ทุกที่ รูปแบบประสบการณ์ของผู้ใช้นี้เป็นที่รู้จักกันดีใน Material UI และดูคำแนะนำในการใช้งานและการวางได้ที่นี่

องค์ประกอบและรูปแบบ

HTML สำหรับตัวควบคุมเหล่านี้ประกอบด้วยองค์ประกอบคอนเทนเนอร์และชุดปุ่มอย่างน้อย 1 ปุ่ม คอนเทนเนอร์จะจัดตำแหน่ง FAB ภายในวิวพอร์ตและจัดการ ช่องว่างระหว่างปุ่ม ปุ่มอาจมีขนาดเล็กหรือค่าเริ่มต้น ซึ่งช่วยให้การทำงานหลักและรองมีความหลากหลาย มากขึ้น

คอนเทนเนอร์ FAB

องค์ประกอบนี้อาจเป็น <div> ปกติ แต่เรามาช่วยผู้ใช้ที่มองไม่เห็นกัน โดยติดแท็กด้วยแอตทริบิวต์ที่เป็นประโยชน์เพื่ออธิบายวัตถุประสงค์และเนื้อหาของ คอนเทนเนอร์นี้

มาร์กอัป FAB

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

ปุ่มลอย 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 มี Hook เข้าไปใน รูปแบบ

<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 อื่นๆ เราจะตั้งค่าพร็อพเพอร์ตี้ที่กำหนดเอง 2-3 รายการเพื่อเก็บ ความตั้งใจของประสบการณ์การเคลื่อนไหวที่ลดลงและประสบการณ์การเคลื่อนไหวเต็มรูปแบบ โดยค่าเริ่มต้น สไตล์จะถือว่าผู้ใช้ต้องการลดการเคลื่อนไหว จากนั้นใช้ 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);
    }
  }
}

บทสรุป

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

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

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

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

ยังไม่มีอะไรให้ดูที่นี่

แหล่งข้อมูล