Skip to content

Commit c66925a

Browse files
committed
[css-anchor-position] First draft of animation support, and interleaving concept. #9598
1 parent 0b132f3 commit c66925a

File tree

1 file changed

+192
-4
lines changed

1 file changed

+192
-4
lines changed

css-anchor-position-1/Overview.bs

Lines changed: 192 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Abstract: This specification defines 'anchor positioning', where a positioned el
1515
</pre>
1616

1717
<pre class=link-defaults>
18+
spec:css-backgrounds-3; type:property; text:border-color
1819
spec:css-break-4; type:dfn; text:fragment
1920
spec:css-display-3; type:dfn; text:element
2021
spec:css-position-3;
@@ -1427,7 +1428,7 @@ it iterates the [=position options list=],
14271428
applying each [=position option's=] styles over the element's base styles,
14281429
and attempts to find an option that avoids overflow.
14291430

1430-
These modified styles are applied to the element via [=style interleaving=],
1431+
These modified styles are applied to the element via [=interleaving=],
14311432
so they affect [=computed values=]
14321433
(and can trigger transitions/etc)
14331434
even tho they depend on layout and [=used values=].
@@ -1445,7 +1446,7 @@ as part of a theoretical UA-controlled final cascade layer.
14451446
2. Return |el|'s [=used value|used styles=].
14461447
</div>
14471448

1448-
<div algorithm>
1449+
<div algorithm="determine the position fallback styles">
14491450
To <dfn>determine the position fallback styles</dfn> of an element |el|:
14501451

14511452
1. Let |base styles| be the current used styles of |el|.
@@ -1468,7 +1469,7 @@ as part of a theoretical UA-controlled final cascade layer.
14681469
and |el rect| is not fully contained within it,
14691470
[=iteration/continue=].
14701471

1471-
5. Set |option| as |el|'s [=last successful position option=].
1472+
5. Set |option| as |el|'s <dfn>last successful position option</dfn>.
14721473
Return |adjusted styles|.
14731474

14741475
3. Assert: The previous step finished without finding a [=position option=]
@@ -1489,6 +1490,9 @@ as part of a theoretical UA-controlled final cascade layer.
14891490
Issue: Make sure the snapshotted scroll offset stuff is correct now,
14901491
given interleaving.
14911492

1493+
Issue: Add conditions for forgetting the [=last successful position option=],
1494+
similar to the [=last remembered size=]
1495+
14921496
The styles returned by [=determining the position fallback styles=]
14931497
are taken as the final values for the specified properties.
14941498

@@ -1583,6 +1587,159 @@ This limit must be <em>at least</em> five.
15831587
</div>
15841588

15851589

1590+
<!-- Big Text: anim
1591+
1592+
███▌ █ █▌ ████ █ █
1593+
▐█ ▐█ █▌ █▌ ▐▌ ██ ██
1594+
█▌ █▌ ██▌ █▌ ▐▌ █▌█ █▐█
1595+
█▌ █▌ █▌▐█ █▌ ▐▌ █▌ █ ▐█
1596+
█████▌ █▌ ██▌ ▐▌ █▌ ▐█
1597+
█▌ █▌ █▌ █▌ ▐▌ █▌ ▐█
1598+
█▌ █▌ █▌ ▐▌ ████ █▌ ▐█
1599+
-->
1600+
1601+
Animating Position {#animating}
1602+
==================
1603+
1604+
<pre class=propdef>
1605+
Name: position-animation
1606+
Value: normal | magic
1607+
Initial: normal
1608+
Percentages: n/a
1609+
Inherited: no
1610+
Computed Value: ''position-animation/normal'', or an [=overriding position rectangle=] (see prose)
1611+
Animation type: (see prose)
1612+
Applies to: [=absolutely positioned elements=]
1613+
</pre>
1614+
1615+
An [=absolutely positioned box=]'s position and size
1616+
are the result of multiple properties interacting,
1617+
and this interaction is non-linear,
1618+
so smoothly animating from one position to another
1619+
can't be accomplished by animating the individual properties independently.
1620+
1621+
The 'position-animation' property resolves this conundrum,
1622+
by representing the final result of applying these properties
1623+
as a <dfn>overriding position rectangle</dfn>:
1624+
a width, height, [=x-axis=] offset, and [=y-axis=] offset.
1625+
The width and height represent the size of its [=margin box=],
1626+
and the x and y offsets represent its position
1627+
relative to its [=containing block=],
1628+
after <a href="https://www.w3.org/TR/css-position/">positioning</a>/<a href="https://www.w3.org/TR/css-align/">alignment</a>/etc.
1629+
have been performed.
1630+
1631+
If the element is not [=absolutely positioned=],
1632+
this property has no effect.
1633+
1634+
Values are:
1635+
1636+
<dl dfn-type=value dfn-for=position-animation>
1637+
: <dfn>normal</dfn>
1638+
::
1639+
This value has no effect.
1640+
1641+
: <dfn>magic</dfn> (name to be bikeshedded)
1642+
::
1643+
At [=computed value=] time,
1644+
resolves to a [=overriding position rectangle=],
1645+
using [=interleaving=].
1646+
1647+
At [=used value=] time,
1648+
overrides the position and size of the element's [=margin box=],
1649+
setting it to match the computed [=overriding position rectangle=].
1650+
</dl>
1651+
1652+
The ''position-animation/magic'' value always serializes as <css>magic</css>;
1653+
the [=overriding position rectangle=] is not observable in any way.
1654+
1655+
Interpolating to or from ''position-animation/normal''
1656+
is done as a discrete step,
1657+
where values of <var ignore>p</var> between 0 and 1 map to ''position-animation/normal'',
1658+
and other values of <var ignore>p</var> map to the closer endpoint.
1659+
<span class=note>(Similar to 'visibility'.)</span>
1660+
1661+
Two [=overriding position rectangles=] are interpolated
1662+
by interpolating the width, height, x offset, and y offset independently
1663+
as [=computed lengths=].
1664+
1665+
Issue: Should the x/y offset be relative to the top/left corner or (CB) center to (AbsPos) center or something else?
1666+
1667+
Note: The [=overriding position rectangle=] is not directly exposed,
1668+
because it functionally allows overriding the entire cascade;
1669+
the [=overriding position rectangle=] causes the element
1670+
to ignore all the other positioning properties,
1671+
regardless of where they come from.
1672+
The rectangle can nevertheless be <em>read</em> by authors
1673+
using existing JS APIs (such as {{Element/getBoundingClientRect()}}).
1674+
1675+
<div class=example>
1676+
Given a change in positioning properties like:
1677+
1678+
<pre highlight=css>
1679+
p.start {
1680+
top: 0px;
1681+
bottom: 100px;
1682+
align-self: start;
1683+
}
1684+
p.end {
1685+
top: 100px;
1686+
bottom: 50px;
1687+
align-self: end;
1688+
}
1689+
</pre>
1690+
1691+
The following causes a smooth animation between the two endpoints:
1692+
1693+
<pre highlight=css>
1694+
p {
1695+
transition: position-animation 2s; /* magic transition yay */
1696+
position-animation: magic;
1697+
}
1698+
</pre>
1699+
1700+
This doesn't smoothly animate
1701+
(you get the "constantly recomputed,
1702+
triggering fresh transitions every frame" effect
1703+
that occurs if you transition 'color' and 'border-color',
1704+
using ''border-color:currentcolor''):
1705+
1706+
<pre highlight=css>
1707+
p {
1708+
transition: position-animation 2s, inset 2s; /* sadface */
1709+
}
1710+
</pre>
1711+
</div>
1712+
1713+
<div class=issue>
1714+
Need a way to force <em>animations</em> to work correctly as well,
1715+
like:
1716+
1717+
<pre highlight=css>
1718+
p {
1719+
position-animation: magic;
1720+
animation: foo 2s;
1721+
}
1722+
1723+
@keyframes foo {
1724+
to {
1725+
top: 0px;
1726+
bottom: 100px;
1727+
align-self: start;
1728+
}
1729+
from {
1730+
top: 100px;
1731+
bottom: 50px;
1732+
align-self: end;
1733+
}
1734+
}
1735+
</pre>
1736+
1737+
Without some sort of magic intercept of animations
1738+
(forcing them to turn into a 'position-animation' animation)
1739+
this will not smoothly animate.
1740+
</div>
1741+
1742+
15861743

15871744
<!-- Big Text: cssom
15881745

@@ -1618,11 +1775,42 @@ represents the name declared in the rule's prelude.
16181775
Its <dfn attribute for=CSSPositionTryRule>style</dfn> attribute
16191776
represents the styles declared in the rule's body,
16201777
in the specified order.
1621-
Only the [=allowed @position-try properties=] are valid in this rule.
1778+
Only the [=accepted @position-try properties=] are valid in this rule.
16221779

16231780
Issue: match the concept of validity to whatever we do in similar situations.
16241781

16251782

1783+
<h2 id=interleaving>
1784+
Appendix: Style & Layout Interleaving</h2>
1785+
1786+
<dfn export lt="style & layout interleave" local-lt="interleave">Style & layout interleaving</dfn> is a technique
1787+
where a style update can occur on a subtree
1788+
during the layout process,
1789+
resulting in retroactive updates
1790+
to elements’ [=computed value|computed styles=].
1791+
1792+
Issue: This is not the correct spec for this concept,
1793+
it should probably go in <a href="https://www.w3.org/TR/css-cascade/">Cascade</a>,
1794+
but I need a sketch of it to refer to.
1795+
1796+
Note: [=Style & layout interleaving=] is already used with [=container queries=]
1797+
and [=container query lengths=].
1798+
A length like ''10cqw'' is resolved into a [=computed length=]
1799+
using layout information about the query container's size,
1800+
which can thus trigger <a href="https://www.w3.org/TR/css-transitions-1/">transitions</a>
1801+
when the container changes size between layouts.
1802+
1803+
An [=absolutely positioned box=]'s [=overriding position rectangle=]
1804+
(see 'position-animation')
1805+
is determined by [=style & layout interleaving=].
1806+
The [=accepted @position-try properties=] are also [=interleaved=]
1807+
when resolving fallback
1808+
(see 'position-try').
1809+
1810+
Issue: Obviously this needs way more details filled in,
1811+
but for now "act like you already do for container queries" suffices.
1812+
That behavior is also undefined,
1813+
but at least it's interoperable (to some extent?).
16261814

16271815

16281816
Security Considerations {#sec}

0 commit comments

Comments
 (0)