sdxc

[ @sdxc/u/layout ]

anchor

Resolves an anchor() reference to a plain string — the length an inset utility needs to pin an edge to the anchor's geometry.

import { anchor } from "@sdxc/u/layout";

Quick reference

Every documented call, beside the CSS it emits.

CallCSS
u.insBs(u.anchor("tip", "bottom"))"anchor(--tip bottom)"
u.anchor("menu-button", "self-end")"anchor(--menu-button self-end)"
u.anchor("tip", "bottom", "100%")"anchor(--tip bottom, 100%)"
u.anchor("sidebar", "center", "0px")"anchor(--sidebar center, 0px)"

Examples

Basic example

Use anchor(name, side) as an inset value to pin an edge of a positioned element to a side of the element named by anchorName():

⌘S
<div mix={[relative(), center(), is(72), bs(32)]}>
	<button mix={[anchorName("save-button"), ...]}>Save</button>
	<div
		mix={[
			absolute(),
			insBs(anchor("save-button", "bottom")),
			insIs(anchor("save-button", "start")),
			mbs(2),
			p(1, 2),
			rounded("md"),
			bg("neutral.solid"),
			fg("neutral.onSolid"),
			text("xs"),
		]}
	>
		⌘S
	</div>
</div>

Placing above the anchor

Pin the block-end edge to the anchor's "top" with insBe(anchor(name, "top")) to open the element above it:

Visible to everyone
<div mix={[relative(), center(), is(72), bs(32)]}>
	<button mix={[anchorName("publish-button"), ...]}>Publish</button>
	<div
		mix={[
			absolute(),
			insBe(anchor("publish-button", "top")),
			insIs(anchor("publish-button", "start")),
			mbe(2),
			p(1, 2),
			rounded("md"),
			bg("neutral.solid"),
			fg("neutral.onSolid"),
			text("xs"),
			nowrap(),
		]}
	>
		Visible to everyone
	</div>
</div>

Aligning to the end edge

Use logical sides like "start" and "end" to line edges up in the writing direction, here keeping a wide menu flush with its button's end:

  • Profile
  • Billing
  • Sign out
<div mix={[relative(), flex(), items("start"), justify("end"), is(80), bs(44)]}>
	<button mix={[anchorName("account-menu"), ...]}>Account</button>
	<ul
		mix={[
			absolute(),
			insBs(anchor("account-menu", "bottom")),
			insIe(anchor("account-menu", "end")),
			is(48),
			mbs(2),
			mbe(0),
			listStyle("none"),
			...,
		]}
	>
		<li>Profile</li>
		<li>Billing</li>
		<li>Sign out</li>
	</ul>
</div>

Applying on a state

Wrap the call in a state utility to scope it to one selector.

u.hover(u.insBs(u.anchor("tip", "bottom")))

Responsive design

Wrap the call in a container query to scope it to one width.

u.at("md", u.insBs(u.anchor("tip", "bottom")))

Signature

u.anchor(name: string, side: AnchorSide, fallback?: string)

Written by Sergio Xalambrí. Follow @sergiodxa for new packages, or sponsor the work.