ในปัจจุบันคุณผูกโยงองค์ประกอบหนึ่งกับอีกองค์ประกอบหนึ่งได้อย่างไร คุณอาจลองติดตามตำแหน่งเหล่านั้น หรือใช้องค์ประกอบ Wrapper บางรูปแบบ
<!-- index.html -->
<div class="container">
<a href="/link" class="anchor">I’m the anchor</a>
<div class="anchored">I’m the anchored thing</div>
</div>
/* styles.css */
.container {
position: relative;
}
.anchored {
position: absolute;
}
โซลูชันเหล่านี้มักไม่เหมาะสำหรับ เนื่องจากจำเป็นต้องใช้ JavaScript หรือต้องใช้มาร์กอัปเพิ่มเติม API การวางตำแหน่ง Anchor ของ CSS มีวัตถุประสงค์เพื่อแก้ปัญหานี้โดยการระบุ CSS API สำหรับองค์ประกอบการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ วิธีการวางตำแหน่งและกำหนดขนาดขององค์ประกอบหนึ่งตามตำแหน่งและขนาดขององค์ประกอบอื่นๆ
การสนับสนุนเบราว์เซอร์
คุณสามารถลองใช้ API การวางตำแหน่ง Anchor ของ CSS ใน Chrome Canary ที่มี Flag "ฟีเจอร์แพลตฟอร์มเว็บรุ่นทดลอง" ได้ หากต้องการเปิดการตั้งค่าสถานะดังกล่าว ให้เปิด Chrome Canary แล้วไปที่ chrome://flags
จากนั้นให้เปิดใช้ Flag "ฟีเจอร์แพลตฟอร์มเว็บรุ่นทดลอง"
นอกจากนี้ยังมี Polyfill ที่อยู่ระหว่างการพัฒนาโดยทีม Oddbird ด้วย อย่าลืมตรวจสอบที่เก็บที่ github.com/oddbird/css-anchor-positioning
คุณสามารถตรวจสอบการสนับสนุนการตรึงด้วยสิ่งต่อไปนี้
@supports(anchor-name: --foo) {
/* Styles... */
}
โปรดทราบว่า API นี้ยังอยู่ในระยะทดลองและอาจมีการเปลี่ยนแปลง บทความนี้ครอบคลุมส่วนสําคัญในภาพรวม การใช้งานในปัจจุบันไม่ได้ซิงค์กับข้อกำหนดของคณะทำงานของ CSS โดยสมบูรณ์
ปัญหา
เหตุใดคุณจึงต้องทำเช่นนี้ กรณีการใช้งานที่เด่นชัดคือการสร้างเคล็ดลับเครื่องมือหรือประสบการณ์ที่เหมือนกับเคล็ดลับเครื่องมือ ในกรณีนี้ คุณมักจะต้องการเชื่อมโยงเคล็ดลับเครื่องมือกับเนื้อหาที่อ้างอิงอยู่ บ่อยครั้งจำเป็นต้องใช้วิธีเชื่อมโยงองค์ประกอบหนึ่งกับอีกองค์ประกอบหนึ่ง นอกจากนี้ คุณยังคาดหวังได้ว่าการโต้ตอบกับหน้าเว็บจะไม่ทำให้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือหยุดชะงัก เช่น หากผู้ใช้เลื่อนหรือปรับขนาด UI
ปัญหาอีกส่วนหนึ่งคือหากคุณต้องการตรวจสอบว่าองค์ประกอบที่ปล่อยสัญญาณไว้ยังคงมองเห็นได้อยู่ เช่น หากคุณเปิดเคล็ดลับเครื่องมือและองค์ประกอบนั้นถูกตัดโดยขอบเขตของวิวพอร์ต นี่อาจไม่ใช่ประสบการณ์การใช้งานที่ดีสำหรับผู้ใช้ คุณต้องการให้เคล็ดลับเครื่องมือสามารถนำไปใช้ได้
โซลูชันปัจจุบัน
ปัจจุบันคุณมีวิธีต่างๆ ในการจัดการปัญหานี้
อย่างแรกคือแนวทาง "รวมจุดยึด" ที่เป็นพื้นฐาน นำองค์ประกอบทั้ง 2 อย่างมารวมไว้ในภาชนะบรรจุ จากนั้นคุณสามารถใช้ position
เพื่อจัดตำแหน่งเคล็ดลับเครื่องมือให้สัมพันธ์กับแท็ก Anchor
<div class="containing-block">
<div class="tooltip">Anchor me!</div>
<a class="anchor">The anchor</a>
</div>
.containing-block {
position: relative;
}
.tooltip {
position: absolute;
bottom: calc(100% + 10px);
left: 50%;
transform: translateX(-50%);
}
คุณสามารถย้ายคอนเทนเนอร์ได้เพื่อให้ทุกอย่างอยู่ในที่ที่คุณต้องการมากที่สุด
อีกแนวทางหนึ่งอาจเป็นหากคุณทราบตำแหน่งของจุดยึดหรือติดตามตำแหน่งดังกล่าว คุณอาจส่งไปยังเคล็ดลับเครื่องมือด้วยพร็อพเพอร์ตี้ที่กำหนดเอง
<div class="tooltip">Anchor me!</div>
<a class="anchor">The anchor</a>
:root {
--anchor-width: 120px;
--anchor-top: 40vh;
--anchor-left: 20vmin;
}
.anchor {
position: absolute;
top: var(--anchor-top);
left: var(--anchor-left);
width: var(--anchor-width);
}
.tooltip {
position: absolute;
top: calc(var(--anchor-top));
left: calc((var(--anchor-width) * 0.5) + var(--anchor-left));
transform: translate(-50%, calc(-100% - 10px));
}
แต่หากคุณไม่ทราบตำแหน่งของ Anchor ล่ะ คุณอาจต้องแทรกแซง JavaScript คุณสามารถทำสิ่งต่างๆ ได้เหมือนที่โค้ดต่อไปนี้ทำได้ แต่ตอนนี้รูปแบบเริ่มรั่วไหลจาก CSS และเข้าสู่ JavaScript
const setAnchorPosition = (anchored, anchor) => {
const bounds = anchor.getBoundingClientRect().toJSON();
for (const [key, value] of Object.entries(bounds)) {
anchored.style.setProperty(`--${key}`, value);
}
};
const update = () => {
setAnchorPosition(
document.querySelector('.tooltip'),
document.querySelector('.anchor')
);
};
window.addEventListener('resize', update);
document.addEventListener('DOMContentLoaded', update);
สิ่งนี้จะเริ่มทำให้เกิดคำถามต่างๆ:
- ฉันจะคำนวณสไตล์เมื่อใด
- ฉันจะคำนวณสไตล์ได้อย่างไร
- ฉันคำนวณสไตล์บ่อยเพียงใด
วิธีนี้ช่วยแก้ปัญหาได้หรือไม่ อาจเพื่อ Use Case ของคุณ แต่มีปัญหาเดียวคือโซลูชันของเราปรับไม่ได้ อุปกรณ์ไม่ตอบสนอง จะเกิดอะไรขึ้นหากองค์ประกอบที่ตรึงไว้ของฉันถูกตัดโดยวิวพอร์ต
ตอนนี้คุณต้องตัดสินใจว่าจะตอบสนองหรือไม่และจะดำเนินการอย่างไร จำนวนคำถามและการตัดสินใจที่คุณจำเป็นต้องทำเริ่มเพิ่มมากขึ้น สิ่งที่คุณต้องทำคือการเชื่อมโยงองค์ประกอบหนึ่งเข้ากับอีกองค์ประกอบหนึ่ง โซลูชันของคุณจะปรับและตอบสนองต่อสภาพแวดล้อม
คุณอาจหาโซลูชัน JavaScript เพื่อช่วยคุณแก้ไขปัญหาดังกล่าว ซึ่งจะก่อให้เกิดค่าใช้จ่ายในการเพิ่มทรัพยากร Dependency ในโปรเจ็กต์ และอาจทำให้เกิดปัญหาด้านประสิทธิภาพ ทั้งนี้ขึ้นอยู่กับวิธีที่คุณใช้งาน เช่น แพ็กเกจบางรายการใช้ requestAnimationFrame
เพื่อให้ตำแหน่งถูกต้อง ซึ่งหมายความว่าคุณและทีมจะต้องทำความคุ้นเคยกับแพ็กเกจและตัวเลือกการกำหนดค่า ด้วยเหตุนี้ คำถามและการตัดสินใจของคุณอาจไม่ลดลง แต่มีการเปลี่ยนแปลงแทน ซึ่งเป็นส่วนหนึ่งของ "เหตุผล" สำหรับการวางตำแหน่ง Anchor ของ CSS ขณะคำนวณอันดับ นั่นจะทำให้คุณไม่คิดถึงปัญหาด้านประสิทธิภาพ
ต่อไปนี้คือหน้าตาของโค้ดเมื่อใช้ "floating-ui" ซึ่งเป็นแพ็กเกจยอดนิยมสำหรับปัญหานี้
import {computePosition, flip, offset, autoUpdate} from 'https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.2.1/+esm';
const anchor = document.querySelector('.anchor')
const tooltip = document.querySelector('.tooltip')
const updatePosition = () => {
computePosition(anchor, tooltip, {
placement: 'top',
middleware: [offset(10), flip()]
})
.then(({x, y}) => {
Object.assign(tooltip.style, {
left: `${x}px`,
top: `${y}px`
})
})
};
const clean = autoUpdate(anchor, tooltip, updatePosition);
ลองจัดตำแหน่งแท็ก Anchor ใหม่ในการสาธิตที่ใช้โค้ดดังกล่าว
"เคล็ดลับเครื่องมือ" อาจทำงานได้ไม่ตรงตามที่คุณคาดหวัง โดยจะตอบสนองต่อการออกไปนอกวิวพอร์ตบนแกน Y แต่ไม่ใช่แกน X อ่านเอกสารประกอบ แล้วคุณอาจพบวิธีแก้ปัญหาที่เหมาะกับคุณ
แต่การค้นหาแพ็กเกจที่เหมาะกับโครงการของคุณอาจใช้เวลานาน เป็นการตัดสินใจเพิ่มเติมและอาจทำให้น่าหงุดหงิดหากดำเนินการไม่ได้ตามที่ต้องการ
การใช้การวางตำแหน่งจุดยึด
ป้อน API การวางตำแหน่ง Anchor ของ CSS แนวคิดก็คือการคงสไตล์ไว้ใน CSS และลดจำนวนการตัดสินใจที่ต้องทำ คุณหวังว่าจะได้รับผลลัพธ์เดียวกัน แต่เป้าหมายคือการทำให้นักพัฒนาแอปได้รับประสบการณ์ที่ดียิ่งขึ้น
- ไม่ต้องใช้ JavaScript
- ให้เบราว์เซอร์ทำงานในตำแหน่งที่ดีที่สุดจากคำแนะนำของคุณ
- ไม่มีทรัพยากร Dependency ของบุคคลที่สามแล้ว
- ไม่มีองค์ประกอบ Wrapper
- ทำงานร่วมกับองค์ประกอบที่อยู่ในเลเยอร์บนสุด
มาลองแก้ไขปัญหาที่เราพยายามแก้ไขข้างต้นอีกครั้ง แต่ให้ใช้การอุปมาอุปไมยของเรือที่มีสมอ องค์ประกอบเหล่านี้แสดงถึงองค์ประกอบที่ตรึงไว้และแท็ก Anchor ส่วนน้ำแสดงถึงบล็อกที่มี
ก่อนอื่น คุณต้องเลือกวิธีกำหนดแท็ก Anchor ซึ่งทำได้ภายใน CSS โดยการตั้งค่าพร็อพเพอร์ตี้ anchor-name
ในองค์ประกอบ Anchor ยอมรับค่า id-ident
.anchor {
anchor-name: --my-anchor;
}
หรือจะกำหนดแท็ก Anchor ใน HTML ด้วยแอตทริบิวต์ anchor
ก็ได้ ค่าแอตทริบิวต์คือรหัสขององค์ประกอบแท็ก Anchor ซึ่งจะสร้าง Anchor โดยนัย
<a id="my-anchor" class="anchor"></a>
<div anchor="my-anchor" class="boat">I’m a boat!</div>
เมื่อคุณกำหนดแท็ก Anchor แล้ว คุณสามารถใช้ฟังก์ชัน anchor
ได้ ฟังก์ชัน anchor
รับอาร์กิวเมนต์ 3 รายการ ดังนี้
- องค์ประกอบ Anchor:
anchor-name
ของแท็ก Anchor ที่จะใช้ หรือคุณสามารถละเว้นค่าเพื่อใช้แท็ก Anchorimplicit
ก็ได้ ซึ่งสามารถกำหนดผ่านความสัมพันธ์ HTML หรือพร็อพเพอร์ตี้anchor-default
ที่มีค่าanchor-name
- ด้าน Anchor: คีย์เวิร์ดของตําแหน่งที่ต้องการใช้ ซึ่งอาจเป็น
top
,right
,bottom
,left
,center
ฯลฯ หรือคุณจะส่งผ่านเปอร์เซ็นต์ก็ได้ เช่น 50% จะเท่ากับcenter
- วิดีโอสำรอง: เป็นค่าสำรองที่ไม่บังคับซึ่งยอมรับความยาวหรือเปอร์เซ็นต์
คุณใช้ฟังก์ชัน anchor
เป็นค่าสำหรับพร็อพเพอร์ตี้ Inset (top
, right
, bottom
, left
หรือเทียบเท่าทางตรรกะ) ขององค์ประกอบที่ตรึงไว้ คุณยังใช้ฟังก์ชัน anchor
ใน calc
ได้ด้วย โดยทำดังนี้
.boat {
bottom: anchor(--my-anchor top);
left: calc(anchor(--my-anchor center) - (var(--boat-size) * 0.5));
}
/* alternative with anchor-default */
.boat {
anchor-default: --my-anchor;
bottom: anchor(top);
left: calc(anchor(center) - (var(--boat-size) * 0.5));
}
ไม่มีพร็อพเพอร์ตี้ Inset center
ดังนั้นตัวเลือกหนึ่งคือการใช้ calc
หากคุณทราบขนาดขององค์ประกอบที่ตรึงไว้ เหตุใดจึงไม่ใช้ translate
โดยคุณสามารถใช้คำสั่งต่อไปนี้
.boat {
anchor-default: --my-anchor;
bottom: anchor(top);
left: anchor(center);
translate: -50% 0;
}
แต่เบราว์เซอร์จะไม่พิจารณาตำแหน่งที่จะเปลี่ยนรูปแบบขององค์ประกอบที่ตรึงไว้ คุณจะเข้าใจได้ชัดเจนว่าเหตุใดจึงมีความสำคัญเมื่อพิจารณาการใช้ตำแหน่งสำรองและการกำหนดตำแหน่งอัตโนมัติ
คุณอาจสังเกตเห็นว่าด้านบนใช้พร็อพเพอร์ตี้ที่กำหนดเอง --boat-size
แต่หากต้องการยึดขนาดองค์ประกอบที่ตรึงไว้ตามขนาดของ Anchor ก็เข้าถึงขนาดดังกล่าวได้เช่นกัน คุณใช้ฟังก์ชัน anchor-size
แทนการคำนวณด้วยตนเองได้ เช่น หากต้องการทำให้เรือของเรากว้างเป็น 4 เท่าของความกว้างของสมอเรือ
.boat {
width: calc(4 * anchor-size(--my-anchor width));
}
คุณยังเข้าถึงความสูงได้ด้วยanchor-size(--my-anchor height)
และจะใช้เพื่อกำหนดขนาดของแกนใดแกนหนึ่งหรือทั้ง 2 แกนได้
หากคุณต้องการตรึงองค์ประกอบที่มีการจัดตำแหน่ง absolute
กฎคือองค์ประกอบต้องไม่เป็นระดับเดียวกัน ในกรณีดังกล่าว คุณจะรวม Anchor กับคอนเทนเนอร์ที่มีตําแหน่ง relative
ได้ จากนั้นคุณก็จะยึดติดกับชิ้นงานนั้นได้
<div class="anchor-wrapper">
<a id="my-anchor" class="anchor"></a>
</div>
<div class="boat">I’m a boat!</div>
ลองดูการสาธิตที่คุณสามารถลากสมอหมุนไปรอบๆ แล้วเรือจะตามมา
ตำแหน่งการเลื่อนการติดตาม
ในบางกรณี องค์ประกอบ Anchor อาจอยู่ในคอนเทนเนอร์แบบเลื่อน ในขณะเดียวกัน องค์ประกอบที่ตรึงไว้อาจอยู่นอกคอนเทนเนอร์นั้น เนื่องจากการเลื่อนเกิดขึ้นในชุดข้อความที่ต่างจากเลย์เอาต์ คุณจึงต้องมีวิธีติดตาม พร็อพเพอร์ตี้ anchor-scroll
ทำสิ่งต่อไปนี้ได้ โดยตั้งค่าในองค์ประกอบที่ตรึงไว้ในองค์ประกอบที่กำหนด และระบุค่าของ Anchor ที่ต้องการติดตาม
.boat { anchor-scroll: --my-anchor; }
ลองดูการสาธิตนี้ ซึ่งคุณจะเปิดและปิด anchor-scroll
ได้ด้วยช่องทำเครื่องหมายที่มุม
แต่ตัวเทียบเคียงจะมีลักษณะเป็นแนวราบเล็กน้อย ดังเช่นในอุดมคติ เรือและสมอเรือของคุณต่างก็จมอยู่ในน้ำ นอกจากนี้ ฟีเจอร์ต่างๆ อย่าง Popover API ก็โปรโมตว่าสามารถเก็บองค์ประกอบที่เกี่ยวข้องไว้ใกล้ตัวได้ แต่การวางตำแหน่งจุดยึดจะทำงานร่วมกับองค์ประกอบที่อยู่ในเลเยอร์บนสุด ซึ่งหนึ่งในประโยชน์หลักของ API นี้คือความสามารถในการเชื่อมต่ออินเทอร์เน็ตผ่านองค์ประกอบต่างๆ ในช่องทางต่างๆ
ลองดูการสาธิตนี้ซึ่งมีคอนเทนเนอร์แบบเลื่อนซึ่งมีแท็ก Anchor ซึ่งมีเคล็ดลับเครื่องมือ องค์ประกอบเคล็ดลับเครื่องมือที่เป็นป๊อปอัปอาจไม่ได้ตั้งอยู่ร่วมกับ Anchor ดังนี้
แต่คุณจะสังเกตเห็นวิธีที่ป๊อปอัปติดตามลิงก์ Anchor ที่เกี่ยวข้อง คุณปรับขนาดคอนเทนเนอร์แบบเลื่อนได้และระบบจะอัปเดตตำแหน่งให้คุณ
ตำแหน่งสำรองและการวางตำแหน่งอัตโนมัติ
นี่คือจุดที่กำลังของตำแหน่งของจุดยึดจะสูงขึ้นหนึ่งระดับ position-fallback
จะจัดตำแหน่งองค์ประกอบที่ตรึงไว้ในตำแหน่งตามชุดวิดีโอสำรองที่คุณให้ไว้ได้ คุณเป็นผู้กำหนดสไตล์ให้กับเบราว์เซอร์และปล่อยให้เบราว์เซอร์ทำงานให้เหมาะสมกับคุณ
Use Case ที่พบได้ทั่วไปคือเคล็ดลับเครื่องมือที่ควรเปลี่ยนระหว่างการแสดงเหนือหรือใต้แท็ก Anchor และลักษณะการทำงานนี้ขึ้นอยู่กับว่าคอนเทนเนอร์จะตัดเคล็ดลับเครื่องมือไปหรือไม่ คอนเทนเนอร์นั้นมักจะเป็นวิวพอร์ต
หากเจาะลึกโค้ดของการสาธิตล่าสุด คุณจะเห็นว่ามีการใช้พร็อพเพอร์ตี้ position-fallback
อยู่ หากคุณเลื่อนคอนเทนเนอร์ คุณอาจเห็นว่าป๊อปอัปที่ยึดตำแหน่งอยู่เหล่านั้นกระโดดขึ้น เหตุการณ์นี้เกิดขึ้นเมื่อ Anchor ที่เกี่ยวข้องอยู่ใกล้ขอบเขตของวิวพอร์ต ในตอนนี้ ป๊อปอัปกำลังพยายามปรับเพื่อให้อยู่ในวิวพอร์ตต่อไป
ก่อนที่จะสร้าง position-fallback
ที่ชัดเจน การกำหนดตำแหน่งจุดยึดจะเสนอการกำหนดตำแหน่งอัตโนมัติด้วย คุณพลิกนี้ไปได้ฟรีโดยใช้ค่า auto
ทั้งในฟังก์ชัน Anchor และพร็อพเพอร์ตี้ Inset ตรงกันข้าม เช่น หากคุณใช้ anchor
สําหรับ bottom
ให้ตั้งค่า top
เป็น auto
.tooltip {
position: absolute;
bottom: anchor(--my-anchor auto);
top: auto;
}
อีกทางเลือกหนึ่งที่ใช้แทนการจัดตำแหน่งอัตโนมัติคือการใช้ position-fallback
ที่ชัดเจน โดยคุณต้องกำหนดชุดตำแหน่งสำรอง เบราว์เซอร์จะตรวจสอบสิ่งเหล่านี้จนกว่าจะพบเบราว์เซอร์ที่ใช้ได้ จากนั้นจึงใช้การกำหนดตำแหน่งดังกล่าว หากไม่พบเครื่องมือที่ใช้งานได้ จะใช้ค่าเริ่มต้นเป็นกฎแรกที่กำหนดไว้
position-fallback
ที่พยายามแสดงเคล็ดลับเครื่องมือด้านบนอาจมีลักษณะดังนี้
@position-fallback --top-to-bottom {
@try {
bottom: anchor(top);
left: anchor(center);
}
@try {
top: anchor(bottom);
left: anchor(center);
}
}
การนำค่านั้นไปใช้กับเคล็ดลับเครื่องมือจะมีลักษณะดังนี้
.tooltip {
anchor-default: --my-anchor;
position-fallback: --top-to-bottom;
}
การใช้ anchor-default
หมายความว่าคุณจะใช้ position-fallback
ซ้ำกับองค์ประกอบอื่นๆ ได้ คุณยังใช้พร็อพเพอร์ตี้ที่กำหนดเองซึ่งกำหนดขอบเขตเพื่อตั้งค่า anchor-default
ได้ด้วย
ลองพิจารณาการสาธิตนี้โดยใช้เรืออีกครั้ง มีชุด position-fallback
อยู่ เมื่อคุณเปลี่ยนตำแหน่งของสมอ เรือจะปรับให้ยังอยู่ในภาชนะบรรจุ ลองเปลี่ยนค่าระยะห่างจากขอบด้วย ซึ่งจะปรับระยะห่างจากขอบเนื้อหาด้วย สังเกตวิธีที่เบราว์เซอร์แก้ไขตำแหน่ง ตำแหน่งจะเปลี่ยนโดยการเปลี่ยนการจัดแนวตารางกริดของคอนเทนเนอร์
คราวนี้ลองจัดตำแหน่งในทิศทางตามเข็มนาฬิกามากกว่า position-fallback
.boat {
anchor-default: --my-anchor;
position-fallback: --compass;
}
@position-fallback --compass {
@try {
bottom: anchor(top);
right: anchor(left);
}
@try {
bottom: anchor(top);
left: anchor(right);
}
@try {
top: anchor(bottom);
right: anchor(left);
}
@try {
top: anchor(bottom);
left: anchor(right);
}
}
ตัวอย่าง
ตอนนี้คุณมีไอเดียเกี่ยวกับคุณลักษณะหลักๆ สำหรับการกำหนดตำแหน่งจุดยึดแล้ว มาดูตัวอย่างที่น่าสนใจนอกเหนือจากเคล็ดลับเครื่องมือกันดีกว่า ตัวอย่างเหล่านี้มีเป้าหมายที่จะทำให้ไอเดียของคุณลื่นไหลในการใช้การวางตำแหน่งโฆษณา Anchor วิธีที่ดีที่สุดในข้อกำหนดเพิ่มเติมคือการให้ข้อมูลจากผู้ใช้จริงเช่นคุณ
เมนูตามบริบท
เรามาเริ่มกันที่เมนูตามบริบทที่ใช้ Popover API แนวคิดคือการคลิกปุ่มที่มีเครื่องหมายบั้งจะแสดงเมนูตามบริบท และเมนูดังกล่าวจะมีเมนูของตัวเองให้ขยายออก
มาร์กอัปไม่ใช่ส่วนสำคัญในที่นี้ แต่มีปุ่ม 3 ปุ่มที่ใช้แต่ละปุ่ม popovertarget
จากนั้นคุณก็มีองค์ประกอบ 3 อย่างโดยใช้แอตทริบิวต์ popover
ซึ่งจะช่วยให้คุณเปิดเมนูตามบริบทได้โดยไม่ต้องใช้ JavaScript ซึ่งจะมีลักษณะดังนี้
<button popovertarget="context">
Toggle Menu
</button>
<div popover="auto" id="context">
<ul>
<li><button>Save to your Liked Songs</button></li>
<li>
<button popovertarget="playlist">
Add to Playlist
</button>
</li>
<li>
<button popovertarget="share">
Share
</button>
</li>
</ul>
</div>
<div popover="auto" id="share">...</div>
<div popover="auto" id="playlist">...</div>
ตอนนี้คุณสามารถกำหนด position-fallback
และแชร์ระหว่างเมนูตามบริบทได้แล้ว อย่าลืมยกเลิกการตั้งค่าสไตล์ inset
สำหรับป๊อปอัปด้วย
[popovertarget="share"] {
anchor-name: --share;
}
[popovertarget="playlist"] {
anchor-name: --playlist;
}
[popovertarget="context"] {
anchor-name: --context;
}
#share {
anchor-default: --share;
position-fallback: --aligned;
}
#playlist {
anchor-default: --playlist;
position-fallback: --aligned;
}
#context {
anchor-default: --context;
position-fallback: --flip;
}
@position-fallback --aligned {
@try {
top: anchor(top);
left: anchor(right);
}
@try {
top: anchor(bottom);
left: anchor(right);
}
@try {
top: anchor(top);
right: anchor(left);
}
@try {
bottom: anchor(bottom);
left: anchor(right);
}
@try {
right: anchor(left);
bottom: anchor(bottom);
}
}
@position-fallback --flip {
@try {
bottom: anchor(top);
left: anchor(left);
}
@try {
right: anchor(right);
bottom: anchor(top);
}
@try {
top: anchor(bottom);
left: anchor(left);
}
@try {
top: anchor(bottom);
right: anchor(right);
}
}
ซึ่งจะแสดง UI เมนูตามบริบทที่ซ้อนกันแบบปรับขนาดได้ ลองเปลี่ยนตำแหน่งเนื้อหาด้วยรายการที่เลือก ตัวเลือกที่คุณเลือกจะอัปเดตการจัดแนวตารางกริด ซึ่งจะส่งผลต่อการวางตำแหน่งหมุดยึดตำแหน่งป๊อปโอเวอร์
จดจ่อและทำตาม
เดโมนี้รวมค่าดั้งเดิมของ CSS ด้วยการนำ :has() เข้ามาด้วย แนวคิดคือเปลี่ยนสัญญาณบอกสถานะสำหรับ input
ที่โฟกัสอยู่
ซึ่งทำได้โดยการตั้งค่า Anchor ใหม่ระหว่างรันไทม์ ในการสาธิตนี้ พร็อพเพอร์ตี้ที่กำหนดเองซึ่งกำหนดขอบเขตจะได้รับการอัปเดต ณ จุดโฟกัสของอินพุต
#email {
anchor-name: --email;
}
#name {
anchor-name: --name;
}
#password {
anchor-name: --password;
}
:root:has(#email:focus) {
--active-anchor: --email;
}
:root:has(#name:focus) {
--active-anchor: --name;
}
:root:has(#password:focus) {
--active-anchor: --password;
}
:root {
--active-anchor: --name;
--active-left: anchor(var(--active-anchor) right);
--active-top: calc(
anchor(var(--active-anchor) top) +
(
(
anchor(var(--active-anchor) bottom) -
anchor(var(--active-anchor) top)
) * 0.5
)
);
}
.form-indicator {
left: var(--active-left);
top: var(--active-top);
transition: all 0.2s;
}
แต่คุณจะพัฒนาไปไกลอีกได้อย่างไร ซึ่งคุณสามารถใช้สำหรับการซ้อนทับการสอนบางรูปแบบได้ เคล็ดลับเครื่องมือจะย้ายไปมาระหว่างจุดสนใจและอัปเดตเนื้อหาได้ คุณสามารถข้ามเนื้อหาไปได้ ภาพเคลื่อนไหวแบบต่อเนื่องที่อนุญาตให้คุณ ทำให้ display
เคลื่อนไหว หรือ ดูการเปลี่ยน อาจทำงานที่นี่
การคำนวณแผนภูมิแท่ง
ความสนุกอีกอย่างที่คุณทำได้โดยใช้การกำหนดตำแหน่ง Anchor คือการรวมกับ calc
ลองจินตนาการถึงแผนภูมิที่มีป๊อปอัปที่ใส่คำอธิบายประกอบในแผนภูมิ
คุณสามารถติดตามค่าสูงสุดและต่ำสุดได้โดยใช้ CSS min
และ max
CSS จะมีลักษณะดังนี้
.chart__tooltip--max {
left: anchor(--chart right);
bottom: max(
anchor(--anchor-1 top),
anchor(--anchor-2 top),
anchor(--anchor-3 top)
);
translate: 0 50%;
}
โดยมี JavaScript บางส่วนเพื่ออัปเดตค่าของแผนภูมิและ CSS บางรายการเพื่อปรับรูปแบบแผนภูมิ แต่การวางตำแหน่ง Anchor จะช่วยเราจัดการการอัปเดตเลย์เอาต์
ปรับขนาดแฮนเดิล
คุณไม่จำเป็นต้องตรึงเพียงองค์ประกอบเดียว คุณอาจใช้จุดยึดหลายรายการสำหรับองค์ประกอบหนึ่งๆ คุณอาจสังเกตเห็นว่าในตัวอย่างแผนภูมิแท่ง เคล็ดลับเครื่องมือตรึงอยู่กับแผนภูมิและแท่งที่เหมาะสม หากคุณเข้าใจแนวคิดดังกล่าวมากขึ้นอีกเล็กน้อย คุณสามารถใช้แนวคิดนั้นเพื่อปรับขนาดองค์ประกอบได้
คุณอาจใช้จุดยึดอย่างเช่นแฮนเดิลปรับขนาดที่กำหนดเอง และใช้ค่า inset
.container {
position: absolute;
inset:
anchor(--handle-1 top)
anchor(--handle-2 right)
anchor(--handle-2 bottom)
anchor(--handle-1 left);
}
ในการสาธิตนี้ GreenSock Draggable จะทำให้แฮนเดิลลากได้ แต่องค์ประกอบ <img>
จะปรับขนาดให้เต็มคอนเทนเนอร์ซึ่งปรับให้เต็มช่องว่างระหว่างแฮนเดิล
เลือกเมนู?
ข้อสุดท้าย นี้เป็นเพียงตัวอย่างเล็กน้อยเกี่ยวกับสิ่งที่จะเกิดขึ้น แต่คุณสามารถสร้างป๊อปอัปที่โฟกัสได้ และตอนนี้คุณมีตำแหน่งจุดยึดแล้ว คุณจะสร้างพื้นฐานขององค์ประกอบ <select>
ที่กำหนดค่าได้
<div class="select-menu">
<button popovertarget="listbox">
Select option
<svg>...</svg>
</button>
<div popover="auto" id="listbox">
<option>A</option>
<option>Styled</option>
<option>Select</option>
</div>
</div>
การกำหนด anchor
โดยนัยจะช่วยให้ดำเนินการได้ง่ายขึ้น แต่ CSS สำหรับจุดเริ่มต้นเบื้องต้นอาจมีลักษณะดังนี้
[popovertarget] {
anchor-name: --select-button;
}
[popover] {
anchor-default: --select-button;
top: anchor(bottom);
width: anchor-size(width);
left: anchor(left);
}
รวมฟีเจอร์ของ Popover API เข้ากับตำแหน่ง Anchor ของ CSS แค่นี้ก็เสร็จแล้ว
การเริ่มแนะนำสิ่งต่างๆ อย่าง :has()
จะช่วยได้ คุณสามารถหมุนเครื่องหมายขณะเปิดได้โดยทําดังนี้
.select-menu:has(:open) svg {
rotate: 180deg;
}
คุณจะพัฒนาไปตรงไหนต่อไป มีอะไรที่เราต้องมีอีกบ้างเพื่อทำให้เป็น select
ที่ใช้งานได้ เราจะบันทึกไว้สำหรับบทความถัดไป แต่ไม่ต้องกังวล เรากำลังจะเปิดตัวองค์ประกอบที่เลือกสไตล์ได้ โปรดติดตามต่อไป
เท่านี้ก็เรียบร้อย
แพลตฟอร์มเว็บกำลังพัฒนา การจัดตำแหน่ง Anchor ของ CSS เป็นส่วนสำคัญในการปรับปรุงวิธีพัฒนาการควบคุม UI แต่จะทำให้คุณขจัดความยุ่งยากในการตัดสินใจ นอกจากนี้ยังช่วยให้คุณทำในสิ่งที่ไม่เคยได้ทำมาก่อนอีกด้วย เช่น การจัดรูปแบบองค์ประกอบ <select>
บอกให้เรารู้ว่าคุณคิดอย่างไร
รูปภาพโดย CHUTTERSNAP ใน Unsplash