8000 GitHub - toolwind/anchors: Anchors for Tailwind CSS provides a simple API for working with CSS anchor positioning, enabling flexible, declarative positioning relative to custom anchors.
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Anchors for Tailwind CSS provides a simple API for working with CSS anchor positioning, enabling flexible, declarative positioning relative to custom anchors.

License

MIT, MIT licenses found

Licenses found

MIT
LICENSE
MIT
LICENSE.md
Notifications You must be signed in to change notification settings

toolwind/anchors

Repository files navigation

Anchors for Tailwind CSSAnchors for Tailwind CSS

Anchors for Tailwind CSS is a plugin that brings declarative support for the CSS Anchor Positioning API to Tailwind CSS. It provides utilities for defining anchors (anchor-name) and positioning elements relative to them (position-anchor, position-area, anchor(), anchor-size()), as well as utilities for advanced features like conditional visibility (position-visibility) and fallback positioning (position-try-order, position-try-fallbacks).

It also lays the groundwork for using View Transitions to animate any anchored elements, which would require separate JS (for now 👀).

Installation

  1. Install the plugin from npm with your preferred package manager:

    npm install -D @toolwind/anchors
  2. Then include it in your Tailwind CSS or JS config file:

    CSS (Tailwind CSS v4+)
    /* style.css */
    @import "@toolwind/anchors";
    JS (Tailwind CSS v3 compatible)
    // tailwind.config.js
    import anchors from "@toolwind/anchors";

Usage

Defining an anchor

Use the anchor/{name} utility to define an anchor point. The CSS anchor-name property requires a dashed ident type (e.g. --my-anchor). For convenience, Anchors for Tailwind CSS automatically converts simpler ident types (e.g. my-anchor) names into dashed idents under the hood.

There are several ways to define an anchor:

  1. Use a non-dashed ident (e.g. my-anchor)

    <div class="anchor/my-anchor"></div>

    This utlity generates the below CSS, prefixed with --tw-anchor_ since CSS anchor-name property requires a dashed ident type (e.g. --my-anchor), as mentioned previously:

    .anchor\/my-anchor {
      anchor-name: --tw-anchor_my-anchor;
    }
  2. Use a dashed ident (e.g. --my-anchor)

    If you explicitly specify a dashed ident as an anchor name, this utility will preserve that dashed ident so you can re-use it elsewhere more easily.

    <div class="anchor/--my-anchor"></div>

    This will generate the following CSS:

    .anchor\/--my-anchor {
      anchor-name: --my-anchor;
    }
  3. Use an arbitrary value (e.g. [var(--x)] or [--my-anchor])

    🚧 Note that names passed via an arbitrary value (square bracket syntax) must be or resolve to a dashed ident.

    1. Include a variable reference inside an arbitrary value (e.g. [var(--x)])

      If you want to pass a name via a CSS variable, you can do so using an arbitrary value (square bracket syntax), like this:

      <div class="[--x:--my-anchor]">
        <div class="anchor/[var(--x)]"></div>
      </div>

      This will generate the following CSS:

      .anchor\/\[var\(--x\)\] {
        anchor-name: var(--x);
      }
      .\[--x\:--my-anchor\] {
        --x: var(--my-anchor);
      }

      For an even simpler syntax, take a look at the variable shorthand syntax under point 4 below.

    2. Include dashed ident inside arbitrary value (e.g. [--my-anchor])

      You can directly pass a dashed ident using the square bracket syntax:

      <div class="anchor/[--my-anchor]"></div>

      This will generate the following CSS:

      .anchor\/\[--my-anchor\] {
        anchor-name: --my-anchor;
      }

      However, while this approach works, it is equivalent to using the dashed ident syntax shown in example 2 (anchor/--my-anchor), which is simpler.

      [!WARNING] Note that Tailwind v3.x treats this syntax as differently, and will process anchor/[--my-anchor] as anchor-name: var(--my-anchor) instead of anchor-name: --my-anchor, as it uses this as the syntax for variable shorthand syntax. See point 4 below for more information.

  4. Pass a variable using variable shorthand syntax

    1. Tailwind CSS v4.x

      In Tailwind CSS v4.x and above, you can use this shorthand below instead of passing a custom property reference to an arbitrary value (square bracket syntax).

      These two utilities are equivalent, and will both produce anchor-name: var(--x):

      <div class="anchor/[var(--x)]"></div>
      <div class="anchor/(--x)"></div>

      [!IMPORTANT] This is not the same as anchor/--my-anchor or anchor/[--my-anchor], as they pass the dashed ident itself directly, where the variable shorthand syntax wraps its value in var().

    2. Tailwind CSS v3.x (≥ 3.3 and above)

      Using variable shorthand syntax in Tailwind v3.x (≥ 3.3 and above), you can use square brackets to reference CSS variables, similarly to the v4 example above, only using square brackets instead of parentheses.

      These two utilities are equivalent, and will both produce anchor-name: var(--x):

      <div class="anchor/[var(--x)]"></div>
      <div class="anchor/[--x]"></div>

      [!IMPORTANT] This behavior differs from Tailwind CSS v4 and newer, where anchor/[--x] would pass the dashed ident directly. In Tailwind CSS v3, if you want to pass the dashed ident directly without wrapping it in var(), use the dashed ident syntax shown in example 2 above.

Positioning relative to an anchor

