Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove implicit anchors, as they are not yet supported in the spec #272

Merged
merged 6 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,6 @@ manually, by passing a single boolean with `polyfill(true)`.

## Limitations

This polyfill was implemented against an early version of the spec, and updates
were paused to allow the syntax to solidify. Now that browsers are working on
implementation, we are in the process of bringing it up to date.

While this polyfill supports many basic use cases, it doesn't (yet) support the
following features:

Expand All @@ -142,16 +138,16 @@ following features:
- `position-area` property
- `anchor-center` value for `justify-self`, `align-self`, `justify-items`, and
`align-items` properties
- anchor functions with `implicit` anchor-element
- automatic anchor positioning: anchor functions with `inside` or `outside`
anchor-side
- `position-visibility` property
- dynamically added/removed anchors or targets
- anchors or targets in the shadow-dom
- anchors or targets in constructed stylesheets (https://github.com/oddbird/css-anchor-positioning/issues/228)
- anchor functions assigned to `inset-*` properties or `inset` shorthand
property
- vertical/rtl writing-modes (partial support)
- implicit anchors or the `position-anchor: auto` keyword (pending resolution of
https://github.com/whatwg/html/pull/9144)

In addition, JS APIs like `CSSPositionTryRule` or `CSS.supports` will not be
polyfilled.
Expand Down
78 changes: 24 additions & 54 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
</script>
<link rel="stylesheet" href="/demo.css" />

<!-- Included to test invalid stylesheets -->
<link rel="stylesheet" href="/fake.css" />
<link rel="stylesheet" href="/anchor.css" />
<link rel="stylesheet" href="/anchor-positioning.css" />
<link rel="stylesheet" href="/anchor-popover.css" />
Expand All @@ -39,12 +37,13 @@
<link rel="stylesheet" href="/anchor-name-list.css" />
<link rel="stylesheet" href="/anchor-custom-props.css" />
<link rel="stylesheet" href="/anchor-duplicate-custom-props.css" />
<link rel="stylesheet" href="/anchor-implicit.css" />
<link rel="stylesheet" href="/anchor-update.css" />
<link rel="stylesheet" href="/anchor-absolute.css" />
<link rel="stylesheet" href="/anchor-pseudo-element.css" />
<link rel="stylesheet" href="/anchor-media-query.css" />
<link rel="stylesheet" href="/anchor-scope.css" />
<!-- Included to test invalid stylesheets -->
<link rel="stylesheet" href="/fake.css" />
<style>
#my-anchor-style-tag {
anchor-name: --my-anchor-style-tag;
Expand Down Expand Up @@ -263,9 +262,9 @@ <h2>Anchoring Elements Using CSS</h2>
rel="noopener noreferrer"
>specification</a
>
defines anchor positioning, "where a positioned element can size and
position itself relative to one or more 'anchor elements' elsewhere on
the page." This CSS Anchor Positioning Polyfill supports and is based on
defines anchor positioning, where a positioned element can size and
position itself relative to one or more anchor elements elsewhere on
the page. This CSS Anchor Positioning Polyfill supports and is based on
this specification.
</p>
<p>
Expand Down Expand Up @@ -320,10 +319,8 @@ <h2>Anchoring Elements Using CSS</h2>
</li>
</ul>
<p>
<strong>Note: </strong>This polyfill was implemented against an early
version of the spec, and updates were paused to allow the syntax to
solidify. Now that browsers are working on implementation, we are in the
process of bringing it up to date, and welcome
<strong>Note: </strong>We strive to keep the polyfill up-to-date with
ongoing changes to the spec, and we welcome
<a
href="https://github.com/oddbird/css-anchor-positioning"
target="_blank"
Expand All @@ -343,7 +340,7 @@ <h2>
<div id="my-anchor-positioning" class="anchor">Anchor</div>
</div>
<p class="note">
With polyfill applied: Target and Anchor's right edges line up. Target's
With polyfill applied: Target and Anchors right edges line up. Targets
top edge lines up with the bottom edge of the Anchor.
</p>
<pre><code class="language-css"
Expand Down Expand Up @@ -409,7 +406,7 @@ <h2>
</div>
</div>
<p class="note">
With polyfill applied: Target and Anchor's right edges line up. Target's
With polyfill applied: Target and Anchors right edges line up. Targets
top edge lines up with the bottom edge of the Anchor.
</p>
<pre><code class="language-css"
Expand All @@ -426,33 +423,6 @@ <h2>
top: anchor(--my-anchor-in-line bottom);
right: anchor(--my-anchor-in-line right);
"</code></pre>
</section>
<section id="implicit-name" class="demo-item">
<h2>
<a href="#implicit-name" aria-hidden="true">🔗</a>
Positioning with <code>anchor()</code> [implicit
<code>anchor</code> attribute]
</h2>
<div style="position: relative" class="demo-elements">
<div id="my-implicit-anchor" class="anchor">Anchor</div>
<div id="my-implicit-target" class="target" anchor="my-implicit-anchor">
Target
</div>
</div>
<p class="note">
With polyfill applied: Target is positioned at the top left corner of
the Anchor.
</p>
<pre><code class="language-html"
>&lt;div id="my-implicit-anchor"&gt;Anchor&lt;/div&gt;
&lt;div id="my-implicit-target" anchor="my-implicit-anchor"&gt;Target&lt;/div&gt;</code>

<code class="language-css"
>#my-implicit-target {
position: absolute;
right: anchor(implicit left);
bottom: anchor(top);
}</code></pre>
</section>
<section id="position-anchor" class="demo-item">
<h2>
Expand Down Expand Up @@ -861,7 +831,7 @@ <h2>
<div id="my-target-math" class="target">Target</div>
</div>
<p class="note">
With polyfill applied: Target's left edge is 10px left of the Anchor's
With polyfill applied: Targets left edge is 10px left of the Anchors
right edge). The top edge of the Target is 10px below the bottom edge of
the Anchor.
</p>
Expand Down Expand Up @@ -890,9 +860,9 @@ <h2>
<div id="my-target" class="target">Target</div>
</div>
<p class="note">
With polyfill applied: Target's top edge is positioned at 50% of the
With polyfill applied: Targets top edge is positioned at 50% of the
height of the Anchor. The right edge of the Target lines up with 100% of
the width of the Anchor (i.e. the Anchor's right edge).
the width of the Anchor (i.e. the Anchors right edge).
</p>
<pre><code class="language-css"
>#my-anchor {
Expand All @@ -919,8 +889,8 @@ <h2>
<div id="my-target-props" class="target">Target</div>
</div>
<p class="note">
With polyfill applied: Target's left edge is positioned in Anchor's
horizontal center. Target's bottom edge is 10% above the bottom edge of
With polyfill applied: Targets left edge is positioned in Anchors
horizontal center. Targets bottom edge is 10% above the bottom edge of
Anchor.
</p>
<pre><code class="language-css"
Expand Down Expand Up @@ -949,7 +919,7 @@ <h2>
<div id="target-duplicate-custom-props" class="target">Target</div>
</div>
<p class="note">
With polyfill applied: Target's top left corner is positioned in the
With polyfill applied: Targets top left corner is positioned in the
center (vertically and horizontally) of the Anchor.
</p>
<pre><code class="language-css"
Expand Down Expand Up @@ -1002,7 +972,7 @@ <h2>
</div>
<button id="toggle-anchor-width">Toggle anchor width</button>
<p class="note">
With polyfill applied: Target and Anchor's right edges line up. Target's
With polyfill applied: Target and Anchors right edges line up. Targets
top edge lines up with the bottom edge of the Anchor.
<br />
<br />
Expand Down Expand Up @@ -1031,8 +1001,8 @@ <h2>
<div id="my-target-name-list-b" class="target">Target B</div>
</div>
<p class="note">
With polyfill applied: Target A is positioned at Anchor's top left
corner. Target B is positioned at Anchor's bottom right corner.
With polyfill applied: Target A is positioned at Anchors top left
corner. Target B is positioned at Anchors bottom right corner.
</p>
<pre><code class="language-css"
>#my-anchor-name-list {
Expand Down Expand Up @@ -1098,7 +1068,7 @@ <h2>
<div id="my-target-pseudo-element" class="target">Target</div>
</div>
<p class="note">
Target is positioned at the bottom right corner of the Anchor's
Target is positioned at the bottom right corner of the Anchors
<code>::before</code> pseudo-element.
</p>
<pre><code class="language-css"
Expand All @@ -1125,7 +1095,7 @@ <h2>
<div id="my-target-media-query" class="target">Target</div>
</div>
<p class="note">
With polyfill applied: Target and Screen Anchor's right and top edges
With polyfill applied: Target and Screen Anchors right and top edges
line up.
</p>
<pre><code class="language-css"
Expand Down Expand Up @@ -1256,7 +1226,7 @@ <h2>
</div>
<p class="note">
With polyfill applied: Targets are positioned to the right of their
corresponding item's arrow.
corresponding items arrow.
</p>
<pre><code class="language-css">#anchor-scope li {
anchor-scope: --anchor-scope;
Expand All @@ -1274,10 +1244,10 @@ <h2>
}</code></pre>
</section>
<section id="sponsor">
<h2>Sponsor OddBird's OSS Work</h2>
<h2>Sponsor OddBirds OSS Work</h2>
<p>
At OddBird, we love contributing to the languages & tools developers
rely on. We're currently working on polyfills for new Popover & Anchor
rely on. Were currently working on polyfills for new Popover & Anchor
Positioning functionality, as well as CSS specifications for functions,
mixins, and responsive typography. Help us keep this work sustainable
and centered on your needs as a developer! We display sponsor logos and
Expand All @@ -1293,7 +1263,7 @@ <h2>Sponsor OddBird's OSS Work</h2>
href="https://github.com/sponsors/oddbird"
target="_blank"
rel="noopener noreferrer"
>Sponsor OddBird's OSS Work</a
>Sponsor OddBirds OSS Work</a
>
</section>
<footer>
Expand Down
5 changes: 0 additions & 5 deletions public/anchor-implicit.css

