Chia sẻ các phần tử với nhau bằng vị trí neo CSS

Bạn hiện đang chia sẻ Internet từ một phần tử khác bằng cách nào? Bạn có thể thử theo dõi vị trí của các phần tử đó hoặc sử dụng một dạng phần tử trình bao bọc nào đó.

<!-- 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;
}

Những giải pháp này thường không lý tưởng. Chúng cần JavaScript hoặc tạo thêm mã đánh dấu. API định vị neo CSS nhằm giải quyết vấn đề này bằng cách cung cấp một CSS API cho các phần tử chia sẻ Internet. Thành phần này cung cấp phương tiện để định vị và định kích thước một phần tử dựa trên vị trí và kích thước của các phần tử khác.

Hình ảnh minh hoạ cửa sổ trình duyệt nêu chi tiết cấu trúc chú giải công cụ.

Hỗ trợ trình duyệt

Bạn có thể dùng thử API định vị neo CSS trong Chrome Canary sau cờ "Tính năng nền tảng web thử nghiệm". Để bật cờ đó, hãy mở Chrome Canary rồi truy cập chrome://flags. Sau đó, bật cờ "Các tính năng nền tảng web thử nghiệm".

Nhóm của Oddbird cũng đang phát triển một đoạn mã polyfill. Hãy nhớ kiểm tra kho lưu trữ tại github.com/oddbird/css-anchor-positioning.

Bạn có thể kiểm tra tính năng hỗ trợ neo bằng:

@supports(anchor-name: --foo) {
  /* Styles... */
}

Xin lưu ý rằng API này vẫn đang trong giai đoạn thử nghiệm và có thể thay đổi. Bài viết này đề cập đến các phần quan trọng ở cấp độ tổng quát. Cách triển khai hiện tại cũng chưa hoàn toàn đồng bộ với quy cách của Nhóm hoạt động CSS.

Vấn đề

Vì sao bạn cần thực hiện việc này? Một trường hợp sử dụng nổi bật sẽ là tạo chú giải công cụ hoặc trải nghiệm giống chú giải công cụ. Trong trường hợp đó, bạn thường nên chia sẻ chú giải với nội dung mà chú thích đó tham chiếu. Thường thì bạn cần phải biết cách để chia sẻ Internet một phần tử với một phần tử khác. Bạn cũng kỳ vọng rằng việc tương tác với trang sẽ không làm hỏng đường liên kết đó, ví dụ: khi người dùng cuộn hoặc đổi kích thước giao diện người dùng.

Một vấn đề khác là khi bạn muốn đảm bảo phần tử được chia sẻ Internet vẫn hiển thị trong khung nhìn, ví dụ: nếu bạn mở một chú giải công cụ và phần này bị cắt bớt theo các giới hạn của khung nhìn. Đây có thể không phải là một trải nghiệm chất lượng cao cho người dùng. Bạn muốn điều chỉnh chú thích cho phù hợp.

Giải pháp hiện tại

Hiện tại, có một số cách khác nhau để bạn có thể tiếp cận vấn đề.

Đầu tiên là phương pháp cơ bản "Đóng gói neo". Bạn lấy cả hai thành phần và gói chúng trong một vùng chứa. Sau đó, bạn có thể dùng position để định vị chú giải công cụ so với điểm neo.

<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%);
}

Bạn có thể di chuyển vùng chứa và mọi thứ sẽ vẫn ở vị trí bạn muốn.

Một phương pháp tiếp cận khác có thể là nếu bạn biết vị trí của quảng cáo cố định hoặc bằng cách nào đó bạn có thể theo dõi vị trí đó. Bạn có thể chuyển nó vào chú giải công cụ có các thuộc tính tuỳ chỉnh.

<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));
}

Nhưng nếu bạn không biết vị trí neo thì sao? Có thể bạn cần phải can thiệp bằng JavaScript. Bạn có thể thực hiện thao tác như mã sau, nhưng hiện tại điều này có nghĩa là các kiểu của bạn đang bắt đầu bị rò rỉ ra khỏi CSS và vào 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);