Once an anchor has been defined, you can anchor other elements to it.

  • Anchoring: Attach an element to an anchor

    Use anchored/{name} to attach an element to an anchor:

    <div class="anchored/my-anchor"></div>
    {
      position-anchor: --tw-anchor_my-anchor;
      :where(&) {
        position: absolute;
        view-transition-name: --tw-anchor-view-transition-313d192p322r2w3336;
      }
    }
  • Positioning: Position an element relative its linked anchor

    Use anchored-{side} to specify the position area of the anchored element. For example, anchored-top-center will position the element at the top center of its anchor, touching the anchored element:

    <div class="anchored-top-center"></div>
    {
      position-area: top center;
    }
  • Shorthand: Anchor and position an element relative to an anchor

    Use anchored-{side}/{name} to combine anchoring and positioning in a single utility:

    <div class="anchored-top-center/my-anchor"></div>
    {
      position-anchor: --tw-anchor_my-anchor;
      position-area: top center;
      :where(&) {
        position: absolute;
        view-transition-name: --tw-anchor-view-transition-313d192p322r2w3336;
      }
    }

Important

A quick note on the use of :where() here:

Using :where() in a CSS selector resets the specificity of the styles declared inside that selector's block to zero, meaning they hold the lowest priority in selector matching. This makes it extremely easy for you to override these values.

Because this plugin sets both position and view-transition-name with zero specificity, you can override both of these styles with ease without having to worry about using ! (!important) on your overriding styles. making them easy to overwrite with other values, if you choose.

As a rule of thumb, anchored elements must use absolute or fixed positioning. This plugin defaults to absolute positioning, but you can add fixed to use fixed positioning instead for any anchored element.

Because of the way the view-transition-name value is encoded, it really shouldn't conflict with any of your other styles, but if you wish to opt of that being applied as well, you can simple add [view-transition-name:none] to your classes for the anchored element (alongside the anchored utility classes).

Supported Utilities

  • anchor/{name}

    Sets anchor-name

  • anchored/{name}

    Sets: position-anchor

  • anchored-{position}

    Sets position-area. Examples:

    • anchored-top-centertop center
    • anchored-bottom-span-leftbottom span-left
    • anchored-rightright
  • {top|right|bottom|left|inset}-anchor-{side}-{offset}/{name?}

    Generates explicit directional positioning using anchor():

    <div class="top-anchor-bottom"></div>

    Results in:

    top: anchor(bottom);

    With offset support:

    <div class="top-anchor-bottom-4"></div>
    top: calc(anchor(bottom) + 1rem);
  • {w|h}-anchor{-size?}/{name?}]

    Sets size utilities using anchor-size():

    • Omitting the anchor size (i.e. default size/dimension)

      w-anchorwidth: anchor-size(width)

      If a size is omitted, the size value is set to the same size on the linked anchor element for the property being set.

      For example, (w-anchor) would 8000 set width: anchor-size(), which is equivalent to width: anchor-size(width), setting the width of the anchored element equal to the width of its linked anchor.

      For further reading: anchor-size#anchor-size (MDN)

    • Declaring the anchor-size (width/height/etc.) to use as a length

      w-anchor-heightwidth: anchor-size(height)

      This example sets the anchored element's width to the height of its linked anchor element. This is useful when you want to create elements with dimensions based on different aspects of their anchor elements.

    • Setting/omitting the anchor name

      • w-anchorwidth: anchor-size(width)
      • w-anchor/--namewidth: anchor-size(--name width)
      • w-anchor/namewidth: anchor-size(--tw-anchor_name width)

      Specifying an anchor name on an anchor size utility is entirely optional when setting sizes relevant to an anchored element's linked anchor element.

      However, it only defines which anchor the element's property values should be set relative to.

      For further reading: anchor-size#anchor-size (MDN)

  • anchored-visible-* (position-visibility)

    Controls when the anchored element is visible.

    • anchored-visible-always: Always visible (default behavior if property isn't set).
    • anchored-visible-anchor: Visible only when the anchor is at least partially visible.
    • anchored-visible-no-overflow: Visible only when the anchored element does not overflow the viewport.
    • Arbitrary values: anchored-visible-[custom-value]
  • try-order-* (position-try-order)

    Sets the order for trying fallback positions.

    • try-order-normal: Tries fallbacks in the order they are defined (default).
    • try-order-w: Prioritizes fallbacks that maximize width within the viewport.
    • try-order-h: Prioritizes fallbacks that maximize height within the viewport.
    • Arbitrary values: try-order-[custom-value]
  • try-* (position-try-fallbacks)

    Defines the fallback positions to attempt.

    • try-none: No fallbacks.
    • try-flip-all: Flips horizontally, vertically, and diagonally (flip-block, flip-inline, flip-block flip-inline).
    • try-flip-x: Flips horizontally (flip-inline).
    • try-flip-y: Flips vertically (flip-block).
    • try-flip-s: Flips based on writing mode start direction (flip-start).
    • Position area values: try-top, try-bottom-left, try-left-span-top, etc. (maps to the corresponding position-area value, e.g., try-toptop).
    • Arbitrary values: try-[custom-value]

View Transition API Integration

Every anchored/{name} class includes a view-transition-name, making your anchored elements animatable with document.startViewTransition():

document.startViewTransition(() => {
  el.classList.remove('anchored-top-left')
  el.classList.add('anchored-bottom-right')
})

This animates position shifts smoothly using the browser-native View Transitions API.

Why use Anchors for Tailwind CSS? 🤔

  • Declarative anchor positioning with Tailwind utility syntax
  • Full support for native anchor-related CSS properties and functions
  • Easy offset control via calc(anchor(...) + theme spacing) (under the hood)
  • Built-in support for View Transitions
  • Fully JIT-compatible, no runtime required

Additional Resources 📚

If you liked this plugin...

Check out more by @branmcconnell:

About

Anchors for Tailwind CSS provides a simple API for working with CSS anchor positioning, enabling flexible, declarative positioning relative to custom anchors.

Resources

License

MIT, MIT licenses found

Licenses found

MIT
LICENSE
MIT
LICENSE.md

Stars

Watchers

Forks

Packages

No packages published
0