ขอแนะนำ CSS Anchor Positioning API

Anchor Positioning API ของ CSS เป็นตัวเปลี่ยนเกมในการพัฒนาเว็บ เนื่องจากจะช่วยให้คุณวางตำแหน่งองค์ประกอบได้อย่างกลมกลืนกับองค์ประกอบอื่นๆ ซึ่งเรียกว่าแท็ก Anchor API นี้จะลดความซับซ้อนของข้อกำหนดเลย์เอาต์ที่ซับซ้อนสำหรับฟีเจอร์อินเทอร์เฟซต่างๆ เช่น เมนูและเมนูย่อย เคล็ดลับเครื่องมือ รายการที่เลือก ป้ายกำกับ การ์ด กล่องโต้ตอบการตั้งค่า และอีกมากมาย เมื่อมีการวางตำแหน่งจุดยึดในเบราว์เซอร์ คุณจะสามารถสร้างอินเทอร์เฟซผู้ใช้แบบเลเยอร์ได้โดยไม่ต้องอาศัยไลบรารีของบุคคลที่สาม ซึ่งจะเปิดโลกแห่งความเป็นไปได้ในการสร้างสรรค์

การวางตำแหน่ง Anchor พร้อมให้ใช้งานใน Chrome 125

การรองรับเบราว์เซอร์

  • Chrome: 125
  • ขอบ: 125
  • Firefox: ไม่สนับสนุน
  • Safari: ไม่รองรับ

แหล่งที่มา

แนวคิดหลัก: จุดยึดและองค์ประกอบที่จัดวางตำแหน่ง

หัวใจของ API นี้คือความสัมพันธ์ระหว่างแท็ก Anchor และองค์ประกอบที่มีตำแหน่ง แท็ก Anchor คือองค์ประกอบที่ได้รับการกำหนดให้เป็นจุดอ้างอิงโดยใช้คุณสมบัติ anchor-name องค์ประกอบที่มีตำแหน่งคือองค์ประกอบที่วางสัมพันธ์กับ Anchor โดยใช้พร็อพเพอร์ตี้ position-anchor หรือใช้ anchor-name อย่างชัดแจ้งในตรรกะการจัดตำแหน่ง

วันที่
องค์ประกอบ Anchor และองค์ประกอบที่วางตำแหน่ง

การตั้งค่า Anchor

การสร้าง Anchor นั้นไม่ซับซ้อน ใช้พร็อพเพอร์ตี้ชื่อ Anchor กับองค์ประกอบที่เลือก และกำหนดตัวระบุที่ไม่ซ้ำกันให้กับองค์ประกอบนั้น ตัวระบุที่ไม่ซ้ำกันนี้ต้องเพิ่มขีดกลาง 2 ขีดไว้ด้านหน้า คล้ายกับตัวแปร CSS

.anchor-button {
    anchor-name: --anchor-el;
}

เมื่อได้รับชื่อ Anchor แล้ว .anchor-button จะทำหน้าที่เป็น Anchor ที่พร้อมแนะนำตำแหน่งขององค์ประกอบอื่นๆ คุณเชื่อมต่อจุดยึดนี้กับองค์ประกอบอื่นๆ ได้ 2 วิธีดังนี้

โฆษณา Anchor ที่ไม่เจาะจง

วิธีแรกในการเชื่อมต่อแท็ก Anchor กับองค์ประกอบอื่นคือใช้ anchor โดยนัย ตามตัวอย่างโค้ดต่อไปนี้ ระบบจะเพิ่มพร็อพเพอร์ตี้ position-anchor ลงในองค์ประกอบที่คุณต้องการเชื่อมต่อกับแท็ก Anchor และใช้ชื่อ Anchor (ในกรณีนี้คือ --anchor-el) เป็นค่า

.positioned-notice {
    position-anchor: --anchor-el;
}

คุณจัดตำแหน่งองค์ประกอบโดยใช้ฟังก์ชัน anchor() ได้โดยไม่ต้องระบุชื่อ Anchor ที่อาร์กิวเมนต์แรกอย่างชัดแจ้ง

.positioned-notice {
    position-anchor: --anchor-el;
    top: anchor(bottom);
}

โฆษณา Anchor ที่อาจไม่เหมาะสม

