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

Bạn hiện làm cách nào để chia sẻ Internet từ một phần tử với nhau? 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.

<!-- 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. Công cụ này cần JavaScript hoặc sử dụng mã đánh dấu bổ sung. API định vị điểm neo CSS hướng đến giải quyết vấn đề này bằng cách cung cấp CSS API cho các phần tử chia sẻ Internet. Nó cung cấp phương tiện để xác định vị trí 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 là một cửa sổ trình duyệt minh hoạ, trình bày chi tiết cấu trúc của một chú thích.

Hỗ trợ trình duyệt

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

Ngoài ra, nhóm của Oddbird còn có một polyfill đang trong quá trình phát triển. Hãy nhớ kiểm tra repo 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 không hoàn toàn đồng bộ với quy cách của Nhóm công tác CSS.

Vấn đề

Tại sao bạn cần phải thực hiện việc này? Một trường hợp sử dụng nổi bật là tạo chú thích hoặc trải nghiệm giống như chú thích. Trong trường hợp đó, bạn thường muốn chia sẻ phần chú thích với nội dung mà chú giải công cụ tham chiếu đến. Thông thường, bạn sẽ cần một cách nào đó để chia sẻ Internet từ một phần tử. Bạn cũng có thể kỳ vọng rằng việc tương tác với trang không phá vỡ quy tắc chia sẻ Internet đó, ví dụ: nếu 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 xuất hiện trong khung nhìn, chẳng hạn như khi bạn mở một chú thích và phần đó bị cắt bớt do ranh giới khung nhìn. Có thể đây không phải là một trải nghiệm tốt cho người dùng. Bạn muốn chú thích điều chỉnh.

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

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

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

<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 ở nơi bạn muốn.

Một phương pháp khác có thể là nếu bạn biết vị trí neo của mình hoặc bạn có thể theo dõi nó bằng cách nào đó. Bạn có thể chuyển tham số này đến chú giải công cụ bằng 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í quảng cáo cố định thì sao? Bạn có thể cần phải can thiệp bằng JavaScript. Bạn có thể làm những việc tương tự 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 rò rỉ ra khỏi CSS và chuyển 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 bắt đầu đặt ra một số câu hỏi:

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

Cách đó có giải quyết được vấn đề không? Có thể nó 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 chưa thích ứng. 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 bớt?

Bây giờ, bạn cần quyết định xem có nên phản ứng với điều này hay không và phản ứng bằng cách nào. 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 phần tử với một phần tử khác. Và trong một 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 một phần đau khổ, bạn có thể tìm kiếm giải pháp JavaScript để giúp bạn. Việc này sẽ làm phát sinh chi phí 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 làm quen với gói này và các lựa chọn cấu hình. Do đó, các câu hỏi và quyết định của bạn có thể sẽ không giảm đi, mà sẽ thay đổi. Đây là một phần của "lý do" cho vị trí neo CSS. Khi đó, bạn sẽ không còn phải suy nghĩ đến các vấn đề về hiệu suất khi tính toán vị trí.

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í neo trong bản minh hoạ có sử dụng mã đó.

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

Tuy nhiên, việc tìm được gói phù hợp với dự án của bạn có thể sẽ mất rất nhiều thời gian. Việc này là quyết định bổ sung và có thể gây phiền toái nếu chiến dịch không hoạt động như mong muốn.

Sử dụng vị trí neo

Nhập API định vị quảng cáo cố định cuối màn hình CSS. Mục đích là giữ nguyên kiểu của bạn 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 cần JavaScript.
  • Để trình duyệt tìm ra vị trí phù hợp nhất theo hướng dẫn của bạn.
  • Không còn phần phụ thuộc của bên thứ ba
  • Không có phần tử trình bao bọc.
  • Làm việc với các phần tử ở lớp trên cùng.

Hãy tạo lại và giải quyết vấn đề mà chúng ta đã cố gắng giải quyết ở trên. Nhưng thay vào đó, hãy sử dụng ví dụ giống như một chiếc thuyền có neo. Các thành phần này đại diện cho thành phần cố định và điểm 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 quảng cáo cố định. Bạn có thể làm việc này trong CSS bằng cách đặt thuộc tính anchor-name trong thành phần neo. Phương thức này chấp nhận giá trị dấu gạch ngang.

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