Việc này sẽ bắt đầu đặt ra một số câu hỏi:

  • Khi nào tôi tính toán kiểu được?
  • Làm cách nào để tính toán kiểu?
  • Tôi có thường xuyên tính toán kiểu không?

Cách này có giải quyết được vấn đề không? Có thể giải pháp này phù hợp với trường hợp sử dụng của bạn, nhưng có một vấn đề: giải pháp của chúng tôi không thích ứng. Quảng cáo này không phản hồi. Điều gì sẽ xảy ra nếu phần tử cố định của tôi bị khung nhìn cắt mất?

Bây giờ, bạn cần quyết định xem có nên phản ứng với vấn đề này hay không và cách thức phản ứng. Số lượng câu hỏi và quyết định bạn cần đưa ra đang bắt đầu tăng lên. Bạn chỉ cần liên kết một thành phần với nhau. Và trong thế giới lý tưởng, giải pháp của bạn sẽ điều chỉnh và phản ứng với môi trường xung quanh.

Để giảm bớt phần nào đó, bạn có thể tìm đến giải pháp JavaScript để giúp mình. Việc đó sẽ làm phát sinh chi phí khi thêm phần phụ thuộc vào dự án của bạn và có thể gây ra các vấn đề về hiệu suất tuỳ thuộc vào cách bạn sử dụng phần phụ thuộc đó. Ví dụ: một số gói sử dụng requestAnimationFrame để giữ vị trí chính xác. Điều này có nghĩa là bạn và nhóm của bạn cần phải làm quen với gói và các tuỳ chọn cấu hình đi kèm. Kết quả là những câu hỏi và quyết định của bạn có thể không giảm xuống mà thay vào đó đã được thay đổi. Đây là một phần "lý do" cho việc định vị vị trí neo CSS. Khi tính toán vị trí, bạn sẽ không cần suy nghĩ về các vấn đề hiệu suất.

Dưới đây là ví dụ về mã khi sử dụng "floating-ui", một gói phổ biến cho vấn đề này:

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);

Hãy thử đặt lại vị trí của điểm neo (dùng mã đó) trong bản minh hoạ này.

"Chú thích" có thể không hoạt động như bạn mong đợi. Khung hình phản ứng khi chuyển ra ngoài khung nhìn trên trục y nhưng không phản ứng với trục x. Hãy tìm hiểu kỹ tài liệu này để có thể tìm được giải pháp phù hợp với mình.

Tuy nhiên, việc tìm được một gói phù hợp với dự án của bạn có thể mất nhiều thời gian. Đó là nhiều quyết định phụ và có thể gây khó chịu nếu kết quả không như bạn mong muốn.

Sử dụng tính năng định vị neo

Nhập API định vị neo CSS. Mục đích là để duy trì các kiểu trong CSS và giảm số lượng quyết định bạn cần đưa ra. Bạn hy vọng đạt được kết quả tương tự nhưng mục tiêu là cải thiện trải nghiệm của nhà phát triển.

  • Không yêu cầu JavaScript.
  • Hãy để trình duyệt tìm ra vị trí tốt nhất theo hướng dẫn của bạn.
  • Không còn phần phụ thuộc bên thứ ba nào khác
  • Không có phần tử trình bao bọc.
  • Hoạt động với các phần tử ở lớp trên cùng.

Hãy tái tạo và xử lý vấn đề mà chúng ta đang cố gắng giải quyết nêu trên. Nhưng thay vào đó, hãy sử dụng hình ảnh tương tự như một chiếc thuyền có neo. Các đối tượng này đại diện cho phần tử liên kết và neo. Nước đại diện cho khối chứa.

Trước tiên, bạn cần chọn cách xác định thẻ liên kết. Bạn có thể thực hiện việc này trong CSS bằng cách đặt thuộc tính anchor-name trong phần tử liên kết. Trường này chấp nhận giá trị giá trị nhận dạng có dấu gạch ngang.