หรือจะใช้ชื่อ Anchor โดยตรงในฟังก์ชัน Anchor ก็ได้ (เช่น top: anchor(--anchor-el bottom) วิธีนี้เรียกว่าแท็ก Anchor ที่ชัดแจ้ง และมีประโยชน์ในกรณีที่คุณต้องการยึดกับองค์ประกอบหลายรายการ (อ่านตัวอย่างต่อไป)

.positioned-notice {
    top: anchor(--anchor-el bottom);
}

องค์ประกอบตำแหน่งซึ่งสัมพันธ์กับ Anchor

วันที่
แผนภาพการจัดตำแหน่งแบบยึดกับคุณสมบัติทางกายภาพ

การจัดตำแหน่งแบบ Anchor สร้างขึ้นจากการจัดตำแหน่งแบบสัมบูรณ์ของ CSS หากต้องการใช้ค่าการจัดตำแหน่ง คุณต้องเพิ่ม position: absolute ลงในองค์ประกอบที่จัดวางตำแหน่งของคุณได้ จากนั้นใช้ฟังก์ชัน anchor() เพื่อนำค่าการกำหนดตำแหน่งไปใช้ ตัวอย่างเช่น หากต้องการวางตำแหน่งองค์ประกอบที่ตรึงอยู่ที่ด้านบนซ้ายขององค์ประกอบที่ตรึงอยู่ ให้ใช้ตำแหน่งต่อไปนี้

.positioned-notice {
    position-anchor: --anchor-el;
    /* absolutely position the positioned element */
    position: absolute;
    /* position the right of the positioned element at the right edge of the anchor */
    right: anchor(right);
    /* position the bottom of the positioned element at the top edge of the anchor */
    bottom: anchor(top);
}
แผนภาพของขอบการวางตำแหน่งบนองค์ประกอบที่จัดวางตำแหน่ง

ตอนนี้คุณก็มีองค์ประกอบหนึ่งที่ตรึงอยู่กับอีกองค์ประกอบหนึ่ง ดังนี้

การสาธิตโฆษณา Anchor พื้นฐาน

ภาพหน้าจอของการสาธิต

ในการใช้การจัดตำแหน่งเชิงตรรกะสำหรับค่าเหล่านี้ ค่าที่เทียบเท่ามีดังนี้

  • top = inset-block-start
  • left= inset-inline-start
  • bottom = inset-block-end
  • right= inset-inline-end

จัดองค์ประกอบที่อยู่ในตำแหน่งกึ่งกลางด้วย anchor-center

มีค่าใหม่ที่เรียกว่า anchor-center ซึ่งใช้ได้กับพร็อพเพอร์ตี้ justify-self, align-self, justify-items และ align-items เพื่อให้คุณจัดองค์ประกอบที่อยู่ในตำแหน่งกึ่งกลางโดยเทียบกับแท็ก Anchor ได้ง่ายขึ้น

ตัวอย่างนี้แก้ไของค์ประกอบก่อนหน้าโดยใช้ justify-self: anchor-center เพื่อจัดองค์ประกอบที่วางอยู่ไว้กึ่งกลางด้านบนของ Anchor

.positioned-notice {
  position: absolute;
  /*  Anchor reference  */
  position-anchor: --anchor-el;
  /*  Position bottom of positioned elem at top of anchor  */
  bottom: anchor(top);
  /*  Center justification to the anchor */
  justify-self: anchor-center;
}
การสาธิตโฆษณา Anchor ที่อยู่ตรงกลางโดยใช้ justify-center

ภาพหน้าจอของการสาธิต

โฆษณา Anchor หลายตัว

องค์ประกอบสามารถเชื่อมโยงกับแท็ก Anchor ได้มากกว่า 1 รายการ ซึ่งหมายความว่าคุณอาจต้องตั้งค่าตำแหน่งที่สัมพันธ์กับแท็ก Anchor มากกว่าหนึ่งรายการ โดยใช้ฟังก์ชัน anchor() และระบุให้ชัดเจนว่า Anchor ที่คุณกำลังอ้างอิงในอาร์กิวเมนต์แรก ในตัวอย่างต่อไปนี้ จากด้านบนซ้ายขององค์ประกอบที่มีตำแหน่งจะตรึงอยู่ด้านขวาล่างของ anchor 1 รายการ และด้านล่างขวาขององค์ประกอบที่อยู่ในตำแหน่งจะยึดกับด้านซ้ายบนของ Anchor ที่ 2

.anchored {
  position: absolute;
  top: anchor(--one bottom);
  left: anchor(--one right);
  right: anchor(--two left);
  bottom: anchor(--two top);
}
การสาธิตแสดงโฆษณา Anchor หลายรายการ

ภาพหน้าจอของการสาธิต

ตำแหน่งที่มี inset-area

นอกจากการกำหนดตำแหน่งแบบทิศทางเริ่มต้นจากตำแหน่งแบบสัมบูรณ์แล้ว ยังมีกลไกเลย์เอาต์ใหม่รวมอยู่ใน Anchor API ที่เรียกว่าพื้นที่ฝังด้วย

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

ตัวเลือกต่างๆ ในการกำหนดตำแหน่งพื้นที่ภายในอาคารที่เป็นไปได้ซึ่งแสดงในตารางกริด 9 เซลล์

หากต้องการใช้พื้นที่แทรกแทนการจัดตำแหน่งแบบสัมบูรณ์ ให้ใช้พร็อพเพอร์ตี้ inset-area พร้อมค่าทางกายภาพหรือทางตรรกะ เช่น

  • ตรงกลางด้านบน: inset-area: top หรือ inset-area: block-start
  • กึ่งกลางด้านซ้าย: inset-area: left หรือ inset-area: inline-start
  • ตรงกลางด้านล่าง: inset-area: bottom หรือ inset-area: block-end
  • กึ่งกลางด้านขวา: inset-area: right หรือ inset-area: inline-end
การสาธิตแสดงโฆษณา Anchor หลายรายการ

ภาพหน้าจอของการสาธิต

หากต้องการสำรวจอันดับเหล่านี้เพิ่มเติม ให้ลองใช้เครื่องมือต่อไปนี้

เครื่องมือยึดสำหรับตำแหน่งของพื้นที่แทรก

องค์ประกอบของขนาดที่มี anchor-size()

คุณสามารถใช้ฟังก์ชัน anchor-size() ซึ่งเป็นส่วนหนึ่งของ API การกำหนดตำแหน่งแท็ก Anchor เพื่อกำหนดขนาดหรือจัดตำแหน่งองค์ประกอบที่อยู่ในตำแหน่ง Anchor ได้ตามขนาดของ Anchor (ความกว้าง ความสูง หรือขนาดในบรรทัดและขนาดบล็อก)

CSS ต่อไปนี้แสดงตัวอย่างของการใช้ค่านี้สำหรับความสูง โดยใช้ anchor-size(height) ภายในฟังก์ชัน calc() เพื่อกำหนดความสูงสูงสุดของเคล็ดลับเครื่องมือให้เป็น 2 เท่าของความสูงของจุดยึด

.positioned-notice {
  position-anchor: --question-mark;

  /*  set max height of the tooltip to 2x height of the anchor  */
  max-height: calc(anchor-size(height) * 2);
}
การสาธิตสำหรับ anchor-size

ภาพหน้าจอของการสาธิต

ใช้ Anchor กับองค์ประกอบชั้นบนสุด เช่น ป๊อปโอเวอร์และกล่องโต้ตอบ

การจัดตำแหน่งแท็ก Anchor ทำงานได้ดีอย่างไม่น่าเชื่อกับองค์ประกอบชั้นบนสุดอย่างเช่น popover และ <dialog> แม้ว่าองค์ประกอบเหล่านี้จะวางอยู่ในเลเยอร์ที่แยกจากโครงสร้างย่อย DOM ส่วนที่เหลือ แต่การจัดตำแหน่งแท็ก Anchor จะช่วยให้คุณเชื่อมโยงองค์ประกอบเหล่านั้นกลับไปและเลื่อนไปตามองค์ประกอบที่ไม่ได้อยู่ในเลเยอร์บนสุดได้ นี่เป็นข้อดีอย่างยิ่งสำหรับอินเทอร์เฟซแบบเลเยอร์

ในตัวอย่างต่อไปนี้ ชุดของป๊อปอัปเคล็ดลับเครื่องมือจะทริกเกอร์ให้เปิดโดยใช้ปุ่ม ปุ่มคือ Anchor ส่วนเคล็ดลับเครื่องมือคือองค์ประกอบที่อยู่ในตำแหน่ง คุณจัดรูปแบบองค์ประกอบที่อยู่ในตำแหน่งได้เช่นเดียวกับองค์ประกอบที่ตรึงไว้อื่นๆ สำหรับตัวอย่างนี้ anchor-name และ position-anchor เป็นรูปแบบอินไลน์บนปุ่มและเคล็ดลับเครื่องมือ เนื่องจากแท็ก Anchor แต่ละรายการต้องมีชื่อ Anchor ที่ไม่ซ้ำกัน เมื่อสร้างเนื้อหาแบบไดนามิก ในบรรทัดจึงเป็นวิธีที่ง่ายที่สุดในการดำเนินการดังกล่าว

สาธิตโดยใช้ Anchor กับ popover

ภาพหน้าจอของการสาธิต

ปรับตำแหน่ง Anchor ด้วย @position-try

เมื่อคุณได้ตำแหน่งยึดตำแหน่งเริ่มต้นแล้ว คุณอาจต้องปรับตำแหน่งเมื่อยึดตำแหน่งไปถึงขอบของบล็อกยึด หากต้องการสร้างตำแหน่งแท็ก Anchor ทางเลือก ให้ใช้คำสั่ง @position-try ร่วมกับพร็อพเพอร์ตี้ position-try-options

ในตัวอย่างต่อไปนี้ เมนูย่อยจะปรากฏที่ด้านขวาของเมนู เมนูและเมนูย่อยใช้ API การกำหนดตำแหน่งจุดยึดร่วมกับแอตทริบิวต์ป๊อปโอเวอร์ได้เป็นอย่างดี เนื่องจากเมนูเหล่านี้มักจะยึดอยู่กับปุ่มทริกเกอร์

สำหรับเมนูย่อยนี้ หากมีพื้นที่ในแนวนอนไม่เพียงพอ คุณสามารถย้ายเมนูย่อยนั้นไปด้านล่างเมนูแทนได้ หากต้องการทำเช่นนี้ ก่อนอื่นให้ตั้งค่าตำแหน่งเริ่มต้น

#submenu {
  position: absolute;
  position-anchor: --submenu;

  /* initial position */
  margin-left: var(--padding);
  inset-area: right span-bottom;
}

