แพลตฟอร์มเว็บเต็มไปด้วยนวัตกรรม โดยมีฟีเจอร์ CSS และ UI เว็บเป็นหัวใจสำคัญของการเปลี่ยนแปลงที่น่าตื่นเต้นนี้ เรากำลังอยู่ในยุคทองของ UI บนเว็บ โดยมีฟีเจอร์ CSS ใหม่ๆ ที่พร้อมใช้งานในเบราว์เซอร์ต่างๆ อย่างรวดเร็วอย่างที่ไม่เคยมีมาก่อน ซึ่งเปิดโอกาสให้เราสร้างประสบการณ์บนเว็บที่สวยงามและน่าสนใจได้มากมาย บล็อกโพสต์นี้จะเจาะลึกสถานะปัจจุบันของ CSS โดยสำรวจฟีเจอร์ใหม่ๆ ที่เปลี่ยนแปลงเกมมากที่สุด ซึ่งจะมาเปลี่ยนคำจำกัดความของวิธีที่เราสร้างเว็บแอปพลิเคชัน โดยฟีเจอร์เหล่านี้จะมีการนำเสนอแบบสดๆ ในงาน Google I/O 2024
ประสบการณ์แบบอินเทอร์แอกทีฟรูปแบบใหม่
ประสบการณ์การใช้งานเว็บคือการเรียกและการตอบสนองระหว่างคุณกับผู้ใช้ การลงทุนในการโต้ตอบของผู้ใช้ที่มีคุณภาพจึงเป็นสิ่งสำคัญอย่างยิ่ง เรากำลังดำเนินการปรับปรุงครั้งใหญ่ที่จะช่วยให้เราสามารถนำเสนอความสามารถที่ไม่เคยมีมาก่อนบนเว็บสำหรับการไปยังส่วนต่างๆ ภายในหน้าเว็บและการไปยังส่วนต่างๆ ระหว่างหน้าเว็บ
ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน
API ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนช่วยให้คุณสร้างภาพเคลื่อนไหวแบบไดนามิกตามการเลื่อนได้โดยไม่ต้องอาศัยเครื่องสังเกตการณ์การเลื่อนหรือการเขียนสคริปต์ที่ซับซ้อนอื่นๆ
สร้างภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน
ตอนนี้คุณสามารถใช้ความคืบหน้าในการเลื่อนของตัวเลื่อนเพื่อเริ่ม หยุดชั่วคราว และย้อนกลับภาพเคลื่อนไหวได้แล้ว ซึ่งคล้ายกับวิธีที่ภาพเคลื่อนไหวตามเวลาทำงานบนแพลตฟอร์ม ดังนั้นขณะเลื่อนไปข้างหน้า คุณจะเห็นความคืบหน้าของภาพเคลื่อนไหว และเมื่อเลื่อนถอยหลัง ภาพเคลื่อนไหวจะย้อนกลับ ซึ่งช่วยให้คุณสร้างภาพทั้งหน้าหรือบางส่วนของหน้าเว็บโดยมีองค์ประกอบที่เคลื่อนไหวเข้าและอยู่ภายใน Viewport หรือที่เรียกว่า Scrollytelling เพื่อให้ภาพมีความเคลื่อนไหวแบบไดนามิก
คุณใช้ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนเพื่อไฮไลต์เนื้อหาสำคัญ นำผู้ใช้ผ่านเรื่องราว หรือเพียงแค่เพิ่มลูกเล่นแบบไดนามิกลงในหน้าเว็บได้
ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน
การสาธิตแบบสด
@keyframes appear {
  from {
    opacity: 0;
    scale: 0.8;
  }
  to {
    opacity: 1;
    scale: 1;
  }
}
img {
  animation: appear linear;
  animation-timeline: view();
  animation-range: entry 25% cover 50%;
}
โค้ดก่อนหน้าจะกำหนดภาพเคลื่อนไหวอย่างง่ายที่ปรากฏใน Viewport โดยการเปลี่ยนความทึบและขนาดของรูปภาพ ภาพเคลื่อนไหวจะขับเคลื่อนด้วยตำแหน่งการเลื่อน หากต้องการสร้างเอฟเฟกต์นี้ ให้ตั้งค่าภาพเคลื่อนไหว CSS ก่อน แล้วจึงตั้งค่า animation-timeline ในกรณีนี้ view() ฟังก์ชันที่มีค่าเริ่มต้นจะติดตามรูปภาพที่สัมพันธ์กับ Scrollport (ซึ่งในอินสแตนซ์นี้ก็คือ Viewport)
คุณควรคำนึงถึงการรองรับเบราว์เซอร์และค่ากำหนดของผู้ใช้ โดยเฉพาะอย่างยิ่งความต้องการด้านการช่วยเหลือพิเศษ ดังนั้น ให้ใช้กฎ @supports เพื่อตรวจสอบว่าเบราว์เซอร์รองรับภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนหรือไม่ และห่อหุ้มภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนในคำค้นหาค่ากำหนดของผู้ใช้ เช่น @media (prefers-reduced-motion: no-preference) เพื่อให้เป็นไปตามค่ากำหนดการเคลื่อนไหวของผู้ใช้ เมื่อตรวจสอบแล้ว คุณจะทราบว่าสไตล์จะใช้งานได้ และภาพเคลื่อนไหวจะไม่เป็นปัญหาสำหรับผู้ใช้
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Apply scroll-driven animations here */
  }
}
ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนอาจหมายถึงประสบการณ์การเล่าเรื่องด้วยการเลื่อนแบบเต็มหน้า แต่ก็อาจหมายถึงภาพเคลื่อนไหวที่ละเอียดอ่อนกว่า เช่น แถบส่วนหัวที่ย่อเล็กสุดและแสดงเงาขณะที่คุณเลื่อนเว็บแอป
ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน
การสาธิตแบบสด
@keyframes shrink-name {
  from {
    font-size: 2em;
  }
  to {
    font-size: 1.5em;
  }
}
@keyframes add-shadow {
  from {
    box-shadow: none;
  }
  to {
    box-shadow: 0 4px 2px -2px gray;
  }
}
header {
  animation: add-shadow linear both;
}
h2 {
  animation: shrink-name linear both;
}
header, h2 {
  animation-timeline: scroll();
  animation-range: 0 150px;
}
การสาธิตนี้ใช้ภาพเคลื่อนไหวคีย์เฟรมที่แตกต่างกัน 2-3 รายการ ได้แก่ ส่วนหัว ข้อความ แถบนำทาง และพื้นหลัง จากนั้นใช้ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนที่เกี่ยวข้องกับแต่ละรายการ แม้ว่าแต่ละรายการจะมีสไตล์ภาพเคลื่อนไหวที่แตกต่างกัน แต่ทั้งหมดก็มีไทม์ไลน์ภาพเคลื่อนไหวเดียวกัน ตัวเลื่อนที่ใกล้ที่สุด และช่วงภาพเคลื่อนไหวเดียวกัน ซึ่งก็คือจากด้านบนของหน้าเว็บไปจนถึง 150 พิกเซล
ประโยชน์ด้านประสิทธิภาพของภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน
API ในตัวนี้ช่วยลดภาระด้านโค้ดที่คุณต้องดูแล ไม่ว่าจะเป็นสคริปต์ที่กำหนดเองที่คุณเขียนขึ้นหรือการรวมการขึ้นต่อกันของบุคคลที่สามเพิ่มเติม นอกจากนี้ยังช่วยลดความจำเป็นในการจัดส่ง Scroll Observer ต่างๆ ซึ่งหมายถึงประสิทธิภาพที่เพิ่มขึ้นอย่างมาก เนื่องจากภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนจะทำงานในเธรดหลักเมื่อเคลื่อนไหวพร็อพเพอร์ตี้ที่เคลื่อนไหวได้ใน Compositor เช่น การเปลี่ยนรูปแบบและความทึบ ไม่ว่าคุณจะใช้ API ใหม่ใน CSS โดยตรงหรือใช้ Hook ของ JavaScript
Tokopedia เพิ่งใช้ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนเพื่อให้แถบนำทางผลิตภัณฑ์ปรากฏขึ้นขณะที่คุณเลื่อน การใช้ API นี้มีประโยชน์อย่างมากทั้งในด้านการจัดการโค้ดและประสิทธิภาพ
"เราสามารถลดจำนวนบรรทัดของโค้ดได้ถึง 80% เมื่อเทียบกับการใช้เหตุการณ์การเลื่อน JS แบบเดิม และสังเกตว่าการใช้งาน CPU โดยเฉลี่ยลดลงจาก 50% เป็น 2% ขณะเลื่อน - Andy Wihalim, Senior Software Engineer, Tokopedia"
อนาคตของเอฟเฟกต์การเลื่อน
เราทราบว่าเอฟเฟกต์เหล่านี้จะช่วยให้เว็บเป็นสถานที่ที่น่าสนใจยิ่งขึ้น และเรากำลังคิดถึงสิ่งที่จะเกิดขึ้นต่อไป ซึ่งรวมถึงความสามารถในการไม่เพียงใช้ไทม์ไลน์ภาพเคลื่อนไหวใหม่เท่านั้น แต่ยังใช้จุดเลื่อนเพื่อทริกเกอร์การเริ่มต้นภาพเคลื่อนไหวที่เรียกว่าภาพเคลื่อนไหวที่ทริกเกอร์ด้วยการเลื่อนได้อีกด้วย
และจะมีฟีเจอร์การเลื่อนเพิ่มเติมในเบราว์เซอร์ในอนาคต การสาธิตต่อไปนี้แสดงการรวมฟีเจอร์ในอนาคตเหล่านี้ โดยใช้ CSS scroll-start-target เพื่อตั้งค่าวันที่และเวลาเริ่มต้นภายในเครื่องมือเลือก และเหตุการณ์ JavaScript scrollsnapchange เพื่ออัปเดตวันที่ส่วนหัว ซึ่งช่วยให้ซิงค์ข้อมูลกับเหตุการณ์ที่สแนปได้ง่าย
นอกจากนี้ คุณยังใช้ข้อมูลนี้เพื่ออัปเดตเครื่องมือเลือกแบบเรียลไทม์ด้วยเหตุการณ์ JavaScript scrollsnapchanging ได้ด้วย
ปัจจุบันฟีเจอร์เหล่านี้อยู่ใน Canary โดยซ่อนอยู่หลัง Flag อย่างไรก็ตาม ฟีเจอร์เหล่านี้จะปลดล็อกความสามารถที่ก่อนหน้านี้เป็นไปไม่ได้หรือสร้างได้ยากมากในแพลตฟอร์ม และยังเน้นย้ำถึงความเป็นไปได้ของการโต้ตอบแบบเลื่อนในอนาคตอีกด้วย
หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับการเริ่มต้นใช้งานภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน ทีมของเราเพิ่งเปิดตัววิดีโอซีรีส์ใหม่ที่คุณดูได้ในช่อง YouTube ของ Chrome for Developers ในส่วนนี้ คุณจะได้เรียนรู้พื้นฐานของภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนจาก Bramus Van Damme ซึ่งรวมถึงวิธีการทำงานของฟีเจอร์ คำศัพท์ วิธีต่างๆ ในการสร้างเอฟเฟกต์ และวิธีรวมเอฟเฟกต์เพื่อสร้างประสบการณ์ที่สมบูรณ์ ซึ่งเป็นวิดีโอซีรีส์ที่ยอดเยี่ยมที่คุณควรลองดู
ดูการเปลี่ยน
เราเพิ่งพูดถึงฟีเจอร์ใหม่ที่มีประสิทธิภาพในการสร้างภาพเคลื่อนไหวภายในหน้าเว็บ แต่ก็ยังมีฟีเจอร์ใหม่ที่มีประสิทธิภาพอีกอย่างหนึ่งที่เรียกว่าการเปลี่ยนมุมมอง ซึ่งใช้สร้างภาพเคลื่อนไหวระหว่างการดูหน้าเว็บเพื่อสร้างประสบการณ์การใช้งานที่ราบรื่นสำหรับผู้ใช้ การเปลี่ยนมุมมองช่วยเพิ่มความลื่นไหลในระดับใหม่ให้กับเว็บ ทำให้คุณสร้างการเปลี่ยนผ่านที่ราบรื่นระหว่างมุมมองต่างๆ ภายในหน้าเดียว หรือแม้แต่ในหน้าต่างๆ ได้
Airbnb เป็นหนึ่งในบริษัทที่ทดลองผสานรวมการเปลี่ยนฉากเข้ากับ UI เพื่อประสบการณ์การนำทางบนเว็บที่ราบรื่นและไร้รอยต่อ ซึ่งรวมถึงแถบด้านข้างของเครื่องมือแก้ไขข้อมูลที่แสดง ไปจนถึงการแก้ไขรูปภาพและการเพิ่มสิ่งอำนวยความสะดวก ทั้งหมดนี้อยู่ในขั้นตอนการทำงานของผู้ใช้ที่ราบรื่น
แม้ว่าเอฟเฟกต์เต็มหน้าเหล่านี้จะสวยงามและราบรื่น แต่คุณก็สร้างการโต้ตอบขนาดเล็กได้เช่นกัน ดังตัวอย่างนี้ที่มุมมองรายการได้รับการอัปเดตเมื่อผู้ใช้โต้ตอบ คุณสามารถสร้างเอฟเฟกต์นี้ได้อย่างง่ายดายด้วยการเปลี่ยนมุมมอง
วิธีเปิดใช้การเปลี่ยนมุมมองในแอปพลิเคชันหน้าเดียวอย่างรวดเร็วคือการห่อหุ้มการโต้ตอบโดยใช้ document.startViewTransition และตรวจสอบว่าแต่ละองค์ประกอบที่เปลี่ยนผ่านมี view-transition-name แบบอินไลน์หรือแบบไดนามิกโดยใช้ JavaScript ขณะสร้างโหนด DOM
ภาพสาธิต
การสาธิตแบบสด
document.querySelectorAll('.delete-btn').forEach(btn => {
  btn.addEventListener('click', () => {
    document.startViewTransition(() => {
      btn.closest('.card').remove();
    });
  })
});
/* Styles for the transition animation */
::view-transition-old(.card):only-child {
  animation: fade-out ease-out 0.5s;
}
ดูชั้นเรียนการเปลี่ยนผ่าน
คุณสามารถใช้ชื่อการเปลี่ยนฉากเพื่อใช้ภาพเคลื่อนไหวที่กำหนดเองกับการเปลี่ยนฉากได้ แต่การทำเช่นนี้อาจยุ่งยากหากมีองค์ประกอบจำนวนมากที่เปลี่ยนฉาก การอัปเดตใหม่ครั้งแรกเกี่ยวกับการเปลี่ยนฉากในปีนี้จะช่วยลดความซับซ้อนของปัญหานี้ และเปิดตัวความสามารถในการสร้างคลาสการเปลี่ยนฉากที่ใช้กับภาพเคลื่อนไหวที่กำหนดเองได้
ดูประเภทการเปลี่ยน
การปรับปรุงที่สำคัญอีกอย่างหนึ่งสำหรับการเปลี่ยนฉากคือการรองรับประเภทการเปลี่ยนฉาก ประเภทการเปลี่ยนมุมมองมีประโยชน์เมื่อคุณต้องการการเปลี่ยนมุมมองภาพที่แตกต่างกันเมื่อเปลี่ยนภาพไปยังและจากมุมมองหน้าเว็บ
เช่น คุณอาจต้องการให้หน้าแรกเคลื่อนไหวไปยังหน้าบล็อกในลักษณะที่แตกต่างจากที่หน้าบล็อกเคลื่อนไหวกลับไปยังหน้าแรก หรือคุณอาจต้องการให้หน้าเว็บสลับเข้าและออกในลักษณะต่างๆ เช่น ในตัวอย่างนี้ ซึ่งสลับจากซ้ายไปขวาและขวาไปซ้าย ก่อนหน้านี้การดำเนินการนี้ค่อนข้างซับซ้อน คุณสามารถเพิ่มคลาสลงใน DOM เพื่อใช้สไตล์ แล้วจึงต้องนำคลาสออกในภายหลัง View-transition-types ช่วยให้เบราว์เซอร์ล้างการเปลี่ยนฉากเก่าได้โดยที่คุณไม่ต้องดำเนินการด้วยตนเองก่อนเริ่มการเปลี่ยนฉากใหม่ ซึ่งจะช่วยให้คุณประหยัดเวลาได้
คุณตั้งค่าประเภทภายในdocument.startViewTransition ฟังก์ชันได้ ซึ่งตอนนี้ยอมรับออบเจ็กต์แล้ว update คือฟังก์ชันเรียกกลับที่อัปเดต DOM และ types คืออาร์เรย์ที่มีประเภท 
document.startViewTransition({
  update: myUpdate,
  types: ['slide', 'forwards']
})
การเปลี่ยนมุมมองหลายหน้า
สิ่งที่ทำให้เว็บมีประสิทธิภาพคือความกว้างขวางของเว็บ แอปพลิเคชันจำนวนมากไม่ได้มีเพียงหน้าเดียว แต่เป็นผืนผ้าที่แข็งแกร่งซึ่งประกอบด้วยหลายหน้า ด้วยเหตุนี้ เราจึงตื่นเต้นเป็นอย่างยิ่งที่จะประกาศว่าเราจะเปิดตัวการรองรับการเปลี่ยนฉากมุมมองข้ามเอกสารสำหรับแอปพลิเคชันแบบหลายหน้าใน Chromium 126
ชุดฟีเจอร์ใหม่แบบข้ามเอกสารนี้ประกอบด้วยประสบการณ์การใช้งานเว็บที่อยู่ในต้นทางเดียวกัน เช่น การไปยัง web.dev จาก web.dev/blog แต่จะไม่รวมการไปยังต้นทางอื่น เช่น การไปยัง blog.web.dev จาก web.dev หรือไปยังโดเมนอื่น เช่น google.com
ความแตกต่างที่สำคัญอย่างหนึ่งของการเปลี่ยนฉากมุมมองในเอกสารเดียวกันคือคุณไม่จำเป็นต้องห่อหุ้มการเปลี่ยนฉากด้วย document.startViewTransition() แต่ให้เลือกใช้ทั้ง 2 หน้าที่เกี่ยวข้องในการเปลี่ยนภาพโดยใช้@view-transitionกฎ @ ใน CSS แทน
@view-transition {
  navigation: auto;
}
หากต้องการเอฟเฟกต์ที่กำหนดเองมากขึ้น คุณสามารถเชื่อมต่อ JavaScript โดยใช้เครื่องมือฟังเหตุการณ์ pageswap หรือ pagereveal ใหม่ ซึ่งจะให้สิทธิ์เข้าถึงออบเจ็กต์การเปลี่ยนมุมมอง
pageswap ช่วยให้คุณทำการเปลี่ยนแปลงในนาทีสุดท้ายในหน้าขาออกได้ทันทีก่อนที่จะมีการถ่ายสแนปชอตเก่า และ pagereveal ช่วยให้คุณปรับแต่งหน้าใหม่ได้ก่อนที่จะเริ่มแสดงผลหลังจากที่เริ่มต้นแล้ว
window.addEventListener('pageswap', async (e) => {
    // ...
});
window.addEventListener('pagereveal', async (e) => {
    // ...
});
ในอนาคตเราวางแผนที่จะขยายการเปลี่ยนมุมมอง ซึ่งรวมถึง
- การเปลี่ยนฉากที่กำหนดขอบเขต: ช่วยให้คุณจำกัดการเปลี่ยนฉากไว้ที่ DOM subtree ทำให้ส่วนอื่นๆ ของหน้าเว็บยังคงโต้ตอบได้ และรองรับการเปลี่ยนฉากของมุมมองหลายรายการที่ทำงานพร้อมกัน
- การเปลี่ยนมุมมองที่ขับเคลื่อนด้วยท่าทางสัมผัส: ใช้ท่าทางสัมผัสการลากหรือการปัดเพื่อทริกเกอร์การเปลี่ยนมุมมองข้ามเอกสารเพื่อประสบการณ์การใช้งานบนเว็บที่ดูเป็นเนทีฟมากขึ้น
- การจับคู่การนำทางใน CSS: ปรับแต่งการเปลี่ยนมุมมองเอกสารโดยตรงใน CSS เพื่อเป็นทางเลือกแทนการใช้เหตุการณ์ pageswapและpagerevealใน JavaScript ดูข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนมุมมองสำหรับแอปพลิเคชันแบบหลายหน้า รวมถึงวิธีตั้งค่าอย่างมีประสิทธิภาพสูงสุดด้วยการแสดงผลล่วงหน้าได้ที่การพูดคุยต่อไปนี้โดย Bramus Van Damme
คอมโพเนนต์ UI ที่เปิดใช้เครื่องมือ: ลดความซับซ้อนของการโต้ตอบที่ซับซ้อน
การสร้างเว็บแอปพลิเคชันที่ซับซ้อนไม่ใช่เรื่องง่าย แต่ CSS และ HTML กำลังพัฒนาเพื่อให้กระบวนการนี้จัดการได้ง่ายขึ้นมาก ฟีเจอร์และการปรับปรุงใหม่ๆ จะช่วยลดความซับซ้อนในการสร้างคอมโพเนนต์ UI เพื่อให้คุณมุ่งเน้นที่การสร้างประสบการณ์ที่ยอดเยี่ยมได้ โดยเราได้ร่วมมือกับองค์กรมาตรฐานและกลุ่มชุมชนที่สำคัญหลายแห่ง ซึ่งรวมถึง CSS Working Group, Open UI Community Group และ WHATWG (Web Hypertext Application Technology Working Group)
ปัญหาใหญ่ที่นักพัฒนาซอฟต์แวร์พบคือคำขอที่ดูเหมือนจะง่ายๆ นั่นคือความสามารถในการจัดรูปแบบเมนูแบบเลื่อนลง (องค์ประกอบ select) แม้ว่าในเบื้องต้นจะดูเหมือนเป็นเรื่องง่าย แต่จริงๆ แล้วปัญหานี้มีความซับซ้อนมากและเกี่ยวข้องกับหลายส่วนของแพลตฟอร์ม ตั้งแต่เลย์เอาต์และการแสดงผล ไปจนถึงการเลื่อนและการโต้ตอบ ไปจนถึงการจัดรูปแบบ User Agent และพร็อพเพอร์ตี้ CSS รวมถึงการเปลี่ยนแปลงใน HTML เองด้วย
 
  ดรอปดาวน์ประกอบด้วยหลายส่วนและมีหลายสถานะที่ต้องพิจารณา เช่น