.anchor {
  anchor-name: --my-anchor;
}

Ngoài ra, bạn có thể xác định thẻ liên kết trong HTML bằng thuộc tính anchor. Giá trị thuộc tính là mã nhận dạng của phần tử liên kết. Thao tác này sẽ tạo neo ngầm ẩn.

<a id="my-anchor" class="anchor"></a>
<div anchor="my-anchor" class="boat">I’m a boat!</div>

Sau khi xác định một neo, bạn có thể sử dụng hàm anchor. Hàm anchor nhận 3 đối số:

  • Phần tử liên kết: anchor-name của liên kết để sử dụng, hoặc bạn có thể bỏ qua giá trị để sử dụng liên kết implicit. Bạn có thể xác định đối số này thông qua mối quan hệ HTML hoặc bằng thuộc tính anchor-default có giá trị anchor-name.
  • Bên neo: Từ khoá về vị trí bạn muốn sử dụng. Đó có thể là top, right, bottom, left, center, v.v. Hoặc bạn có thể truyền một giá trị phần trăm. Ví dụ: 50% sẽ bằng center.
  • Dự phòng: Đây là giá trị dự phòng không bắt buộc chấp nhận độ dài hoặc tỷ lệ phần trăm.

Bạn sử dụng hàm anchor làm giá trị cho các thuộc tính lồng ghép (top, right, bottom, left hoặc giá trị tương đương về mặt logic) của phần tử liên kết. Bạn cũng có thể sử dụng hàm anchor trong 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));
}

Không có thuộc tính phần lồng ghép center, vì vậy, bạn có thể sử dụng calc nếu biết kích thước của phần tử liên kết. Tại sao không sử dụng translate? Bạn có thể sử dụng:

.boat {
  anchor-default: --my-anchor;
  bottom: anchor(top);
  left: anchor(center);
  translate: -50% 0;
}

Tuy nhiên, trình duyệt sẽ không xem xét các vị trí được biến đổi cho các phần tử cố định. Sẽ làm rõ lý do tại sao điều này lại quan trọng khi xem xét việc dự phòng vị trí và định vị tự động.

Bạn có thể đã nhận thấy việc sử dụng thuộc tính tuỳ chỉnh --boat-size ở trên. Tuy nhiên, nếu muốn dựa vào kích thước của phần tử liên kết dựa trên kích thước của điểm neo, bạn cũng có thể sử dụng kích thước đó. Thay vì tự tính toán, bạn có thể sử dụng hàm anchor-size. Ví dụ: để làm thuyền của chúng ta có chiều rộng gấp 4 lần chiều rộng của neo:

.boat {
  width: calc(4 * anchor-size(--my-anchor width));
}

Bạn cũng có quyền truy cập vào chiều cao bằng anchor-size(--my-anchor height). Và bạn có thể sử dụng đối tượng này để đặt kích thước của một trong hai trục hoặc cả hai.

Nếu bạn muốn liên kết với một phần tử có vị trí absolute thì sao? Quy tắc này là các phần tử không được là đồng cấp. Trong trường hợp đó, bạn có thể gói neo bằng một vùng chứa có vị trí relative. Sau đó, bạn có thể liên kết với trang web đó.

<div class="anchor-wrapper">
  <a id="my-anchor" class="anchor"></a>
</div>
<div class="boat">I’m a boat!</div>

Hãy xem bản minh hoạ này, trong đó bạn có thể kéo neo xung quanh và chiếc thuyền sẽ đi theo.

Theo dõi vị trí cuộn

Trong một số trường hợp, phần tử liên kết của bạn có thể nằm trong vùng chứa cuộn. Đồng thời, phần tử liên kết của bạn có thể nằm ngoài vùng chứa đó. Vì thao tác cuộn xảy ra trên một luồng khác với bố cục, nên bạn cần có cách theo dõi luồng này. Thuộc tính anchor-scroll có thể thực hiện việc này. Bạn đặt giá trị này cho thành phần liên kết và gán cho phần tử đó giá trị của điểm neo mà bạn muốn theo dõi.

