Giới thiệu API định vị neo CSS

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.

Hỗ trợ trình duyệt

  • 125
  • 125
  • x
  • x

Nguồn

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ìnhcá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ị.

Phần tử liên kết và phần tử được đị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

Sơ đồ định vị neo với các thuộc tính thực tế.

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);
}
Biểu đồ các cạnh định vị trên phần tử đã được định vị.

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:

Bản minh hoạ về điểm neo cơ bản.

Ảnh chụp màn hình bản minh hoạ.

Để 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-itemsalign-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;
}
Bản minh hoạ neo được căn giữa bằng justify-center.

Ảnh chụp màn hình bản minh hoạ.

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);
}
Bản minh hoạ cho thấy nhiều quảng cáo cố định cuối màn hình.

Ảnh chụp màn hình bản minh hoạ.

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ặc inset-area: block-start
  • Bên trái chính giữa: inset-area: left hoặc inset-area: inline-start
  • Dưới cùng chính giữa: inset-area: bottom hoặc inset-area: block-end
  • Chính giữa bên phải: inset-area: right hoặc inset-area: inline-end
Bản minh hoạ cho thấy nhiều quảng cáo cố định cuối màn hình.

Ảnh chụp màn hình bản minh hoạ.

Để khám phá thêm về những vị trí này, hãy kiểm tra công cụ sau:

Công cụ neo cho các vị trí của vùng lồng ghép.

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);
}
Bản minh hoạ cho anchor-size

Ảnh chụp màn hình bản minh hoạ.

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-nameposition-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.

Bản minh hoạ sử dụng neo với popover

Ảnh chụp màn hình bản minh hoạ.

Đ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;
}
Bản minh hoạ sử dụng neo với popover

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-blockflip-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;
}
Dùng tính năng tự động lật với 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);
}
Bản minh hoạ position-visibility: anchors-visible

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);
}
Bản minh hoạ position-visibility: no-overflow

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.

Tài liệu đọc thêm