- การเชื่อมโยงแป้นพิมพ์ (เพื่อเข้า/ออกจากการโต้ตอบ)
- คลิกเพื่อปิด
- การจัดการป๊อปโอเวอร์ที่ใช้งานอยู่ (ปิดป๊อปโอเวอร์อื่นๆ เมื่อเปิดป๊อปโอเวอร์หนึ่ง)
- การจัดการโฟกัสแท็บ
- การแสดงค่าตัวเลือกที่เลือก
- รูปแบบการโต้ตอบด้วยลูกศร
- การจัดการสถานะ (เปิด/ปิด)
ปัจจุบันการจัดการสถานะทั้งหมดนี้ด้วยตนเองเป็นเรื่องยาก แต่แพลตฟอร์มก็ไม่ได้ช่วยให้ง่ายขึ้นเช่นกัน เราจึงแยกชิ้นส่วนเหล่านั้นออกและกำลังจะเปิดตัวฟีเจอร์พื้นฐาน 2-3 รายการที่จะช่วยให้จัดรูปแบบเมนูแบบเลื่อนลงได้ รวมถึงทำสิ่งอื่นๆ ได้อีกมากมาย
Popover API
ก่อนอื่น เราได้เปิดตัวแอตทริบิวต์ส่วนกลางที่ชื่อ popover ซึ่งฉันรู้สึกตื่นเต้นที่จะประกาศว่าแอตทริบิวต์นี้เพิ่งได้รับสถานะ "พื้นฐาน" ที่พร้อมใช้งานเมื่อไม่กี่สัปดาห์ที่ผ่านมา
องค์ประกอบป๊อปโอเวอร์จะซ่อนด้วย display: none จนกว่าจะเปิดด้วยตัวเรียกใช้ เช่น ปุ่ม หรือด้วย JavaScript หากต้องการสร้างป๊อปโอเวอร์พื้นฐาน ให้ตั้งค่าแอตทริบิวต์ป๊อปโอเวอร์ในองค์ประกอบ และลิงก์รหัสของป๊อปโอเวอร์กับปุ่มโดยใช้ popovertarget ตอนนี้ปุ่มนี้เป็นตัวเรียกใช้
ภาพสาธิต
การสาธิตแบบสด
<button popovertarget="my-popover">Open Popover</button>
<div id="my-popover" popover>
  <p>I am a popover with more information.</p>