Ngoài ra, bạn có thể xác định một quảng cáo cố định 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 ra một 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ố:

  • Thành phần 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 thuộc tính 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.
  • Quảng cáo cố định cuối màn hình: Từ khoá cho vị trí mà bạn muốn sử dụng. Đó có thể là top, right, bottom, left, center, v.v. Bạn cũng có thể chuyển một tỷ lệ 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 thời lượng 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 phần lồng ghép (top, right, bottom, left hoặc các thuộc tính logic tương đương của chúng) 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 nên bạn có thể dùng calc nếu biết kích thước của phần tử cố định. Tại sao không sử dụng translate? Bạn có thể dùng:

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

Tuy nhiên, trình duyệt không xem xét vị trí được chuyển đổi cho các phần tử cố định. Vì sao điều này lại quan trọng khi xem xét việc dự phòng vị trí và tự động định vị.

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 đặt kích thước phần tử cố định dựa vào kích thước của neo, bạn cũng có thể truy cập vào kích thước đó. Thay vì tự tính, bạn có thể sử dụng hàm anchor-size. Ví dụ: để làm cho chiếc 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 hàm 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 đến một phần tử có vị trí absolute thì sao? Quy tắc là các phần tử không được đồng cấp. Trong trường hợp đó, bạn có thể gói điểm neo bằng một vùng chứa có vị trí relative. Sau đó, bạn có thể neo vào ứng dụng đó.

<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ẽ theo sau.

Đang theo dõi vị trí cuộn

Trong một số trường hợp, phần tử neo của bạn có thể nằm trong vùng chứa cuộn. Đồng thời, phần tử cố định có thể nằm bên ngoài vùng chứa đó. Vì thao tác cuộn diễn 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 nó vào phần tử neo và gán giá trị cho quảng cáo cố định mà bạn muốn theo dõi.

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

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

Tuy nhiên, ví dụ tương tự này là một chút phẳng ở đây, giống như trong một thế giới lý tưởng, thuyền và neo của bạn đều ở trong nước. Ngoài ra, các tính năng như API Cửa sổ bật lên giúp giữ kín 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ử ở lớp trên cùng. Đây là một trong những lợi ích chính của API: có thể chia sẻ kết nối các phần tử trong nhiều luồng.

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

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 đường liên kết neo tương ứng. Bạn có thể đổi kích thước vùng chứa cuộn đó và các vị trí sẽ cập nhật cho bạn.

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

Đây là lúc công suất định vị neo tăng lên. position-fallback có thể định vị phần tử cố định dựa trên một nhóm các phương án dự phòng mà bạn cung cấp. Bạn sẽ định hướng cho trình duyệt bằng các kiểu của mình và để công cụ này 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ụ mà bạn có thể lật để hiển thị bên trên hoặc bên dưới quảng cáo cố định. Hành vi này phụ thuộc vào việc liệu chú thích có bị cắt bớt theo vùng chứa của chú thích hay không. Vùng chứa đó thường là khung nhìn.

Nếu đào sâu vào mã nguồn 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 đó đã nhảy lên. Điều này xảy ra khi các neo tương ứng của chúng gần ranh giới khung nhìn. Tại thời điểm này, cửa sổ bật lên đang cố điều chỉnh để vẫn nằm trong khung nhìn.

Trước khi tạo một 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 việc lật mà không mất phí bằng cách sử dụng giá trị của auto trong cả hàm neo và thuộc tính phần lồng ghép ngược lại. 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;
}

Lựa chọn thay thế cho tính năng định vị tự động là sử dụng position-fallback rõ ràng. Việc này yêu cầu bạn phải xác định một tập hợp vị trí dự phòng. Trình duyệt sẽ đi qua các vị trí đó 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 tệp nào phù hợp, thì mặc định sẽ là tệp đầu tiên được xác định.

Một position-fallback cố gắng hiển thị chú giải công cụ ở trên rồi ở 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);
  }
}

Áp dụng cho chú giải công cụ như sau:

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

Việc sử dụng anchor-default đồng nghĩa với việc 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 một thuộc tính tuỳ chỉnh trong phạm vi để đặt anchor-default.