จากนั้นตั้งค่าตำแหน่ง Anchor สำรองโดยใช้ @position-try ดังนี้

/* alternate position */
@position-try --bottom {
  margin: var(--padding) 0 0 var(--padding);
  inset-area: bottom;
}

สุดท้าย ให้เชื่อมต่อทั้งคู่กับ position-try-options เมื่อรวมกันแล้ว จะมีลักษณะดังนี้

#submenu {
  position: absolute;
  position-anchor: --submenu;
  /* initial position */
  margin-left: var(--padding);
  inset-area: right span-bottom;
  */ connect with position-try options */
  position-try-options: --bottom;
}

/* alternate position */
@position-try --bottom {
  margin: var(--padding) 0 0 var(--padding);
  inset-area: bottom;
}
สาธิตโดยใช้ Anchor กับ popover

คีย์เวิร์ดพลิกอัตโนมัติในตำแหน่งโฆษณา Anchor

หากมีการปรับแต่งขั้นพื้นฐาน เช่น พลิกจากบนลงล่างหรือซ้ายไปขวา (หรือทั้ง 2 อย่าง) คุณยังข้ามขั้นตอนในการสร้างการประกาศ @position-try ที่กำหนดเองและใช้คีย์เวิร์ดแบบพลิกที่เบราว์เซอร์รองรับในตัวได้ เช่น flip-block และ flip-inline ค่าเหล่านี้ทำหน้าที่เป็นตัวเทียบข้อมูลสําหรับการประกาศ @position-try ที่กําหนดเอง และใช้ร่วมกันได้