</div>
เมื่อเปิดใช้แอตทริบิวต์ป๊อปโอเวอร์แล้ว เบราว์เซอร์จะจัดการลักษณะการทำงานที่สำคัญหลายอย่างโดยไม่ต้องใช้สคริปต์เพิ่มเติม ซึ่งรวมถึง
- การเลื่อนชั้น เลเยอร์แยกต่างหากเหนือส่วนอื่นๆ ของหน้าเว็บ คุณจึงไม่ต้องยุ่งกับ z-index
- ฟังก์ชันการปิดอย่างรวดเร็ว: การคลิกนอกพื้นที่ป๊อปโอเวอร์จะปิดป๊อปโอเวอร์และกลับไปโฟกัส
- การจัดการโฟกัสแท็บเริ่มต้น: การเปิดป๊อปโอเวอร์จะทำให้แท็บถัดไปหยุดอยู่ภายในป๊อปโอเวอร์
- แป้นพิมพ์ลัดในตัว: การกดปุ่ม escหรือการสลับสองครั้งจะปิดป๊อปโอเวอร์และคืนค่าโฟกัส
- การเชื่อมโยงคอมโพเนนต์เริ่มต้น : เบราว์เซอร์เชื่อมต่อป๊อปโอเวอร์กับทริกเกอร์ในเชิงความหมาย
 
  คุณอาจกำลังใช้ Popover API นี้อยู่โดยไม่รู้ตัว GitHub ใช้ป๊อปโอเวอร์ในเมนู "ใหม่" ของหน้าแรกและในภาพรวมการตรวจสอบคำขอ Pull โดยได้ปรับปรุงฟีเจอร์นี้อย่างต่อเนื่องโดยใช้ popover polyfill ซึ่งสร้างโดย Oddbird โดยได้รับการสนับสนุนอย่างมากจาก Keith Cirkel ของ GitHub เอง เพื่อรองรับเบราว์เซอร์รุ่นเก่า