.boat { anchor-scroll: --my-anchor; }

Hãy xem bản minh hoạ này, trong đó bạn có thể bật và tắt anchor-scroll bằng hộp đánh dấu ở góc.

Tuy nhiên, hình ảnh tương tự sẽ hơi bằng phẳng ở đây, như trong một thế giới lý tưởng, thuyền và neo của bạn đều ở dưới nước. Ngoài ra, các tính năng như Popover API (API Cửa sổ bật lên) quảng bá khả năng giữ chặt các phần tử có liên quan. Tuy nhiên, vị trí neo sẽ hoạt động với các phần tử nằm trong lớp trên cùng. Đây là một trong những lợi ích chính của API này: có thể chia sẻ Internet các phần tử ở nhiều luồng (flow).

Hãy xem xét bản minh hoạ này có vùng chứa cuộn với các neo có chú giải công cụ. Các thành phần chú giải công cụ là cửa sổ bật lên có thể không được đặt cùng vị trí với các điểm neo:

Tuy nhiên, bạn sẽ nhận thấy cách các cửa sổ bật lên theo dõi các liên kết neo tương ứng của chúng. Bạn có thể đổi kích thước vùng chứa cuộn đó và vị trí sẽ cập nhật cho bạn.

Vị trí dự phòng và định vị tự động

Đây là lúc khả năng định vị vị trí neo tăng lên. position-fallback có thể định vị phần tử cố định của bạn dựa trên một nhóm phương án dự phòng mà bạn cung cấp. Bạn định hướng trình duyệt theo phong cách của mình và để trình duyệt tự xác định vị trí cho bạn.

Trường hợp sử dụng phổ biến ở đây là một chú giải công cụ có thể chuyển đổi giữa việc hiển thị ở phía trên hoặc phía dưới quảng cáo cố định. Đồng thời, hành vi này dựa trên việc vùng chứa có cắt bớt chú giải công cụ hay không. Vùng chứa đó thường là khung nhìn.

Nếu đi sâu vào mã của bản minh hoạ gần đây nhất, bạn sẽ thấy có một thuộc tính position-fallback đang được sử dụng. Nếu cuộn vùng chứa, bạn có thể nhận thấy các cửa sổ bật lên cố định đó bật lên. Điều này xảy ra khi các neo tương ứng gần ranh giới khung nhìn. Tại thời điểm đó, các cửa sổ bật lên đang cố gắng điều chỉnh để ở trong khung nhìn.

Trước khi tạo position-fallback rõ ràng, tính năng định vị neo cũng sẽ cung cấp tính năng định vị tự động. Bạn có thể thực hiện thao tác lật miễn phí đó bằng cách sử dụng giá trị auto trong cả hàm neo và thuộc tính phần lồng ghép đối diện. Ví dụ: nếu bạn sử dụng anchor cho bottom, hãy đặt top thành auto.

.tooltip {
  position: absolute;
  bottom: anchor(--my-anchor auto);
  top: auto;
}

Một phương án thay thế cho việc định vị tự động là sử dụng position-fallback rõ ràng. Điều này yêu cầu bạn xác định một nhóm vị trí dự phòng. Trình duyệt sẽ trải qua các vị trí này cho đến khi tìm thấy vị trí có thể sử dụng, sau đó áp dụng vị trí đó. Nếu không tìm thấy biến thể phù hợp, giá trị mặc định sẽ là giá trị đầu tiên được xác định.

position-fallback cố gắng hiển thị các chú giải công cụ bên trên rồi bên dưới có thể có dạng như sau:

@position-fallback --top-to-bottom {
  @try {
    bottom: anchor(top);
    left: anchor(center);
  }

  @try {
    top: anchor(bottom);
    left: anchor(center);
  }
}

Việc áp dụng mã đó cho chú giải công cụ sẽ có dạng như sau:

