Say why the FAB menu's exit rule wins inside the layer

Plan step 36. fab-menu.css claimed the item sets no translate or opacity
of its own once it has entered; fab-menu-item.css sets both at rest, and
the closing rule wins on specificity, which the header now says.
fab-menu-item.css named the rule by the root's hook instead of the
popover's, and a render test named for the list's scroll asserted the
exit; it is named for what it checks.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-14 17:09:58 +02:00
co-authored by Claude Opus 5
parent 97ba035b68
commit 3b47ebf028
3 changed files with 6 additions and 5 deletions
+1 -1
View File
@@ -7,7 +7,7 @@
* container.
*
* The entry is `@starting-style` on the item itself; the exit needs the state to be readable
* while the popover is on its way out, which `[data-md-fab-menu]:not(:popover-open) > *`
* while the popover is on its way out, which `[data-md-fab-menu-popover]:not(:popover-open) > *`
* (fab-menu.css) drives from the popover's own open state — the popover keeps `display: flex` for
* the length of its own discrete transition, so the item has somewhere to animate to (ACT-33).
*/
+4 -3
View File
@@ -13,9 +13,10 @@
* entry is `@starting-style` on the item itself; the exit needs the state to be readable while the
* popover is on its way out, which `[data-md-fab-menu-popover]:not(:popover-open) > *` is — the
* popover keeps `display: flex` for the length of its own discrete transition, so the items have
* somewhere to animate to (ACT-33). Unlayered would beat an item's own declarations, but nothing
* here needs to: the item sets no `translate`/`opacity` of its own once it has entered, so this
* rule, inside the layer, is what always wins while the popover is closed.
* somewhere to animate to (ACT-33). The Tailwind-era rule sat outside the layers to beat the
* item's utilities; inside the layer it still beats fab-menu-item.css's resting `translate: 0 0`
* and `opacity: 1`, on specificity — an attribute and a pseudo-class against the item's one
* attribute — whichever order the two files are bundled in.
*/
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
+1 -1
View File
@@ -65,7 +65,7 @@ it('opens at the corner asked for, secondary and tertiary in their own colours',
]);
});
it('scrolls the list on a short window, behind the close button, which stays fixed', function () {
it('sinks the items back while the list closes, from the popover\'s own open state', function () {
expect(ComponentStylesheet::read('fab-menu')->declarations('[data-md-fab-menu-popover]:not(:popover-open) > *'))->toBe([
'translate' => '0 var(--md-sys-measurement-space100)',
'opacity' => '0',