"เราเลิกใช้งานโค้ดได้หลายพันบรรทัดด้วยการย้ายข้อมูลไปยังป๊อปโอเวอร์ Popover ช่วยเราได้โดยไม่ต้องต่อสู้กับตัวเลข z-index ที่ซับซ้อน... การสร้างความสัมพันธ์ที่ถูกต้องของโครงสร้างการช่วยเหลือพิเศษด้วยลักษณะการทำงานของปุ่มแบบประกาศ และลักษณะการทำงานของโฟกัสที่สร้างไว้ในตัวช่วยให้ Design System ของเรานำรูปแบบไปใช้ได้อย่างถูกต้องง่ายขึ้นมาก - Keith Cirkel วิศวกรซอฟต์แวร์ GitHub"
การสร้างภาพเคลื่อนไหวของเอฟเฟกต์การเข้าและออก
เมื่อมีป๊อปโอเวอร์ คุณอาจต้องการเพิ่มการโต้ตอบ เราได้เปิดตัวฟีเจอร์การโต้ตอบใหม่ 4 รายการในช่วงปีที่ผ่านมาเพื่อรองรับการเคลื่อนไหวของป๊อปโอเวอร์ ซึ่งได้แก่
ความสามารถในการทำให้ display และ content-visibility เคลื่อนไหวบนไทม์ไลน์คีย์เฟรม
พร็อพเพอร์ตี้ transition-behavior ที่มีคีย์เวิร์ด allow-discrete เพื่อเปิดใช้การเปลี่ยนพร็อพเพอร์ตี้ที่ไม่ต่อเนื่อง เช่น display
@starting-style กฎในการสร้างภาพเคลื่อนไหวของเอฟเฟกต์การเข้าจาก display: none ไปยัง top-layer
พร็อพเพอร์ตี้การซ้อนทับเพื่อควบคุมลักษณะการทำงานของเลเยอร์บนสุดระหว่างภาพเคลื่อนไหว
พร็อพเพอร์ตี้เหล่านี้ใช้ได้กับองค์ประกอบใดก็ตามที่คุณกําลังเคลื่อนไหวไปยังเลเยอร์บนสุด ไม่ว่าจะเป็นป๊อปโอเวอร์หรือกล่องโต้ตอบ เมื่อรวมกันแล้ว ลักษณะของกล่องโต้ตอบที่มีฉากหลังจะเป็นดังนี้
ภาพสาธิต
การสาธิตแบบสด
dialog, ::backdrop{
  opacity: 0;
  transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}