position-try-options: flip-block, flip-inline, flip-block flip-inline;

การพลิกคีย์เวิร์ดอาจลดความซับซ้อนของโค้ด Anchor ได้อย่างมาก เพียงไม่กี่บรรทัด คุณก็สามารถสร้างจุดยึดที่ทำงานได้อย่างสมบูรณ์พร้อมตำแหน่งอื่นๆ ต่อไปนี้

#my-tooltip {
  position-anchor: --question-mark;
  inset-area: top;
  position-try-options: flip-block;
}
การใช้การพลิกอัตโนมัติกับ position-try-options: flip-block

position-visibility สําหรับจุดยึดในแถบเลื่อนย่อย

ในบางกรณีคุณอาจต้องการตรึงองค์ประกอบไว้ในแถบเลื่อนย่อยของหน้าเว็บ ในกรณีเหล่านี้ คุณควบคุมการแสดง Anchor โดยใช้ position-visibility ได้ โฆษณา Anchor จะแสดงเมื่อใด ข้อมูลดังกล่าวหายไปเมื่อใด คุณควบคุมตัวเลือกเหล่านี้ได้ด้วยฟีเจอร์นี้ คุณใช้ position-visibility: anchors-visible เมื่อต้องการให้องค์ประกอบที่อยู่ในตำแหน่งดังกล่าวปรากฏในมุมมองจนกว่า Anchor จะอยู่นอกมุมมอง

#tooltip {
  position: fixed;
  position-anchor: --anchor-top-anchor;
  position-visibility: anchors-visible;
  bottom: anchor(top);
}
position-visibility: anchors-visible การสาธิต

