API vị trí neo CSS là một yếu tố đột phá trong quá trình phát triển web vì API này cho phép bạn định vị nguyên bản các phần tử so với các phần tử khác, được gọi là neo. API này giúp đơn giản hoá các yêu cầu phức tạp về bố cục cho nhiều tính năng giao diện như trình đơn và trình đơn con, chú giải công cụ, lựa chọn, nhãn, thẻ, hộp thoại cài đặt, v.v. Với tính năng định vị neo được tích hợp vào trình duyệt, bạn có thể xây dựng các giao diện người dùng phân lớp mà không cần dựa vào thư viện của bên thứ ba, mở ra một thế giới với vô vàn khả năng sáng tạo.
Bạn có thể sử dụng tính năng định vị vị trí cố định trên Chrome 125.
Khái niệm cốt lõi: Neo và các phần tử được định vị
Trọng tâm của API này là mối quan hệ giữa quảng cáo cố định cuối màn hình và các phần tử có vị trí. Neo là một phần tử được chỉ định làm điểm tham chiếu bằng cách sử dụng thuộc tính anchor-name
. Phần tử được định vị là một phần tử được đặt tương ứng với một điểm neo bằng thuộc tính position-anchor
hoặc sử dụng anchor-name
một cách rõ ràng trong logic định vị.
Thiết lập neo
Việc tạo quảng cáo cố định rất đơn giản. Áp dụng thuộc tính tên liên kết cho phần tử đã chọn và chỉ định giá trị nhận dạng duy nhất cho phần tử đó. Giá trị nhận dạng duy nhất này phải được thêm vào trước một dấu gạch ngang kép, giống như biến CSS.
.anchor-button {
anchor-name: --anchor-el;
}
Sau khi được gán tên liên kết, .anchor-button
đóng vai trò là neo, sẵn sàng định hướng vị trí của các phần tử khác. Bạn có thể kết nối neo này với các phần tử khác theo một trong 2 cách:
Neo ngầm ẩn
Cách đầu tiên để kết nối một neo với một phần tử khác là thông qua một neo ngầm ẩn như trong đoạn mã ví dụ sau. Thuộc tính position-anchor
được thêm vào phần tử bạn muốn kết nối với liên kết và có giá trị là tên của liên kết (trong trường hợp này là --anchor-el
).
.positioned-notice {
position-anchor: --anchor-el;
}
Với mối quan hệ neo ngầm ẩn, bạn có thể định vị các phần tử bằng hàm anchor()
mà không cần chỉ định rõ tên liên kết tại đối số đầu tiên.
.positioned-notice {
position-anchor: --anchor-el;
top: anchor(bottom);
}
Quảng cáo cố định cuối màn hình
Ngoài ra, bạn có thể sử dụng tên liên kết trực tiếp trong hàm liên kết (ví dụ: top: anchor(--anchor-el bottom
). Đây được gọi là liên kết tường minh và có thể hữu ích nếu bạn muốn liên kết đến nhiều phần tử (hãy đọc tiếp để biết ví dụ).
.positioned-notice {
top: anchor(--anchor-el bottom);
}
Định vị các phần tử tương ứng với neo
Vị trí cố định dựa trên vị trí tuyệt đối của CSS Để sử dụng các giá trị định vị, bạn cần thêm position: absolute
vào phần tử được định vị. Sau đó, dùng hàm anchor()
để áp dụng các giá trị định vị. Ví dụ: để định vị một phần tử neo ở trên cùng bên trái của phần tử neo, hãy dùng vị trí sau đây:
.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);
}
Bây giờ, bạn đã liên kết một thành phần với một thành phần khác như sau:
Để sử dụng vị trí logic cho các giá trị này, các giá trị tương đương như sau:
top
=inset-block-start
left
=inset-inline-start
bottom
=inset-block-end
right
=inset-inline-end
Căn giữa một phần tử đã định vị theo vị trí anchor-center
Để giúp bạn dễ dàng căn giữa phần tử có vị trí neo so với điểm neo của phần tử đó dễ dàng hơn, bạn có thể sử dụng một giá trị mới tên là anchor-center
với các thuộc tính justify-self
, align-self
, justify-items
và align-items
.
Ví dụ này sửa đổi phần tử trước bằng cách dùng justify-self: anchor-center
để căn giữa phần tử đã định vị lên đầu neo của nó.
.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;
}
Nhiều quảng cáo cố định cuối màn hình
Các thành phần có thể được chia sẻ Internet với nhiều neo. Điều này có nghĩa là bạn có thể cần đặt giá trị vị trí được định vị tương ứng với nhiều điểm neo. Hãy thực hiện việc này bằng cách dùng hàm anchor()
và nêu rõ bạn đang tham chiếu đến neo nào trong đối số đầu tiên. Trong ví dụ sau, phần trên cùng bên trái của một phần tử được định vị được neo vào phía dưới cùng bên phải của một neo và góc dưới cùng bên phải của phần tử được định vị được neo vào phía trên cùng bên trái của neo thứ hai:
.anchored {
position: absolute;
top: anchor(--one bottom);
left: anchor(--one right);
right: anchor(--two left);
bottom: anchor(--two top);
}
Vị trí với inset-area
Ngoài vị trí định hướng mặc định từ vị trí tuyệt đối, API neo còn có một cơ chế bố cục mới được gọi là vùng lồng ghép.
Vùng lồng ghép giúp bạn dễ dàng đặt các phần tử định vị neo tương ứng với các neo tương ứng và hoạt động trên lưới 9 ô với phần tử neo ở giữa.
Nhiều tuỳ chọn định vị vùng lồng ghép có thể có, hiển thị trên lưới 9 ô
Để sử dụng vùng lồng ghép thay vì vị trí tuyệt đối, hãy dùng thuộc tính inset-area
với các giá trị thực hoặc logic. Ví dụ:
- Trên cùng chính giữa:
inset-area: top
hoặcinset-area: block-start
- Bên trái chính giữa:
inset-area: left
hoặcinset-area: inline-start
- Dưới cùng chính giữa:
inset-area: bottom
hoặcinset-area: block-end
- Chính giữa bên phải:
inset-area: right
hoặcinset-area: inline-end
Để khám phá thêm về những vị trí này, hãy kiểm tra công cụ sau:
Các phần tử kích thước có anchor-size()
Bạn có thể dùng hàm anchor-size()
(cũng là một phần của API định vị neo) để định kích thước hoặc định vị một phần tử neo dựa trên kích thước của phần tử neo (chiều rộng, chiều cao hoặc kích thước cùng dòng và khối).
CSS sau đây đưa ra ví dụ về cách dùng thuộc tính này cho chiều cao,dùng anchor-size(height)
trong hàm calc()
để đặt chiều cao tối đa của chú giải công cụ gấp hai lần chiều cao của điểm neo.
.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);
}
Dùng liên kết có các phần tử ở lớp trên cùng như cửa sổ bật lên và hộp thoại
Vị trí neo hoạt động cực kỳ hiệu quả với các phần tử lớp trên cùng như popover
. và <dialog>
. Mặc dù các phần tử này được đặt trong một lớp riêng biệt với phần còn lại của cây con DOM, nhưng vị trí neo cho phép bạn chia sẻ Internet trở lại và cuộn cùng với các phần tử không nằm trong lớp trên cùng. Đây là một thắng lợi lớn đối với giao diện được phân lớp.
Trong ví dụ sau đây, một nhóm các cửa sổ bật lên của chú giải công cụ được kích hoạt bằng một nút. Nút là điểm neo và chú giải công cụ là phần tử được định vị. Bạn có thể tạo kiểu cho phần tử đã định vị giống như mọi phần tử liên kết khác. Trong ví dụ cụ thể này, anchor-name
và position-anchor
là các kiểu cùng dòng trên nút và chú thích. Vì mỗi liên kết cần một tên liên kết riêng biệt, nên khi tạo nội dung động, cùng dòng là cách dễ nhất để thực hiện việc này.
Điều chỉnh vị trí neo bằng @position-try
Khi đã có vị trí neo ban đầu, bạn có thể điều chỉnh vị trí này nếu neo tiếp cận các cạnh của khối chứa. Để tạo vị trí neo thay thế, bạn có thể dùng lệnh @position-try
cùng với thuộc tính position-try-options
.
Trong ví dụ sau, một trình đơn phụ xuất hiện ở bên phải của một trình đơn. Trình đơn và trình đơn phụ là cách sử dụng tuyệt vời của API vị trí liên kết cùng với thuộc tính bật lên, vì các trình đơn này có xu hướng được neo vào nút kích hoạt.
Đối với trình đơn phụ này, nếu không có đủ không gian theo chiều ngang, bạn có thể di chuyển nó xuống bên dưới trình đơn. Để làm việc này, trước tiên, hãy thiết lập vị trí ban đầu:
#submenu {
position: absolute;
position-anchor: --submenu;
/* initial position */
margin-left: var(--padding);
inset-area: right span-bottom;
}
Sau đó, hãy thiết lập các vị trí neo dự phòng bằng cách sử dụng @position-try
:
/* alternate position */
@position-try --bottom {
margin: var(--padding) 0 0 var(--padding);
inset-area: bottom;
}
Cuối cùng, hãy kết nối cả hai với position-try-options
. Tất cả cùng nhau sẽ trông giống như sau:
#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;
}
Từ khóa tự động lật ở vị trí cố định
Nếu đã có một thao tác điều chỉnh cơ bản, chẳng hạn như lật từ trên xuống dưới hoặc từ trái sang phải (hoặc cả hai), thì bạn thậm chí có thể bỏ qua bước tạo nội dung khai báo @position-try
tuỳ chỉnh và sử dụng từ khoá lật tích hợp sẵn trong trình duyệt hỗ trợ như flip-block
và flip-inline
. Các thao tác này đóng vai trò thay thế cho các nội dung khai báo @position-try
tuỳ chỉnh và có thể kết hợp với nhau:
position-try-options: flip-block, flip-inline, flip-block flip-inline;
Từ khoá lật có thể đơn giản hoá đáng kể mã liên kết của bạn. Chỉ cần vài dòng, bạn có thể tạo một neo có đầy đủ chức năng với các vị trí thay thế:
#my-tooltip {
position-anchor: --question-mark;
inset-area: top;
position-try-options: flip-block;
}
position-visibility
cho quảng cáo cố định cuối màn hình trong thanh cuộn phụ
Trong một số trường hợp, bạn có thể muốn liên kết một phần tử trong một thành phần cuộn con của trang. Trong các trường hợp này, bạn có thể kiểm soát chế độ hiển thị của thẻ liên kết bằng cách sử dụng position-visibility
. Quảng cáo cố định cuối màn hình hiển thị khi nào? Khi nào dữ liệu này biến mất? Bạn có quyền kiểm soát các lựa chọn này bằng tính năng này. Bạn sử dụng position-visibility: anchors-visible
khi muốn phần tử đã được định vị ở chế độ hiển thị cho đến khi neo nằm ngoài khung hiển thị:
#tooltip {
position: fixed;
position-anchor: --anchor-top-anchor;
position-visibility: anchors-visible;
bottom: anchor(top);
}
Ngoài ra, bạn sử dụng position-visibility: no-overflow
để ngăn neo không tràn vùng chứa.
#tooltip {
position: absolute;
position-anchor: --anchor-top-anchor;
position-visibility: no-overflow;
bottom: anchor(top);
}
Phát hiện tính năng và chèn lấp đầy
Do trình duyệt hỗ trợ bị hạn chế tại thời điểm này, bạn có thể cần sử dụng API này kèm theo một số biện pháp phòng ngừa. Trước tiên, bạn có thể trực tiếp kiểm tra dịch vụ hỗ trợ trong CSS bằng cách sử dụng truy vấn tính năng @supports
. Để thực hiện việc này, bạn cần gói các kiểu neo như sau:
@supports (anchor-name: --myanchor) {
/* Anchor styles here */
}
Ngoài ra, bạn có thể chèn lấp tính năng định vị neo bằng polyfill CSS neo định vị của Oddbird, có thể hoạt động trên Firefox 54, Chrome 51, Edge 79 và Safari 10. Tệp polyfill này hỗ trợ hầu hết các tính năng cơ bản của vị trí neo, mặc dù việc triển khai hiện tại chưa hoàn tất và chứa một số cú pháp lỗi thời. Bạn có thể sử dụng đường liên kết unpkg hoặc nhập trực tiếp trong trình quản lý gói.
Lưu ý về khả năng hỗ trợ tiếp cận
Mặc dù API vị trí neo cho phép định vị một phần tử so với các phần tử khác, nhưng về bản chất, API này không tạo ra bất kỳ mối quan hệ ngữ nghĩa có ý nghĩa nào giữa chúng. Nếu thực sự có mối quan hệ ngữ nghĩa giữa phần tử liên kết và phần tử được định vị (ví dụ: phần tử được định vị là nhận xét ở thanh bên về văn bản liên kết), cách thực hiện là sử dụng aria-details
để trỏ từ phần tử liên kết đến(các) phần tử được định vị. Phần mềm trình đọc màn hình vẫn đang tìm hiểu cách xử lý aria-details (thông tin chi tiết về aria), nhưng dịch vụ hỗ trợ sẽ được cải thiện.
<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;
}
Nếu bạn đang dùng chế độ định vị neo với thuộc tính popover
hoặc với phần tử <dialog>
, thì trình duyệt sẽ xử lý các điểm điều chỉnh điều hướng tâm điểm để hỗ trợ tiếp cận phù hợp. Do đó, bạn không cần hiển thị cửa sổ bật lên hoặc hộp thoại theo thứ tự DOM. Vui lòng đọc thêm về ghi chú về tính năng hỗ trợ tiếp cận trong phần thông số kỹ thuật.
Kết luận
Đây là một tính năng hoàn toàn mới và chúng tôi rất vui khi được chứng kiến những sản phẩm mà bạn sẽ phát triển nhờ tính năng này. Cho đến nay, chúng tôi đã thấy một số trường hợp sử dụng thực sự gọn gàng trong cộng đồng như nhãn động trong biểu đồ, dòng kết nối, chú thích cuối trang và tham chiếu chéo trực quan. Trong khi bạn thử nghiệm chế độ xác định vị trí neo, chúng tôi rất mong nhận được ý kiến phản hồi của bạn. Nếu bạn phát hiện bất kỳ lỗi nào, hãy cho chúng tôi biết.