[open], [open]::backdrop {
  opacity: 1;
}
@starting-style {
  [open], [open]::backdrop {
    opacity: 0;
  }
}
ก่อนอื่น ให้ตั้งค่า @starting-style เพื่อให้เบราว์เซอร์ทราบว่าควรใช้สไตล์ใดในการเคลื่อนไหวองค์ประกอบนี้ใน DOM ซึ่งทำได้ทั้งกับกล่องโต้ตอบและฉากหลัง จากนั้นจัดรูปแบบสถานะเปิดสำหรับทั้งกล่องโต้ตอบและฉากหลัง สำหรับกล่องโต้ตอบ จะใช้แอตทริบิวต์ open และสำหรับป๊อปโอเวอร์ จะใช้องค์ประกอบเสมือน ::popover-open สุดท้าย ให้สร้างภาพเคลื่อนไหวของ opacity, display และ overlay โดยใช้คีย์เวิร์ด allow-discrete เพื่อเปิดใช้โหมดภาพเคลื่อนไหวที่พร็อพเพอร์ตี้แบบแยกสามารถเปลี่ยนผ่านได้
การวางตำแหน่งโฆษณา Anchor
ป๊อปโอเวอร์เป็นเพียงจุดเริ่มต้นของเรื่องราว การอัปเดตที่น่าตื่นเต้นอย่างยิ่งคือตอนนี้ Chrome 125 รองรับการวางตำแหน่งจุดยึดแล้ว
การใช้การวางตำแหน่งยึดช่วยให้เบราว์เซอร์จัดการตรรกะในการเชื่อมโยงองค์ประกอบที่วางตำแหน่งกับองค์ประกอบยึดอย่างน้อย 1 รายการได้ด้วยโค้ดเพียงไม่กี่บรรทัด ในตัวอย่างต่อไปนี้ มีการยึดเคล็ดลับเครื่องมือแบบง่ายไว้กับแต่ละปุ่ม โดยวางไว้ที่กึ่งกลางด้านล่าง
ภาพสาธิต
การสาธิตแบบสด
ตั้งค่าความสัมพันธ์ที่ยึดตำแหน่งใน CSS โดยใช้พร็อพเพอร์ตี้ anchor-name ในองค์ประกอบการยึด (ในกรณีนี้คือปุ่ม) และพร็อพเพอร์ตี้ position-anchor ในองค์ประกอบที่ยึดตำแหน่ง (ในกรณีนี้คือเคล็ดลับเครื่องมือ) จากนั้นใช้การวางตำแหน่งแบบสมบูรณ์หรือแบบคงที่เทียบกับจุดยึดโดยใช้ฟังก์ชัน anchor() โค้ดต่อไปนี้จะวางตำแหน่งด้านบนของเคล็ดลับเครื่องมือไว้ที่ด้านล่างของปุ่ม
.anchor {
  anchor-name: --my-anchor;
}
.positioned {
  position: absolute;
  position-anchor: --my-anchor;
}
หรือจะใช้แอตทริบิวต์ anchor-name โดยตรงในฟังก์ชัน Anchor และข้ามพร็อพเพอร์ตี้ position-anchor ก็ได้ ซึ่งจะเป็นประโยชน์เมื่อยึดกับหลายองค์ประกอบ
.anchor {
  anchor-name: --my-anchor;
}
.positioned {
  position: absolute;
  top: anchor(--my-anchor bottom);
}
สุดท้าย ให้ใช้anchor-centerคีย์เวิร์ดใหม่สำหรับพร็อพเพอร์ตี้ justify และ align เพื่อจัดองค์ประกอบที่วางตำแหน่งไว้ให้อยู่ตรงกลางของ Anchor
.anchor {
  anchor-name: --my-anchor;
}
.positioned {
  position: absolute;
  top: anchor(--my-anchor bottom);
  justify-self: anchor-center;
}
แม้ว่าการใช้การวางตำแหน่งจุดยึดกับป๊อปโอเวอร์จะสะดวกมาก แต่ป๊อปโอเวอร์ก็ไม่ใช่ข้อกำหนดสำหรับการใช้การวางตำแหน่งจุดยึด การวางตำแหน่งจุดยึดสามารถใช้กับองค์ประกอบ 2 รายการขึ้นไปเพื่อสร้างความสัมพันธ์เชิงภาพ ที่จริงแล้ว การสาธิตต่อไปนี้ซึ่งได้รับแรงบันดาลใจจากบทความของ Roman Komarov แสดงให้เห็นว่ารูปแบบขีดเส้นใต้จะเชื่อมโยงกับรายการเมื่อคุณวางเมาส์หรือกด Tab เหนือรายการเหล่านั้น
ภาพสาธิต
การสาธิตแบบสด
ตัวอย่างนี้ใช้ฟังก์ชัน Anchor เพื่อตั้งค่าตำแหน่ง Anchor โดยใช้พร็อพเพอร์ตี้ทางกายภาพของ left, right และ bottom เมื่อวางเมาส์เหนือลิงก์ใดลิงก์หนึ่ง สมอเป้าหมายจะเปลี่ยนไป และเบราว์เซอร์จะเปลี่ยนเป้าหมายเพื่อใช้การวางตำแหน่ง พร้อมกับเปลี่ยนสีในเวลาเดียวกันเพื่อสร้างเอฟเฟกต์ที่ดูดี
ul::before {
  content: "";
  position: absolute;
  left:   anchor(var(--target) left);
  right:  anchor(var(--target) right);
  bottom: anchor(var(--target) bottom);
  ...
}
li:nth-child(1) { --anchor: --item-1 }
ul:has(:nth-child(1) a:is(:hover, :focus-visible)) {
  --target: --item-1;
  --color: red;
}
การวางตำแหน่ง inset-area
นอกจากตําแหน่งสัมบูรณ์แบบมีทิศทางเริ่มต้นที่คุณอาจเคยใช้มาก่อนแล้ว ยังมีกลไกเลย์เอาต์ใหม่ที่รวมอยู่ด้วยซึ่งเป็นส่วนหนึ่งของ Anchor Positioning API ที่เรียกว่า Inset Area พื้นที่ขอบในช่วยให้วางองค์ประกอบที่กำหนดตำแหน่งให้สัมพันธ์กับจุดยึดที่เกี่ยวข้องได้ง่าย และทำงานบนตารางกริด 9 เซลล์โดยมีองค์ประกอบการยึดอยู่ตรงกลาง เช่น inset-area: top จะวางองค์ประกอบที่กำหนดตำแหน่งไว้ที่ด้านบน และ inset-area: bottom จะวางองค์ประกอบที่กำหนดตำแหน่งไว้ที่ด้านล่าง
เวอร์ชันที่เรียบง่ายของเดโม Anchor แรกจะมีลักษณะดังนี้พร้อมด้วย inset-area
.anchor {
  anchor-name: --my-anchor;
}
.positioned {
  position: absolute;
  position-anchor: --my-anchor;
  inset-area: bottom;
}
คุณสามารถรวมค่าตำแหน่งเหล่านี้กับคีย์เวิร์ดช่วงเพื่อเริ่มต้นที่ตำแหน่งกึ่งกลางและขยายไปทางซ้าย ขยายไปทางขวา หรือขยายทั้งหมดเพื่อใช้ชุดคอลัมน์หรือแถวทั้งหมดที่มี นอกจากนี้ คุณยังใช้พร็อพเพอร์ตี้เชิงตรรกะได้ด้วย หากต้องการให้เห็นภาพและทำความเข้าใจกลไกเลย์เอาต์นี้ได้ง่ายขึ้น โปรดดูเครื่องมือนี้ใน Chrome 125 ขึ้นไป
เนื่องจากองค์ประกอบเหล่านี้ยึดไว้ องค์ประกอบที่วางตำแหน่งจึงเคลื่อนที่ไปรอบๆ หน้าเว็บแบบไดนามิกเมื่อจุดยึดเคลื่อนที่ ในกรณีนี้ เราจึงมีองค์ประกอบการ์ดที่จัดรูปแบบด้วย Container Query ซึ่งปรับขนาดตามขนาดโดยธรรมชาติ (ซึ่งคุณทำไม่ได้ด้วย Media Query) และเมนูที่ยึดไว้จะเปลี่ยนไปตามเลย์เอาต์ใหม่เมื่อ UI ของการ์ดเปลี่ยนแปลง
ภาพสาธิต
การสาธิตแบบสด
ตำแหน่งโฆษณา Anchor แบบไดนามิกที่มี position-try-options
การสร้างเมนูและการนำทางในเมนูย่อยจะง่ายขึ้นมากเมื่อใช้ร่วมกับป๊อปโอเวอร์และการวางตำแหน่ง Anchor และเมื่อไปถึงขอบของวิวพอร์ตด้วยองค์ประกอบที่ยึดไว้ คุณก็สามารถให้เบราว์เซอร์จัดการการเปลี่ยนตำแหน่งให้คุณได้เช่นกัน
ซึ่งทำได้หลายวิธี วิธีแรกคือการสร้างกฎการวางตำแหน่งของคุณเอง ในกรณีนี้ ระบบจะวางตำแหน่งเมนูย่อยไว้ทางด้านขวาของปุ่ม "หน้าร้าน" ในตอนแรก แต่คุณสามารถสร้าง@position-tryบล็อกสำหรับกรณีที่มีพื้นที่ไม่เพียงพอทางด้านขวาของเมนู โดยกำหนดตัวระบุที่กำหนดเองเป็น --bottom จากนั้นเชื่อมต่อบล็อก @position-try นี้กับ Anchor โดยใช้ position-try-options
ตอนนี้เบราว์เซอร์จะสลับไปมาระหว่างสถานะที่ตรึงไว้เหล่านี้ โดยจะลองใช้ตำแหน่งที่เหมาะสมก่อน แล้วจึงเลื่อนไปที่ด้านล่าง และทำได้โดยใช้การเปลี่ยนฉากที่สวยงาม
ภาพสาธิต
การสาธิตแบบสด
#submenu {
  position-anchor: --submenu;
  top: anchor(top);
  left: anchor(right);
  margin-left: var(--padding);
  position-try-options: --bottom;
  transition: top 0.25s, left 0.25s;
  width: max-content;
}
@position-try --bottom {
  top: anchor(left);
  left: anchor(bottom);
  margin-left: var(--padding);
}
นอกเหนือจากตรรกะการวางตำแหน่งที่ชัดเจนแล้ว ยังมีคีย์เวิร์ดบางคำที่เบราว์เซอร์มีให้หากคุณต้องการการโต้ตอบพื้นฐาน เช่น การพลิกจุดยึดในเส้นทางแบบบล็อกหรือแบบอินไลน์
position-try-options: flip-block, flip-inline;
หากต้องการประสบการณ์การพลิกที่ง่ายดาย ให้ใช้ประโยชน์จากค่าคีย์เวิร์ดพลิกเหล่านี้และข้ามการเขียนคำจำกัดความของ position-try ไปเลย ตอนนี้คุณจึงมีองค์ประกอบยึดที่ตอบสนองต่อตำแหน่งและทำงานได้อย่างสมบูรณ์ด้วย CSS เพียงไม่กี่บรรทัด
ภาพสาธิต
การสาธิตแบบสด
.tooltip {
  inset-area: top;
  position-try-options: flip-block;
}
ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้การวางตำแหน่ง Anchor
อนาคตของ UI แบบเลเยอร์
เราเห็นประสบการณ์การใช้งานที่เชื่อมต่อกันได้ทุกที่ และชุดฟีเจอร์ที่แสดงในโพสต์นี้เป็นจุดเริ่มต้นที่ยอดเยี่ยมในการปลดปล่อยความคิดสร้างสรรค์และควบคุมองค์ประกอบที่วางตำแหน่ง Anchor และอินเทอร์เฟซแบบเลเยอร์ได้ดียิ่งขึ้น แต่นี่เป็นเพียงจุดเริ่มต้น เช่น ปัจจุบัน popover ใช้ได้กับปุ่มเป็นองค์ประกอบการเรียกใช้ หรือใช้กับ JavaScript เท่านั้น สำหรับตัวอย่างเช่น การแสดงตัวอย่างสไตล์ Wikipedia ซึ่งเป็นรูปแบบที่เห็นได้ทั่วทั้งแพลตฟอร์มเว็บ ผู้ใช้ต้องโต้ตอบได้ และยังต้องทริกเกอร์ป๊อปโอเวอร์จากลิงก์และจากผู้ใช้ที่แสดงความสนใจได้โดยไม่ต้องคลิกผ่าน เช่น การวางเมาส์เหนือหรือการโฟกัสแท็บ
ในขั้นตอนถัดไปสำหรับ Popover API เรากำลังดำเนินการเกี่ยวกับ interesttarget เพื่อตอบสนองความต้องการเหล่านี้และช่วยให้สร้างประสบการณ์เหล่านี้ได้ง่ายขึ้นด้วยการผสานรวมการเชื่อมต่อการช่วยเหลือพิเศษที่เหมาะสม นี่เป็นปัญหาด้านการช่วยเหลือพิเศษที่แก้ไขได้ยาก และยังมีคำถามที่ยังไม่มีคำตอบมากมายเกี่ยวกับลักษณะการทำงานที่เหมาะสม แต่การแก้ไขและปรับฟังก์ชันนี้ให้เป็นมาตรฐานในระดับแพลตฟอร์มจะช่วยปรับปรุงประสบการณ์การใช้งานสำหรับทุกคน
<a interesttarget="my-tooltip">Hover/Focus to show the tooltip</a>
<span popover=hint id="my-toolip">This is the tooltip</span>
นอกจากนี้ ยังมีฟังก์ชันเรียกใช้ทั่วไปอีกรายการที่มุ่งเน้นอนาคต (invoketarget) ซึ่งพร้อมให้ทดสอบใน Canary ด้วยผลงานของนักพัฒนาแอปบุคคลที่สาม 2 ราย ได้แก่ Keith Cirkel และ Luke Warlow invoketarget รองรับประสบการณ์การใช้งานของนักพัฒนาแอปแบบประกาศที่ popovertarget มีป๊อปอัปที่ปรับให้เป็นมาตรฐานสำหรับองค์ประกอบแบบอินเทอร์แอกทีฟทั้งหมด ซึ่งรวมถึง <dialog>, <details>, <video>, <input type="file"> และอื่นๆ
<button invoketarget="my-dialog">
  Open Dialog
</button>
<dialog id="my-dialog">
  Hello world!