หรือจะใช้ position-visibility: no-overflow เพื่อป้องกันไม่ให้ Anchor ล้นคอนเทนเนอร์

#tooltip {
  position: absolute;
  position-anchor: --anchor-top-anchor;
  position-visibility: no-overflow;
  bottom: anchor(top);
}
position-visibility: no-overflow การสาธิต

การตรวจหาฟีเจอร์และการทำโพลีฟิลล์

เนื่องจากในขณะนี้มีการจำกัดการรองรับเบราว์เซอร์ คุณอาจต้องการใช้ API นี้อย่างระมัดระวัง ก่อนอื่น คุณสามารถติดต่อขอรับการสนับสนุนได้โดยตรงใน CSS โดยใช้การค้นหาฟีเจอร์@supports วิธีการคือรวมสไตล์ Anchor ไว้ดังนี้

@supports (anchor-name: --myanchor) {

  /* Anchor styles here */

}

นอกจากนี้ คุณยังทำ Polyfill ฟีเจอร์การกำหนดตำแหน่งแท็ก Anchor ได้ด้วย polyfill ของตำแหน่งแท็ก Anchor สำหรับ CSS โดย Oddbird ซึ่งใช้งานได้ใน Firefox 54, Chrome 51, Edge 79 และ Safari 10 Polyfill นี้รองรับฟีเจอร์ตำแหน่งยึดตำแหน่งพื้นฐานส่วนใหญ่ แม้ว่าการใช้งานในปัจจุบันจะยังไม่สมบูรณ์และมีไวยากรณ์ที่ล้าสมัยอยู่บ้าง คุณสามารถใช้ลิงก์ unpkg หรือนำเข้าโดยตรงในตัวจัดการแพ็กเกจ

หมายเหตุเกี่ยวกับการช่วยเหลือพิเศษ

แม้ว่า API การจัดตำแหน่งแท็ก Anchor จะทำให้จัดตำแหน่งองค์ประกอบได้โดยสัมพันธ์กับองค์ประกอบอื่นๆ แต่ API ดังกล่าวไม่ได้สร้างความสัมพันธ์เชิงความหมายที่มีความหมายระหว่างองค์ประกอบเหล่านั้นโดยธรรมชาติ หากมีความสัมพันธ์เชิงความหมายระหว่างองค์ประกอบ Anchor และองค์ประกอบที่วางตำแหน่ง (เช่น องค์ประกอบที่วางตำแหน่งเป็นความคิดเห็นในแถบด้านข้างเกี่ยวกับ anchor text) วิธีหนึ่งที่สามารถทำได้คือใช้ aria-details เพื่อชี้จากองค์ประกอบ Anchor ไปยังองค์ประกอบที่อยู่ในตำแหน่ง ซอฟต์แวร์โปรแกรมอ่านหน้าจอยังอยู่ในช่วงเรียนรู้วิธีจัดการกับรายละเอียด ARIA แต่กำลังปรับปรุงการรองรับ

<div class="anchor" aria-details="sidebar-comment">Main content</div>
<div class="positioned" id="sidebar-comment">Sidebar content</div>
.anchor {
  anchor-name: --anchor;
}

.positioned {
  position: fixed;
  position-anchor: --anchor;
}

หากคุณใช้การวางตำแหน่งจุดยึดกับแอตทริบิวต์ popover หรือองค์ประกอบ <dialog> เบราว์เซอร์จะจัดการการแก้ไขการนำทางโฟกัสเพื่อการเข้าถึงที่เหมาะสม คุณจึงไม่จำเป็นต้องแสดงป๊อปอัปหรือกล่องโต้ตอบตามลำดับ DOM อ่านเพิ่มเติมเกี่ยวกับหมายเหตุเกี่ยวกับการช่วยเหลือพิเศษในข้อมูลจำเพาะ

บทสรุป

ฟีเจอร์นี้เป็นฟีเจอร์ใหม่ และเราตื่นเต้นที่จะได้เห็นผลงานที่คุณพัฒนาจากฟีเจอร์ดังกล่าว ที่ผ่านมาเราได้เห็นกรณีการใช้งานที่มีประโยชน์มากจากชุมชน เช่น ป้ายกํากับแบบไดนามิกในแผนภูมิ เส้นเชื่อมต่อ เชิงอรรถ และการอ้างอิงเปรียบเทียบด้วยภาพ ขณะที่คุณกำลังทดสอบการจัดตำแหน่งโฆษณา Anchor เราอยากจะฟังความคิดเห็นจากคุณ และหากคุณพบข้อบกพร่อง โปรดแจ้งให้เราทราบ

อ่านเพิ่มเติม