Hãy xem lại bản minh hoạ này về cách sử dụng thuyền. Có một tập hợp position-fallback. Khi bạn thay đổi vị trí của neo, thuyền sẽ điều chỉnh để vẫn ở bên trong vùng chứa. Hãy thử thay đổi giá trị khoảng đệm để điều chỉnh khoảng đệm nội dung. Hãy lưu ý cách trình duyệt sửa vị trí. Các vị trí sẽ đượ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 sẽ 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 đã biết các tính năng chính cho vị trí cố định, hãy cùng tìm hiểu một số ví dụ thú vị khác ngoài chú thích. Những ví dụ này nhằm mục đích truyền tải ý tưởng của bạn về cách mà bạn có thể sử dụng vị trí neo. Cách tốt nhất để hiểu rõ hơn về thông số kỹ thuật là sử dụng thông tin đầu vào từ người dùng thực tế như bạn.

Trình đơn theo bối cảnh

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

Đánh dấu không phải là phần quan trọng ở đây. Tuy nhiên, bạn có 3 nút, mỗi nút sử dụng popovertarget. Tiếp theo, bạn có 3 phần tử sử dụng thuộc tính popover. Điều đó cho phép bạn mở trình đơn theo bối cảnh mà không cần JavaScript. Mã đó có thể 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 và chia sẻ position-fallback giữa các trình đơn theo bối cảnh. Chúng ta cũng đảm bảo bạn huỷ đặt mọi kiểu inset 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 cung cấp cho bạn giao diện người dùng của trình đơn theo bối cảnh thích ứng lồng nhau. Hãy thử thay đổi vị trí nội dung bằng lựa chọn. Lựa chọn mà bạn chọn sẽ cập nhật chế độ căn chỉnh lưới. Và điều đó ảnh hưởng đến cách định vị vị trí của các 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 :has() vào. Mục đích là chuyển đổi chỉ báo trực quan cho input có tâm điểm.

Hãy làm việc này bằng cách đặt một quảng cáo cố định 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 có phạm vi đượ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;
}

Tuy nhiên, làm cách nào để bạn có thể tiếp tục thực hiện điều này? Bạn có thể sử dụng đối tượng này cho một số dạng lớp phủ hướng dẫn. 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 của chú thích đó. Bạn có thể làm mờ nội dung. Các ảnh động rời rạc cho phép bạn tạo ảnh động cho display hoặc Hiệu ứng chuyển đổi khung hiển thị có thể hoạt động tại đây.

Hàm calc trong biểu đồ thanh

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

Bạn có thể theo dõi các giá trị cao nhất và thấp nhất bằng cách sử dụng CSS minmax. CSS cho phần đó 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 hoạt động để 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, vị trí neo sẽ đảm nhận việc cập nhật bố cục cho chúng ta.

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

Bạn không nhất thiết phải chỉ neo vào một phần tử. Bạn có thể sử dụng nhiều neo cho một phần tử. Bạn có thể nhận thấy điều đó trong ví dụ về biểu đồ thanh. Những chú giải công cụ được liên kết với biểu đồ và sau đó là thanh tương ứng. Nếu nâng tầm khái niệm đó, bạn có thể sử dụng tính năng này để đổi kích thước các phần tử.

Bạn có thể coi các điểm neo này như ô điều khiển thay đổi kích thước tuỳ chỉnh và sử dụng 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 tay điều khiển có thể Draggable. Tuy nhiên, phần tử <img> sẽ đổi kích thước để lấp đầy vùng chứa và điều chỉnh cho phù hợp với khoảng trống giữa các ô điều khiển.

Chọn một Trình đơn chọn?

Phần cuối này là một phần hé lộ về những gì sắp tới. 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à hiện tại 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 bạn thực hiện 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ể có dạng như sau:

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

Kết hợp các tính năng của Popover API với định vị CSS Anchor và bạn đã hoàn thành.

Thật đơn giản khi bạn bắt đầu giới thiệu những tính năng 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 tiếp theo ở đâu? Chúng tôi cần làm gì khác để khiến select đó hoạt động được? Chúng tôi sẽ lưu câu trả lời đó trong bài viết tiếp theo. Nhưng đừng lo, các phần tử chọn lọc 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. Nó sẽ giúp bạn bớt đi một vài trong số những quyết định khó khăn đó. Ngoài ra, tính năng này cũng sẽ cho phép bạn làm những việc mà trước đây bạn chưa từng làm được. Chẳng hạn như tạo kiểu cho phần tử <select>! Hãy chia sẻ suy nghĩ của bạn.

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