.tooltip {
  anchor-default: --my-anchor;
  position-fallback: --top-to-bottom;
}

Việc sử dụng anchor-default có nghĩa là bạn có thể sử dụng lại position-fallback cho các phần tử khác. Bạn cũng có thể sử dụng thuộc tính tuỳ chỉnh theo phạm vi để đặt anchor-default.

Hãy xem xét lại bản minh hoạ này bằng thuyền. Có một tập hợp position-fallback. Khi bạn thay đổi vị trí của neo, chiếc thuyền sẽ điều chỉnh để vẫn ở trong vùng chứa. Hãy thử thay đổi giá trị khoảng đệm để điều chỉnh khoảng đệm của cơ thể. Lưu ý cách trình duyệt chỉnh sửa vị trí. Các vị trí đang được thay đổi bằng cách thay đổi căn chỉnh lưới của vùng chứa.

Lần này, position-fallback chi tiết hơn khi thử các vị trí theo chiều kim đồng hồ.

.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);
  }
}


Ví dụ

Giờ bạn đã có ý tưởng về các tính năng chính của vị trí neo, hãy cùng xem một số ví dụ thú vị ngoài phần chú thích. Những ví dụ này nhằm giúp bạn hiện thực hoá ý tưởng theo những cách mà bạn có thể sử dụng vị trí neo. Cách tốt nhất để phân tích cụ thể hơn là thông tin từ những người dùng thực như bạn.

Menu ngữ cảnh

Hãy bắt đầu với trình đơn theo bối cảnh bằng API Cửa sổ bật lên. Có ý nghĩa là thao tác nhấp vào nút có dấu chữ V sẽ làm hiển thị trình đơn theo bối cảnh. Và trình đơn đó sẽ có trình đơn riêng để mở rộng.

Mã đánh dấu không phải là phần quan trọng ở đây. Tuy nhiên, bạn có 3 nút sử dụng popovertarget. Tiếp theo là 3 phần tử sử dụng thuộc tính popover. Thao tác đó cung cấp cho bạn khả năng mở trình đơn ngữ cảnh mà không cần bất kỳ JavaScript nào. Mã sẽ có dạng như sau:

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

Giờ đây, bạn có thể xác định position-fallback và chia sẻ giữa các trình đơn theo bối cảnh. Chúng tôi cũng đảm bảo bạn không đặt bất kỳ kiểu inset nào cho cửa sổ bật lên.

[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);
  }
}

Thao tác này sẽ cung cấp cho bạn giao diện người dùng trình đơn theo bối cảnh lồng nhau thích ứng. Hãy thử thay đổi vị trí nội dung bằng nút chọn. Tuỳ chọn cập nhật chế độ căn chỉnh lưới. Và điều đó ảnh hưởng đến cách vị trí neo định vị cửa sổ bật lên.

Tập trung và theo dõi

Bản minh hoạ này kết hợp các dữ liệu gốc CSS bằng cách đưa vào :has(). Bạn có thể chuyển đổi chỉ báo trực quan cho input có tiêu điểm.

Bạn có thể thực hiện việc này bằng cách đặt một neo mới trong thời gian chạy. Đối với bản minh hoạ này, một tài sản tuỳ chỉnh trong phạm vi sẽ được cập nhật dựa trên tâm điểm nhập.

#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;
}

Nhưng làm cách nào để anh tiến xa hơn nữa? Bạn có thể sử dụng dữ liệu này cho một dạng lớp phủ hướng dẫn nào đó. Một chú giải công cụ có thể di chuyển giữa các địa điểm yêu thích và cập nhật nội dung. Bạn có thể làm mờ nội dung. Ảnh động rời rạc cho phép bạn tạo ảnh động cho display hoặc Chuyển đổi khung hiển thị có thể hoạt động ở đây.

Tính toán biểu đồ thanh