</dialog>
เราทราบว่ายังมี Use Case ที่ API นี้ยังไม่ครอบคลุม เช่น การจัดรูปแบบลูกศรที่เชื่อมต่อองค์ประกอบที่ยึดกับจุดยึด โดยเฉพาะอย่างยิ่งเมื่อตำแหน่งขององค์ประกอบที่ยึดเปลี่ยนไป และการเปิดใช้ให้องค์ประกอบ "เลื่อน" และอยู่ในวิวพอร์ตแทนที่จะสแนปไปยังตำแหน่งอื่นที่ตั้งไว้เมื่อถึงกล่องขอบเขต ดังนั้นแม้ว่าเราจะตื่นเต้นกับการเปิดตัว API ที่ทรงพลังนี้ แต่เราก็หวังว่าจะได้ขยายความสามารถของ API นี้ให้มากยิ่งขึ้นในอนาคต
เลือกที่ปรับแต่งสไตล์ได้
การใช้ popover และ anchor ร่วมกันทำให้ทีมมีความคืบหน้าในการเปิดใช้เมนูแบบเลื่อนลงที่เลือกได้และปรับแต่งได้ในที่สุด ข่าวดีคือเรามีความคืบหน้าไปมาก ข่าวร้ายก็คือ API นี้ยังอยู่ในสถานะทดลองในขณะนี้ อย่างไรก็ตาม เราตื่นเต้นที่จะได้แชร์การสาธิตแบบสดและข้อมูลอัปเดตเกี่ยวกับความคืบหน้าของเรา และหวังว่าจะได้รับความคิดเห็นจากคุณ
ประการแรก เราได้พัฒนาวิธีเลือกให้ผู้ใช้ได้สัมผัสประสบการณ์แบบใหม่ที่ปรับแต่งได้ วิธีปัจจุบันที่อยู่ระหว่างการดำเนินการคือการใช้พร็อพเพอร์ตี้ลักษณะที่ปรากฏใน CSS ซึ่งตั้งค่าเป็น appearance: base-select เมื่อตั้งค่าลักษณะที่ปรากฏแล้ว คุณจะเลือกใช้ประสบการณ์การเลือกแบบใหม่ที่ปรับแต่งได้
select {
  appearance: base-select;
}
นอกจาก appearance: base-select แล้ว ยังมีการอัปเดต HTML ใหม่ๆ อีกด้วย ซึ่งรวมถึงความสามารถในการใส่ตัวเลือกใน datalist เพื่อการปรับแต่ง และความสามารถในการเพิ่มเนื้อหาแบบไม่โต้ตอบที่กำหนดเอง เช่น รูปภาพในตัวเลือก นอกจากนี้ คุณยังจะมีสิทธิ์เข้าถึงองค์ประกอบใหม่ <selectedoption> ซึ่งจะแสดงเนื้อหาของตัวเลือกในตัวของมันเอง จากนั้นคุณจะปรับแต่งให้ตรงกับความต้องการของคุณได้ องค์ประกอบนี้มีประโยชน์มาก
ภาพสาธิต
 
      การสาธิตแบบสด
<select>
  <button type=popover>
    <selectedoption></selectedoption>
  </button>
  <datalist>
    <option value="" hidden>
      <p>Select a country</p>
    </option>
    <option value="andorra">
      <img src="Flag_of_Andorra.svg" />
      <p>Andorra</p>
    </option>
    <option value="bolivia">
      <img src="Flag_of_Bolivia.svg" />
      <p>Bolivia</p>
    </option>
...
  </datalist>
</select>
โค้ดต่อไปนี้แสดงการปรับแต่ง <selectedoption> ใน UI ของ Gmail ซึ่งไอคอนภาพจะแสดงประเภทการตอบกลับที่เลือกเพื่อประหยัดพื้นที่ คุณใช้สไตล์การแสดงผลพื้นฐานภายใน selectedoption เพื่อแยกความแตกต่างของสไตล์ตัวเลือกจากสไตล์ตัวอย่างได้ ในกรณีนี้ ข้อความที่แสดงในตัวเลือกจะซ่อนไว้ใน selectedoption
ภาพสาธิต
 
      การสาธิตแบบสด
selectedoption .text {
  display: none;
}
ข้อดีที่สำคัญที่สุดอย่างหนึ่งในการนำองค์ประกอบ <select> มาใช้ซ้ำสำหรับ API นี้คือความเข้ากันได้แบบย้อนหลัง ในตัวเลือกประเทศนี้ คุณจะเห็น UI ที่ปรับแต่งพร้อมรูปภาพธงในตัวเลือกต่างๆ เพื่อให้ผู้ใช้แยกวิเคราะห์เนื้อหาได้ง่ายขึ้น เนื่องจากเบราว์เซอร์ที่ไม่รองรับจะละเว้นบรรทัดที่ไม่เข้าใจ เช่น ปุ่มที่กำหนดเอง, datalist, selectedoption และรูปภาพภายในตัวเลือก การสำรองจึงจะคล้ายกับ UI ของการเลือกเริ่มต้นปัจจุบัน
 
  การเลือกที่ปรับแต่งได้ทำให้ทุกอย่างเป็นไปได้ ฉันชอบตัวเลือกประเทศสไตล์ Airbnb นี้เป็นพิเศษเพราะมีการออกแบบที่ชาญฉลาดสำหรับการออกแบบที่ตอบสนองตามอุปกรณ์ คุณสามารถทำสิ่งนี้และอื่นๆ อีกมากมายได้ด้วยองค์ประกอบการเลือกที่จัดรูปแบบได้ซึ่งกำลังจะเปิดตัว ทำให้เป็นส่วนเสริมที่จำเป็นอย่างยิ่งสำหรับแพลตฟอร์มเว็บ
ภาพสาธิต
การสาธิตแบบสด
แอคคอร์เดียนพิเศษ
การแก้ปัญหาการจัดรูปแบบบางอย่าง (และทุกส่วนที่เกี่ยวข้อง) ไม่ใช่คอมโพเนนต์ UI เพียงอย่างเดียวที่ทีม Chrome มุ่งเน้น การอัปเดตคอมโพเนนต์เพิ่มเติมครั้งแรกคือความสามารถในการสร้าง Accordion แบบพิเศษ ซึ่งจะเปิดได้ครั้งละ 1 รายการเท่านั้น
Browser Support
วิธีเปิดใช้คือการใช้ค่าชื่อเดียวกันกับองค์ประกอบรายละเอียดหลายรายการ ซึ่งจะสร้างกลุ่มรายละเอียดที่เชื่อมต่อกันคล้ายกับกลุ่มปุ่มตัวเลือก
<details name="learn-css" open>
  <summary>Welcome to Learn CSS!</summary>
</details>
<details name="learn-css">
  <summary>Box Model</summary>
  <p>...</p>
</details>
<details name="learn-css">
  <summary>Selectors</summary>
  <p>...</p>
</details>
:user-valid และ :user-invalid
การปรับปรุงคอมโพเนนต์ UI อีกอย่างคือคลาสเสมือน :user-valid และ :user-invalid คลาสเสมือน :user-valid และ :user-invalid ซึ่งเสถียรในเบราว์เซอร์ทั้งหมดเมื่อเร็วๆ นี้ทํางานคล้ายกับคลาสเสมือน :valid และ :invalid แต่จะจับคู่ตัวควบคุมแบบฟอร์มหลังจากที่ผู้ใช้โต้ตอบกับอินพุตอย่างมีนัยสําคัญแล้วเท่านั้น ซึ่งหมายความว่าต้องใช้โค้ดน้อยลงอย่างมากในการพิจารณาว่ามีการโต้ตอบกับค่าของแบบฟอร์มหรือไม่ หรือค่าดังกล่าว "ไม่ถูกต้อง" ซึ่งอาจมีประโยชน์อย่างยิ่งในการให้ความคิดเห็นของผู้ใช้ และลดการเขียนสคริปต์จำนวนมากที่จำเป็นต่อการดำเนินการนี้ในอดีต
Screencast การสาธิต
การสาธิตการใช้งานแบบสด
input:user-valid,
select:user-valid,
textarea:user-valid {
    --state-color: green;
    --bg: linear-gradient(...);
}
input:user-invalid,
select:user-invalid,
textarea:user-invalid {
    --state-color: red;
    --bg: linear-gradient(...);
}
ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้องค์ประกอบเสมือนของรูปแบบการตรวจสอบผู้ใช้-*
field-sizing: content
การอัปเดตคอมโพเนนต์ที่มีประโยชน์อีกอย่างที่เพิ่งเปิดตัวไปเมื่อไม่นานมานี้คือ field-sizing: content ซึ่งใช้กับตัวควบคุมแบบฟอร์ม เช่น อินพุตและพื้นที่ข้อความได้ ซึ่งจะช่วยให้ขนาดของอินพุตเพิ่มขึ้น (หรือลดลง) ได้ตามเนื้อหา field-sizing: content มีประโยชน์อย่างยิ่งสำหรับพื้นที่ข้อความ เนื่องจากคุณไม่ต้องใช้ขนาดคงที่อีกต่อไป ซึ่งอาจต้องเลื่อนขึ้นเพื่อดูสิ่งที่คุณเขียนในส่วนก่อนหน้าของพรอมต์ในช่องป้อนข้อมูลที่เล็กเกินไป
Screencast การสาธิต
การสาธิตการใช้งานแบบสด
textarea, select, input {
  field-sizing: content;
}
ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดขนาดฟิลด์
<hr> ใน <select>
ความสามารถในการเปิดใช้ <hr> หรือองค์ประกอบเส้นแนวนอนในตัวเลือกเป็นอีกหนึ่งฟีเจอร์คอมโพเนนต์เล็กๆ แต่มีประโยชน์ แม้ว่าการดำเนินการนี้จะไม่มีประโยชน์ทางความหมายมากนัก แต่ก็ช่วยให้คุณแยกเนื้อหาภายในรายการที่เลือกได้อย่างดี โดยเฉพาะเนื้อหาที่คุณอาจไม่ต้องการจัดกลุ่มด้วย optgroup เช่น ค่าตัวยึดตำแหน่ง
เลือกภาพหน้าจอ
 
      เลือกการสาธิตการใช้งานแบบสด
