ขอแนะนำ CSS Anchor Positioning API

เผยแพร่: 10 พฤษภาคม 2024

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

ตำแหน่งหมุดพร้อมใช้งานใน Chrome 125

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox: not supported.
  • Safari: not supported.

Source

แนวคิดหลัก: องค์ประกอบหลักและองค์ประกอบที่มีตำแหน่ง

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

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

การตั้งค่าหมุด

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

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

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

โฆษณา Anchor ที่ไม่ระบุ

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

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

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

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

โฆษณา Anchor ที่ระบุอย่างชัดเจน

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

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

วางองค์ประกอบให้สัมพันธ์กับจุดยึด

แผนภาพตำแหน่งของจุดยึดที่มีพร็อพเพอร์ตี้ทางกายภาพ

การจัดตำแหน่งจุดยึดจะอิงตามการจัดตำแหน่งแบบสัมบูรณ์ของ 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);
}
แผนภาพขอบตำแหน่งในองค์ประกอบที่มีตำแหน่ง

ตอนนี้คุณมีองค์ประกอบหนึ่งยึดอยู่กับอีกองค์ประกอบหนึ่งแล้ว ดังที่แสดงในภาพต่อไปนี้

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

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

  • 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 ได้ เพื่อให้จัดองค์ประกอบที่วางตำแหน่งเป็นจุดยึดให้อยู่ตรงกลางได้ง่ายขึ้นเมื่อเทียบกับจุดยึด

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

.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 หลายรายการ

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

.anchored {
  position: absolute;
  top: anchor(--one bottom);
  left: anchor(--one right);
  right: anchor(--two left);
  bottom: anchor(--two top);
}

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

ตำแหน่งด้วย inset-area

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

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

ฟังก์ชัน anchor-size() ซึ่งเป็นส่วนหนึ่งของ Anchor Positioning API สามารถใช้เพื่อปรับขนาดหรือจัดตําแหน่งขององค์ประกอบที่วางตำแหน่งตาม 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);
}

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

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

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

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

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

ปรับตําแหน่งโฆษณา Anchor ด้วย @position-try

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

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

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

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

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

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

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

สุดท้าย ให้เชื่อมต่ออุปกรณ์ทั้ง 2 เครื่องด้วย 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;
}

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

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

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

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

#my-tooltip {
  position-anchor: --question-mark;
  inset-area: top;
  position-try-options: flip-block;
}

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

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

#tooltip {
  position: fixed;
  position-anchor: --anchor-top-anchor;
  position-visibility: anchors-visible;
  bottom: anchor(top);
}

หรือจะใช้ position-visibility: no-overflow เพื่อไม่ให้ตัวยึดเกินขอบคอนเทนเนอร์ก็ได้

#tooltip {
  position: absolute;
  position-anchor: --anchor-top-anchor;
  position-visibility: no-overflow;
  bottom: anchor(top);
}

การตรวจหาฟีเจอร์และ polyfill

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

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

  /* Anchor styles here */

}

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

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

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

<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 อ่านหมายเหตุเกี่ยวกับการช่วยเหลือพิเศษในข้อกำหนด

บทสรุป

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

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