Một điều thú vị khác mà bạn có thể làm với việc định vị neo là kết hợp vị trí đó với calc. Hãy tưởng tượng một biểu đồ trong đó bạn có một số cửa sổ bật lên chú thích biểu đồ đó.

Bạn có thể theo dõi giá trị cao nhất và thấp nhất bằng CSS minmax. CSS cho dữ liệu đó có thể có dạng như sau:

.chart__tooltip--max {
    left: anchor(--chart right);
    bottom: max(
      anchor(--anchor-1 top),
      anchor(--anchor-2 top),
      anchor(--anchor-3 top)
    );
    translate: 0 50%;
  }

Có một số JavaScript đang chạy để cập nhật các giá trị trong biểu đồ và một số CSS để tạo kiểu cho biểu đồ. Tuy nhiên, tính năng định vị vị trí neo sẽ giúp chúng tôi xử lý việc cập nhật bố cục.

Đổi kích thước ô điều khiển

Bạn không cần phải chỉ liên kết đến một phần tử. Bạn có thể dùng nhiều liên kết cho một phần tử. Bạn có thể nhận thấy điều đó trong ví dụ về biểu đồ thanh. Chú giải công cụ được liên kết với biểu đồ rồi đến thanh tương ứng. Nếu triển khai khái niệm đó hơn nữa, bạn có thể sử dụng nó để đổi kích thước các phần tử.

Bạn có thể xem các điểm neo như ô điều khiển thay đổi kích thước tuỳ chỉnh và dựa vào giá trị inset.

.container {
   position: absolute;
   inset:
     anchor(--handle-1 top)
     anchor(--handle-2 right)
     anchor(--handle-2 bottom)
     anchor(--handle-1 left);
 }

Trong bản minh hoạ này, GreenSock Draggable làm cho các ô điều khiển có thể kéo được. Tuy nhiên, phần tử <img> sẽ đổi kích thước để lấp đầy vùng chứa, phần tử này sẽ điều chỉnh để lấp đầy khoảng trống giữa các ô điều khiển.

Một Trình đơn chọn?

Video cuối cùng chỉ để hé lộ về những gì sắp xảy ra. Tuy nhiên, bạn có thể tạo một cửa sổ bật lên có thể làm tâm điểm và giờ đây bạn đã có vị trí neo. Bạn có thể tạo nền tảng cho phần tử <select> có thể tạo kiểu.

<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 ngầm ẩn sẽ giúp việc này dễ dàng hơn. Tuy nhiên, CSS cho một điểm bắt đầu cơ bản có thể như sau:

[popovertarget] {
 anchor-name: --select-button;
}
[popover] {
  anchor-default: --select-button;
  top: anchor(bottom);
  width: anchor-size(width);
  left: anchor(left);
}

Bạn có thể kết hợp các tính năng của API Cửa sổ bật lên với tính năng Định vị neo CSS và bạn đã hoàn tất.

Thật gọn gàng khi bạn bắt đầu giới thiệu những nội dung như :has(). Bạn có thể xoay điểm đánh dấu khi đang mở:

.select-menu:has(:open) svg {
  rotate: 180deg;
}

Bạn có thể thực hiện ở đâu tiếp theo? Chúng ta cần làm gì khác để select hoạt động được? Chúng tôi sẽ lưu thông tin đó cho bài viết tiếp theo. Nhưng đừng lo lắng, các phần tử chọn có thể tạo kiểu sắp ra mắt. Hãy tiếp tục theo dõi!


Vậy là xong!

Nền tảng web đang phát triển. Vị trí neo CSS là một phần quan trọng để cải thiện cách bạn phát triển các thành phần điều khiển trên giao diện người dùng. Điều này sẽ giúp bạn tránh được một số quyết định khó khăn. Nhưng nhờ đó, bạn có thể làm được những việc mà trước đây bạn chưa bao giờ làm được. Chẳng hạn như định kiểu cho một phần tử <select>! Hãy chia sẻ suy nghĩ của bạn.

Ảnh chụp của CHUTTERSNAP trên Unsplash