<select name="majors" id="major-select">
  <option value="">Select a major</option>
  <hr>
  <optgroup label="School of Fine Arts">
    <option value="arthist">
Art History
  </option>
  <option value="finearts">
    Fine Arts
  </option>
...
</select>
ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ hr ใน select
การปรับปรุงคุณภาพชีวิต
เรากำลังปรับปรุงอย่างต่อเนื่อง และไม่ได้มุ่งเน้นเฉพาะการโต้ตอบและคอมโพเนนต์เท่านั้น นอกจากนี้ เรายังได้อัปเดตคุณภาพชีวิตอื่นๆ อีกมากมายในช่วงปีที่ผ่านมา
การซ้อนที่มีการมองไปข้างหน้า
การซ้อน CSS แบบเนทีฟเปิดตัวในเบราว์เซอร์ทั้งหมดเมื่อปีที่แล้ว และได้รับการปรับปรุงให้รองรับการมองไปข้างหน้า ซึ่งหมายความว่าคุณไม่จำเป็นต้องใช้ & ก่อนชื่อองค์ประกอบอีกต่อไป ซึ่งทำให้การซ้อนกันดูเป็นสัดส่วนมากขึ้นและคล้ายกับที่ฉันเคยใช้ในอดีต
สิ่งที่ฉันชอบอย่างหนึ่งเกี่ยวกับการซ้อน CSS คือการที่ช่วยให้คุณบล็อกคอมโพเนนต์ด้วยภาพ และรวมสถานะและตัวแก้ไขไว้ในคอมโพเนนต์เหล่านั้น เช่น การค้นหาคอนเทนเนอร์และการค้นหาสื่อ ก่อนหน้านี้ ฉันเคยจัดกลุ่มการค้นหาทั้งหมดเหล่านี้ไว้ที่ด้านล่างของไฟล์เพื่อความเฉพาะเจาะจง ตอนนี้คุณเขียนได้ในลักษณะที่สมเหตุสมผลข้างๆ โค้ดที่เหลือ
.card {
  /* card base styles */
  h2 {
    /* child element style */
  }
  &.highlight {
    /* modifier style */
  }
  &:hover, &:focus {
    /* state styles */
  }
  @container (width >= 300px) {
    /* container query styles */
  }
}
Align-content สำหรับเลย์เอาต์บล็อก
การเปลี่ยนแปลงที่ยอดเยี่ยมอีกอย่างคือความสามารถในการใช้กลไกการจัดกึ่งกลาง เช่น align-content ในเลย์เอาต์บล็อก ซึ่งหมายความว่าตอนนี้คุณสามารถทำสิ่งต่างๆ เช่น การจัดกึ่งกลางแนวตั้งภายใน div ได้โดยไม่ต้องใช้เลย์เอาต์ Flex หรือ Grid และไม่มีผลข้างเคียง เช่น การป้องกันการยุบขอบ ซึ่งคุณอาจไม่ต้องการจากอัลกอริทึมเลย์เอาต์เหล่านั้น
Browser Support
ภาพหน้าจอ
 
      การสาธิตการใช้งานแบบสด
div {
  align-content: center;
}
การตัดข้อความ: สมดุลและสวยงาม
พูดถึงเลย์เอาต์แล้ว เลย์เอาต์ข้อความได้รับการปรับปรุงอย่างดีด้วยการเพิ่ม text-wrap: balance และ pretty text-wrap: balance ใช้สำหรับบล็อกข้อความที่สม่ำเสมอมากขึ้น ส่วน text-wrap: pretty เน้นการลดคำที่อยู่บรรทัดสุดท้ายในข้อความ
Screencast การสาธิต
การสาธิตการใช้งานแบบสด
balance และ pretty ในส่วนหัวและย่อหน้าได้โดยการลากแถบเลื่อน ลองแปลการสาธิตเป็นภาษาอื่นดูh1 {
  text-wrap: balance;
}
ดูข้อมูลเพิ่มเติมเกี่ยวกับ text-wrap: balance
การอัปเดตการจัดรูปแบบตัวอักษรระหว่างประเทศ
การอัปเดตเลย์เอาต์การจัดตัวอักษรสำหรับฟีเจอร์ข้อความ CJK ได้รับการอัปเดตที่ยอดเยี่ยมมากมายในช่วงปีที่ผ่านมา เช่น ฟีเจอร์ word-break: auto-phrase ที่ตัดบรรทัดที่ขอบเขตวลีที่เป็นธรรมชาติ
Browser Support
 
  word-break: normal กับ word-break: auto-phraseและ text-spacing-trim ซึ่งใช้การจัดระยะตัวอักษรระหว่างเครื่องหมายวรรคตอนเพื่อปรับปรุงความสามารถในการอ่านของตัวอักษรจีน ญี่ปุ่น และเกาหลีเพื่อให้ได้ผลลัพธ์ที่ดูดีขึ้น
 
  ไวยากรณ์สีสัมพัทธ์
