<div class="controls">
<fieldset>Inline</fieldset>
<label> Left :
<input type="radio" name="position-inline" value="left" checked />
</label>
<label> Center :
<input type="radio" name="position-inline" value="center" />
</label>
<label> Right :
<input type="radio" name="position-inline" value="right" />
</label>
<fieldset>Block</fieldset>
<label> Top :
<input type="radio" name="position-block" value="top" checked />
</label>
<label> Center :
<input type="radio" name="position-block" value="center" />
</label>
<label> Bottom :
<input type="radio" name="position-block" value="bottom" />
</label>
</div>
<div>
<button class="open anchor">Anchor
</button>
<article class="anchor-positioned top-left" style="--position-inline: right;--position-block: bottom;">
top-left
</article>
<article class="anchor-positioned top-right" style="--position-inline: left;--position-block: bottom;">
top-right*
</article>
<article class="anchor-positioned bottom-right" style="--position-inline: left;--position-block: top;">
bottom-right*
</article>
<article class="anchor-positioned bottom-left" style="--position-inline: right;--position-block: top;">
bottom-left*
</article>
</div>
<span class="note">* Anchor point position</span>
@layer base, demo;
@layer demo {
.anchor {
anchor-name: --myAnchor;
}
.anchor-positioned {
position: absolute;
position-anchor: --myAnchor;
&.top-left {
top: anchor(var(--position-block));
left: anchor(var(--position-inline));
}
&.top-right {
top: anchor(var(--position-block));
right: anchor(var(--position-inline));
}
&.bottom-right {
bottom: anchor(var(--position-block));
right: anchor(var(--position-inline));
}
&.bottom-left {
bottom: anchor(var(--position-block));
left: anchor(var(--position-inline));
}
}
}
@layer base {
body {
font-family: -apple-system, BlinkMacSystemFont, system-ui, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Open Sans, Helvetica Neue, sans-serif;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
min-height: 100svh;
background: hsl(0 0% 6%);
gap: 2rem;
}
body::before {
--line: hsl(0 0% 95% / 0.35);
content: "";
height: 100vh;
width: 100vw;
position: fixed;
background: linear-gradient(90deg, var(--line) 1px, transparent 1px 10vmin)
0 -5vmin / 10vmin 10vmin,
linear-gradient(var(--line) 1px, transparent 1px 10vmin) 0 -5vmin / 10vmin
10vmin;
mask: radial-gradient(
ellipse at 50% 50%,
rgba(255, 255, 255, 1) 0%,
rgba(255, 255, 255, 0) 70%
);
top: 0;
z-index: -1;
}
*:not(dialog) {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.open {
padding: 1rem;
background: orange;
width: 300px;
height: 300px;
border: 1px white dashed;
}
.anchor-positioned {
background-color: rgba(0, 255, 255, 0.8);
padding: 1rem;
width: fit-content;
position: relative;
border: dashed 1px white;
&::after {
content: "";
position: absolute;
width: 6px;
height: 6px;
border-radius: 100vmax;
background-color: red;
}
&.top-left::after {
top: 0;
left: 0;
transform: translate(-50%, -50%);
}
&.top-right::after {
top: 0;
right: 0;
transform: translate(50%, -50%);
}
&.bottom-right::after {
bottom: 0;
right: 0;
transform: translate(50%, 50%);
}
&.bottom-left::after {
bottom: 0;
left: 0;
transform: translate(-50%, 50%);
}
}
.controls {
background-color: white;
position: absolute;
right: 0;
top: 0;
display: grid;
padding: 1rem;
gap: 1rem;
}
.note {
color: red;
}
}
const radiosInline = document.querySelectorAll('input[name="position-inline"]');
const radiosBlock = document.querySelectorAll('input[name="position-block"]');
const anchorsPositioned = document.querySelectorAll(".anchor-positioned");
[...radiosInline].forEach((radio) => {
radio.addEventListener("input", (e) => {
[...anchorsPositioned].forEach((anchorPositioned) => {
anchorPositioned.style.setProperty("--position-inline", e.target.value);
anchorPositioned.style.setProperty(
"--position-block",
document.querySelector('input[name="position-block"]:checked').value
);
});
});
});
[...radiosBlock].forEach((radio) => {
radio.addEventListener("input", (e) => {
[...anchorsPositioned].forEach((anchorPositioned) => {
anchorPositioned.style.setProperty("--position-block", e.target.value);
anchorPositioned.style.setProperty(
"--position-inline",
document.querySelector('input[name="position-inline"]:checked').value
);
});
});
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.