This file was deleted.

20 changes: 3 additions & 17 deletions src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,9 @@ function parseAnchorFn(
name = undefined;
}
if (name) {
if (isIdentifier(name)) {
if (name.name === 'implicit') {
name = undefined;
} else if (name.name.startsWith('--')) {
// Store anchor name
anchorName = name.name;
}
if (isIdentifier(name) && name.name.startsWith('--')) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was hesitant to combine these ifs, as it subtly changes the logic, but it ends up not making a difference, so it makes sense to combine.

// Store anchor name
anchorName = name.name;
} else if (isVarFunction(name) && name.children.first) {
// Store CSS custom prop for anchor name
customPropName = (name.children.first as csstree.Identifier).name;
Expand Down Expand Up @@ -255,7 +251,6 @@ async function getAnchorEl(
let anchorName = anchorObj.anchorName;
const customPropName = anchorObj.customPropName;
if (targetEl && !anchorName) {
const anchorAttr = targetEl.getAttribute('anchor');
const positionAnchorProperty = getCSSPropertyValue(
targetEl,
'position-anchor',
Expand All @@ -265,15 +260,6 @@ async function getAnchorEl(
anchorName = positionAnchorProperty;
} else if (customPropName) {
anchorName = getCSSPropertyValue(targetEl, customPropName);
} else if (anchorAttr) {
const elementPart = `#${CSS.escape(anchorAttr)}`;

return await validatedForPositioning(
targetEl,
null,
[{ selector: elementPart, elementPart }],
[],
);
}
}
const anchorSelectors = anchorName ? anchorNames[anchorName] || [] : [];
Expand Down
39 changes: 0 additions & 39 deletions tests/unit/parse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,45 +61,6 @@ describe('parseCSS', () => {
expect(rules).toEqual(expected);
});

it('parses `anchor()` (implicit name via `anchor` attr)', async () => {
document.body.innerHTML =
'<div style="position: relative"><div id="my-implicit-anchor"></div>' +
'<div id="my-implicit-target" anchor="my-implicit-anchor"></div></div>';
const css = getSampleCSS('anchor-implicit');
document.head.innerHTML = `<style>${css}</style>`;
const { rules } = await parseCSS([{ css }] as StyleData[]);
const expected = {
'#my-implicit-target': {
declarations: {
right: [
{
anchorName: undefined,
customPropName: undefined,
anchorEl: document.getElementById('my-implicit-anchor'),
targetEl: document.getElementById('my-implicit-target'),
anchorSide: 'left',
fallbackValue: '0px',
uuid: expect.any(String),
},
],
bottom: [
{
anchorName: undefined,
customPropName: undefined,
anchorEl: document.getElementById('my-implicit-anchor'),
targetEl: document.getElementById('my-implicit-target'),
anchorSide: 'top',
fallbackValue: '0px',
uuid: expect.any(String),
},
],
},
},
};

expect(rules).toEqual(expected);
});

it('parses `anchor()` (name set via custom property)', async () => {
document.body.innerHTML =
'<div style="position: relative"><div id="my-target-name-prop"></div>' +
Expand Down
Loading