ในโลกของการกำหนดธีมสี เราได้เห็นการอัปเดตครั้งใหญ่ด้วยไวยากรณ์สีสัมพัทธ์
ในตัวอย่างนี้ สีที่นี่ใช้การกำหนดธีมตาม Oklch เมื่อค่า Hue ปรับตามแถบเลื่อน ธีมทั้งหมดก็จะเปลี่ยนไปด้วย ซึ่งทำได้ด้วยไวยากรณ์สีสัมพัทธ์ พื้นหลังใช้สีหลักตามโทนสี และปรับช่องความสว่าง โครมา และโทนสีเพื่อปรับค่า --i คือดัชนีระดับเดียวกันในรายการสำหรับการไล่ระดับค่า ซึ่งแสดงให้เห็นว่าคุณจะรวมการเพิ่มค่ากับพร็อพเพอร์ตี้ที่กำหนดเองและไวยากรณ์สีสัมพัทธ์เพื่อสร้างธีมได้อย่างไร
Screencast การสาธิต
การสาธิตการใช้งานแบบสด
balance และ pretty ในส่วนหัวและย่อหน้าได้โดยการลากแถบเลื่อน ลองแปลการสาธิตเป็นภาษาอื่นดู:root {
  --hue: 230;
  --primary: oklch(70% .2 var(--hue));
}
li {
  --_bg: oklch(from var(--primary)
    calc(l - (var(--i) * .05))
    calc(c - (var(--i) * .01))
    calc(h - (var(--i) + 5)));
}
ฟังก์ชัน light-dark()
ฟังก์ชัน light-dark() ทำให้การกำหนดธีมมีความไดนามิกและง่ายขึ้นมาก
ฟังก์ชัน light-dark() เป็นการปรับปรุงตามหลักสรีรศาสตร์ที่ช่วยลดความซับซ้อนของตัวเลือกการกำหนดธีมสี เพื่อให้คุณเขียนรูปแบบธีมได้กระชับยิ่งขึ้น ดังที่ Adam Argyle แสดงให้เห็นอย่างชัดเจนในแผนภาพนี้ ก่อนหน้านี้ คุณจะต้องใช้โค้ด 2 บล็อกที่แตกต่างกัน (ธีมเริ่มต้นและคำค้นหาค่ากำหนดของผู้ใช้) เพื่อตั้งค่าตัวเลือกธีม ตอนนี้คุณสามารถเขียนตัวเลือกสไตล์เหล่านี้สำหรับทั้งธีมสว่างและธีมมืดในบรรทัด CSS เดียวกันได้โดยใช้ฟังก์ชัน light-dark()
light-dark() ดูข้อมูลเพิ่มเติมได้ที่เดโม
html {
  color-scheme: light dark;
}
button {
    background-color: light-dark(lightblue, darkblue);
}
หากผู้ใช้เลือกธีมสว่าง ปุ่มจะมีพื้นหลังสีฟ้าอ่อน หากผู้ใช้เลือกธีมมืด ปุ่มจะมีพื้นหลังสีน้ำเงินเข้ม
ตัวเลือก :has()
และคงเป็นการละเลยหากจะพูดถึง UI สมัยใหม่โดยไม่พูดถึงไฮไลต์การทำงานร่วมกันที่มีผลกระทบมากที่สุดอย่างหนึ่งจากปีที่ผ่านมา ซึ่งก็คือ:has()ตัวเลือก :has() ที่เปิดตัวในเบราว์เซอร์ต่างๆ เมื่อเดือนธันวาคมปีที่แล้ว API นี้เป็นตัวเปลี่ยนเกมสำหรับการเขียนสไตล์เชิงตรรกะ
:has()ตัวเลือกช่วยให้คุณตรวจสอบได้ว่าองค์ประกอบย่อยมีองค์ประกอบย่อยที่เฉพาะเจาะจงหรือไม่ หรือองค์ประกอบย่อยเหล่านั้นอยู่ในสถานะที่เฉพาะเจาะจงหรือไม่ และยังทำหน้าที่เป็นตัวเลือกหลักได้ด้วย
has() เพื่อจัดรูปแบบบล็อกเปรียบเทียบใน Tokopedia:has() มีประโยชน์อย่างยิ่งสำหรับบริษัทหลายแห่ง รวมถึง PolicyBazaar ซึ่งใช้ :has() เพื่อจัดรูปแบบบล็อกตามเนื้อหาภายใน เช่น ในส่วนเปรียบเทียบ ซึ่งรูปแบบจะปรับหากมีแพ็กเกจที่จะเปรียบเทียบในบล็อก หรือหากบล็อกว่างเปล่า
"ตัวเลือก :has() ช่วยให้เราไม่ต้องใช้การตรวจสอบที่อิงตาม JavaScript สำหรับตัวเลือกของผู้ใช้ และแทนที่ด้วยโซลูชัน CSS ซึ่งทำงานได้อย่างราบรื่นและให้ประสบการณ์การใช้งานแบบเดียวกับที่เคยได้รับ - Aman Soni, Tech Lead, PolicyBazaar"
การค้นหาคอนเทนเนอร์
อีกสิ่งสำคัญที่เพิ่มเข้ามาในเว็บซึ่งพร้อมให้ใช้งานแล้วและมีการใช้งานเพิ่มขึ้นเรื่อยๆ คือ Container Queries ซึ่งช่วยให้สามารถค้นหาขนาดโดยธรรมชาติขององค์ประกอบหลักเพื่อใช้สไตล์ได้ ซึ่งเป็นวิธีที่ละเอียดกว่า Media Queries มาก เนื่องจาก Media Queries จะค้นหาเฉพาะขนาด Viewport เท่านั้น
Angular เพิ่งเปิดตัวเว็บไซต์เอกสารประกอบใหม่ที่สวยงามบน angular.dev โดยใช้ Container Queries เพื่อจัดรูปแบบบล็อกส่วนหัวตามพื้นที่ว่างที่มีในหน้าเว็บ ดังนั้นแม้ว่าเลย์เอาต์จะเปลี่ยนจากเลย์เอาต์แถบด้านข้างแบบหลายคอลัมน์เป็นเลย์เอาต์แบบคอลัมน์เดียว บล็อกส่วนหัวก็สามารถปรับตัวเองได้
หากไม่มีการค้นหาคอนเทนเนอร์ การทำสิ่งต่างๆ เช่นนี้จะทำได้ยากมาก และส่งผลเสียต่อประสิทธิภาพ ซึ่งต้องใช้ Resize Observer และ Element Observer ตอนนี้การจัดรูปแบบองค์ประกอบตามขนาดขององค์ประกอบหลักจึงเป็นเรื่องง่าย
Screencast การสาธิต
การสาธิตการใช้งานแบบสด
@property
และในที่สุดในเร็วๆ นี้ เราก็ตื่นเต้นที่จะได้เห็น @property ปรากฏใน Baseline ซึ่งเป็นฟีเจอร์สำคัญในการให้ความหมายเชิงความหมายแก่พร็อพเพอร์ตี้ที่กำหนดเองของ CSS (หรือที่เรียกว่าตัวแปร CSS) และช่วยให้มีฟีเจอร์การโต้ตอบใหม่ๆ มากมาย @property ยังช่วยให้มีความหมายตามบริบท การตรวจสอบประเภท ค่าเริ่มต้น และค่าสำรองใน CSS ด้วย เปิดโอกาสให้มีฟีเจอร์ที่ดียิ่งขึ้น เช่น การค้นหาสไตล์ตามช่วง นี่เป็นฟีเจอร์ที่ไม่เคยมีมาก่อน และตอนนี้ก็ช่วยเพิ่มความลึกซึ้งให้กับภาษาของ CSS ได้มาก
Screencast การสาธิต
การสาธิตการใช้งานแบบสด
@property --card-bg {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0bae8;
}
บทสรุป
ความสามารถใหม่ๆ ของ UI ที่ทรงพลังเหล่านี้ซึ่งพร้อมใช้งานในเบราว์เซอร์ต่างๆ จะเปิดโอกาสให้คุณทำสิ่งต่างๆ ได้อย่างไม่สิ้นสุด ประสบการณ์อินเทอร์แอกทีฟใหม่ๆ ที่มีภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนและการเปลี่ยนมุมมองทำให้เว็บมีความลื่นไหลและอินเทอร์แอกทีฟมากขึ้นในแบบที่เราไม่เคยเห็นมาก่อน นอกจากนี้ คอมโพเนนต์ UI ระดับถัดไปยังช่วยให้การสร้างคอมโพเนนต์ที่แข็งแกร่งและปรับแต่งได้อย่างสวยงามทำได้ง่ายกว่าที่เคยโดยไม่ต้องยกเลิกประสบการณ์การใช้งานแบบเนทีฟทั้งหมด และสุดท้าย การปรับปรุงคุณภาพชีวิตในด้านสถาปัตยกรรม เลย์เอาต์ การจัดตัวอักษร และการออกแบบที่ตอบสนองไม่เพียงช่วยแก้ปัญหาเล็กๆ น้อยๆ แต่ยังมอบเครื่องมือที่นักพัฒนาแอปต้องการเพื่อสร้างอินเทอร์เฟซที่ซับซ้อนซึ่งทำงานได้ในอุปกรณ์ รูปแบบ และความต้องการของผู้ใช้ที่หลากหลาย
ฟีเจอร์ใหม่เหล่านี้จะช่วยให้คุณนำสคริปต์ของบุคคลที่สามออกสำหรับฟีเจอร์ที่ใช้ทรัพยากรมาก เช่น การเล่าเรื่องด้วยภาพแบบเลื่อนและเชื่อมโยงองค์ประกอบต่างๆ เข้าด้วยกันด้วยการวางตำแหน่ง Anchor สร้างการเปลี่ยนหน้าเว็บที่ลื่นไหล จัดรูปแบบเมนูแบบเลื่อนลง และปรับปรุงโครงสร้างโดยรวมของโค้ดของคุณได้โดยตรง
ปัจจุบันเป็นช่วงเวลาที่ดีที่สุดสำหรับนักพัฒนาเว็บ ตั้งแต่มีการประกาศ CSS3 ก็ไม่เคยมีเรื่องที่น่าตื่นเต้นและกระตือรือร้นมากขนาดนี้อีกเลย ฟีเจอร์ที่เราต้องการแต่เคยได้แค่ฝันถึงว่าจะได้ใช้จริง ในที่สุดก็กลายเป็นความจริงและเป็นส่วนหนึ่งของแพลตฟอร์ม และด้วยเสียงของคุณ เราจึงสามารถจัดลำดับความสำคัญและทำให้ความสามารถเหล่านี้เกิดขึ้นได้ในที่สุด เรากำลังพยายามทำให้การทำงานที่ยากและน่าเบื่อเป็นเรื่องง่ายขึ้น เพื่อให้คุณมีเวลามากขึ้นในการสร้างสรรค์สิ่งสำคัญ เช่น ฟีเจอร์หลักและรายละเอียดการออกแบบที่ทำให้แบรนด์ของคุณแตกต่าง
หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับฟีเจอร์ใหม่เหล่านี้เมื่อเปิดตัว โปรดติดตามที่ developer.chrome.com และ web.dev ซึ่งทีมของเราจะแชร์ข่าวสารล่าสุดเกี่ยวกับเทคโนโลยีเว็บ ลองใช้ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน การเปลี่ยนมุมมอง การวางตำแหน่งยึด หรือแม้แต่การเลือกที่ปรับแต่งได้ แล้วบอกความคิดเห็นของคุณกับเรา เราพร้อมรับฟังและพร้อมให้ความช่วยเหลือ
