---
id: web-anchor-positioning-css
title: CSS Anchor Positioning / @scope / Speculation Rules
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [web, css, vibe-coding]
tech_stack: { language: "CSS", applicable_to: ["Frontend"] }
applied_in: []
aliases: [CSS anchor, anchor positioning, @scope, speculation rules, prerender, modern CSS]
---
# Modern CSS Features
> Floating UI / scoped CSS / prerender μ native. **Anchor (Chrome 125+), @scope (Chrome 118+), Speculation Rules (Chrome 110+)**.
## π ν΅μ¬ κ°λ
- Floating element μ native (anchor).
- CSS-in-JS μ scoped CSS native.
- Speculative prerender / preload.
## π» μ½λ ν¨ν΄
### Anchor positioning
```html
Hello
```
```css
#trigger {
anchor-name: --my-trigger;
}
.tooltip {
position: absolute;
position-anchor: --my-trigger;
top: anchor(bottom); /* λ§€ anchor μ bottom */
left: anchor(center);
/* λλ */
position-area: bottom;
}
```
β JS / Floating UI μμ΄ popover position.
### position-area (λ¨μ)
```css
.tooltip {
position-anchor: --trigger;
position-area: bottom;
}
```
β "anchor μ bottom" μ declarative.
### Try alternatives (fallback)
```css
.tooltip {
position-anchor: --trigger;
position-area: bottom;
position-try-fallbacks:
bottom right,
top left,
top right;
}
```
β Viewport edge μ λ€λ₯Έ position.
### Popover + anchor
```html
Content
```
β Popover + anchor = native modal.
### @scope (CSS scoping)
```html
```
```css
@scope (.card) {
h2 { color: blue; }
p { font-size: 14px; }
}
```
β `.card` μ λ§ μ μ©. CSS-in-JS μμ΄.
### @scope to (limit)
```css
@scope (.card) to (.card-children) {
h2 { color: blue; }
}
```
β `.card-children` μ descendant κ° μ λ°μ.
### CSS nesting (related)
```css
.card {
padding: 16px;
& h2 {
font-size: 1.5rem;
}
}
```
### Speculation Rules (prerender)
```html
```
β Hover μ prerender. Click = instant.
### Eagerness
```
- conservative: explicit only (anchor click).
- moderate: hover.
- eager: visible link.
- immediate: λ§€ link.
```
β Cost vs UX trade-off.
### Prefetch (lighter)
```html
```
β HTML / resource preload (no execute).
### Container queries
```css
.card {
container-type: inline-size;
}
@container (min-width: 400px) {
.card-content {
display: grid;
grid-template-columns: 1fr 1fr;
}
}
```
β Component μ size λ°λΌ layout.
### Container query units
```css
.card {
container-type: inline-size;
container-name: card;
}
.card h2 {
font-size: 5cqw; /* 5% of card width */
}
```
β `cqw, cqh, cqi, cqb` κ° container μ width / height.
### View timeline
```css
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
.fade {
animation: fade-in linear;
animation-timeline: view();
animation-range: entry 0% cover 30%;
}
```
β Scroll μμΉ λ°λΌ animation. JS μμ΄.
### Scroll timeline
```css
.progress {
animation: progress-bar linear;
animation-timeline: scroll();
}
@keyframes progress-bar {
from { width: 0%; }
to { width: 100%; }
}
```
β Page scroll λ°λΌ progress bar.
### Color modern
```css
:root {
--primary: oklch(0.7 0.15 270);
}
.button:hover {
background: oklch(from var(--primary) 0.6 c h); /* darker */
}
```
β OKLCH = perceptual uniform color.
### color-mix()
```css
.button {
background: color-mix(in oklch, var(--primary) 70%, white);
}
```
β Mix 2 color.
### relative colors
```css
.button:hover {
background: oklch(from var(--primary) calc(l * 0.8) c h);
}
```
β κΈ°μ‘΄ color μ lighter / darker μλ.
### :has() selector
```css
.card:has(img) {
padding-top: 0;
}
form:has(input:invalid) {
border-color: red;
}
```
β Parent κ° child λ°λΌ style. Game-changing.
### subgrid
```css
.parent {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.child {
display: grid;
grid-template-columns: subgrid;
}
```
β Child κ° parent μ grid μ¬μ©.
### Browser support
```
- Anchor: Chrome 125+, FF flag.
- @scope: Chrome 118+.
- Speculation Rules: Chrome 110+.
- Container queries: λͺ¨λ modern.
- :has(): λͺ¨λ modern.
- View Timeline: Chrome 115+.
- OKLCH: λͺ¨λ modern.
- Subgrid: λͺ¨λ modern (Safari 16+).
```
β Caniuse κ° reality.
### Polyfill / fallback
```css
.tooltip {
/* Fallback */
position: absolute;
top: 100%;
left: 50%;
/* Modern */
position-anchor: --trigger;
position-area: bottom;
}
```
β Progressive enhancement.
### Use case
```
Anchor: tooltip, popover, dropdown.
@scope: component-scoped CSS.
Speculation: navigation λΉ λ¦.
Container: responsive component.
:has(): conditional layout.
View Timeline: scroll-based animation.
```
### vs Floating UI library
```
Floating UI:
- JavaScript (3 KB).
- λͺ¨λ browser.
- μ λ° control.
Native anchor:
- 0 JS.
- Modern browser only.
- CSS declarative.
β Modern only = native.
Cross-browser = library.
```
### vs CSS-in-JS
```
CSS-in-JS:
- JavaScript runtime.
- Dynamic style.
- ν° bundle.
@scope:
- Native CSS.
- Build-time.
- μμ.
β Modern = @scope.
```
### Production examples
- **Astro / Next**: View Transitions.
- **Tailwind 4**: Lightning CSS + container.
- **Vercel docs**: Speculation Rules.
- **Apple**: scroll animation.
### LLM / Cursor λμ
```
Modern CSS κ° LLM μ baked.
- Generate anchor positioning.
- @scope μμ±.
- :has() pattern.
β μμ bundle + clean code.
```
### ν¨μ
```
- Anchor κ° Chrome λ§: fallback νμ.
- Container μ layout κ° ambiguous: type λͺ
μ.
- :has() μ performance: λ§€μ° ν° tree κ° slow.
- View Timeline μ timing μ λ° X.
- Speculation Rules cost: prerender κ° page render.
```
## π€ μμ¬κ²°μ κΈ°μ€
| μμ
| μΆμ² |
|---|---|
| Floating UI | Anchor (modern) / Floating UI |
| Component CSS | @scope |
| Page navigation | Speculation Rules |
| Responsive component | Container queries |
| Conditional layout | :has() |
| Scroll animation | View Timeline |
| Color | OKLCH |
## β μν°ν¨ν΄
- **Anchor + no fallback**: Safari κΉ¨μ§.
- **λͺ¨λ νμ΄μ§ prerender**: cost.
- **Container κ° type μ**: ignore.
- **:has() ν° tree**: performance.
- **CSS-in-JS + @scope λ λ€**: redundant.
## π€ LLM νμ© ννΈ
- Anchor positioning κ° Chrome 125+.
- @scope κ° native CSS-in-JS.
- Speculation Rules κ° prerender.
- :has() κ° game-changing parent selector.
## π κ΄λ ¨ λ¬Έμ
- [[Frontend_CSS_Modern_Features]]
- [[Frontend_Container_Queries]]
- [[Web_Origin_Trial_Platform]]