C

CSS Handbook

Clean • Professional

Anchor Positioning & Dynamic Viewports

3 minute

Anchor Positioning & Dynamic Viewports

Modern layouts need tooltips, popovers, and sticky elements to stay aligned with targets. Using the Anchor Position API with dynamic viewport units keeps them visually consistent across devices, minimizing layout shifts and enhancing UX.

Advanced Anchor Position API

The Anchor Position API (experimental, Chrome 125+, partial support elsewhere in 2025) allows elements to position themselves relative to a designated “anchor” element. This makes creating tooltips, popovers, sticky menus, and dynamically aligned elements straightforward, even during scrolling.

By linking elements directly to anchors, developers can reduce manual calculations and ensure smooth, consistent alignment.

Key Properties :

PropertyDescription
anchor-nameAssigns a unique identifier to an anchor element.
position-anchorLinks an element to a specific anchor.
inset-* (top, left, right, bottom)Positions an element relative to the anchor’s edges or center.

How It Works

  • Define an anchor using anchor-name.
  • Attach a target element to that anchor using position-anchor.
  • Use inset functions like anchor(top), anchor(bottom), or anchor(center) to place the element dynamically.
  • The element updates position automatically during scrolling, reducing layout shifts and improving UX.

Dynamic Placement & Scroll-Aware Offsets

The API supports top, bottom, left, and right placement, automatically adjusting during scroll events. This ensures elements stay aligned with anchors without extra JavaScript.

Example: Tooltip with Anchor Positioning

<span anchor-name="tooltip-anchor">Hover me</span>
<div class="tooltip">Tooltip content</div>
/* Anchor element */
[anchor-name="tooltip-anchor"] {
  cursor: pointer;
}

/* Tooltip styling */
.tooltip {
  position: absolute;
  position-anchor: tooltip-anchor;
  top: anchor(bottom);       /* Place below the anchor */
  left: anchor(center);      /* Center horizontally */
  transform: translateX(-50%);
  background: oklch(20% 0.1 200); /* Dark for contrast */
  color: white;
  padding: 5px 10px;
  border-radius: 4px;
  display: none;             /* Hidden by default */
  white-space: nowrap;
  font-size: 0.9rem;
  box-shadow: 0 2px 6px rgba(0,0,0,0.3);
}

/* Show tooltip on hover */
[anchor-name]:hover + .tooltip {
  display: block;
}

New Viewport Units

Traditional vh (viewport height) units often cause layout issues on mobile because dynamic toolbars (address bar, navigation bars) change the visible viewport height. The new viewport units solve this by providing more precise, adaptive measurements for modern responsive design.

New Units Overview

UnitDescription
lvhLarge viewport height — maximum viewport height (toolbars fully expanded).
svhSmall viewport height — minimum viewport height (toolbars collapsed).
dvhDynamic viewport height — adjusts dynamically as toolbars expand/collapse.

Browser Support (2025):

Chrome 108+, Firefox 101+, Safari 15.4+, Edge latest.

Differences from Traditional vh

  • vh: Static, may cause layout jumps on mobile (CLS).

  • lvh / svh: Stable max/min heights, do not adapt dynamically.
  • dvh: Dynamically adjusts with toolbar changes, minimizing layout shifts.

Practical Example: Full-Screen Hero Section

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dynamic Viewport Units</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <section class="hero">
        <h1>Welcome</h1>
    </section>
</body>
</html>
.hero {
    height: 100dvh; /* Adapts to dynamic viewport height */
    display: flex;
    align-items: center;
    justify-content: center;
    background: oklch(80% 0.1 200); /* Accessible background color */
}

@supports not (height: 100dvh) {
    .hero {
        height: 100vh; /* Fallback for older browsers */
    }
}

.hero h1 {
    font-size: 2rem;
    color: oklch(20% 0.05 200);
}


Article 0 of 0