-
Notifications
You must be signed in to change notification settings - Fork 682
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
Proposal: Expose Pointer Position Information on Hovered Elements #6733
Comments
Starting with
Also, sometimes you use Then, pseudo-classes are just a way to select elements. They shouldn't which CSS features you can use in these elements. I don't think there is a clear choice for the coordinates, either. You mention center of the box, but that could even change depending on whether we consider the content area, padding area, border area... Note that saying that -1 is the left, 0 is the center, and 1 is the right doesn't imply that the range of values is [-1,1]. Because an element can be hovered when the pointer is outside of its border area (in front of an overflowing descendant). Also, I guess that most usecases would need the sizes of the element. Or want the coordinates with respect to the screen, or the containing block. Overall, it seems to me that this is better fitted for JS. |
Yeah, this isn't a
So this could be done, just as a new pair of functions, for x and y, that each returned a |
Ah yes. Started off with Custom Properties in my explorations, and then worked my way back to something proposal-y which uses Env Vars but forgot to remove the
In the part where I compare the various coordinate systems I indeed use
Oh, that I did not know. This would indeed make env vars not part of a possible solution here.
I started off from hover and built from there. I'm sure WG has better solutions to this that align with all other existing things :)
Time for a new function? j/k 🙃
In my experimentation I found that "percentage expressed as a float" hit the sweet spot:
Could of course be that I'm overlooking things here. |
Are TiltJS/Atropos the only usecases you see this working for or do you feel there might be something else also? |
@mystrdat I've mentioned some use-cases in the OP:
Another thing that came to mind is these two-up image comparison things, but then using hover. |
Since we can nowadays define alternative animation timelines with @property --pointer-x { … }
@property --pointer-y { … }
@keyframes track-x-value {
from { --pointer-x: -1; }
to { --pointer-y: 1; }
}
@keyframes track-y-value {
from { --pointer-y: -1; }
to { --pointer-y: 1; }
}
el {
animation: track-x-value auto linear, track-y-value auto linear;
animation-timeline: hover(vertical), hover(horizontal); /* 👈 THIS */
transform: rotate3d(
var(--pointer-y),
var(--pointer-x),
0,
-15deg
);
} See https://codepen.io/bramus/full/porJLgR for a demo that could be simplified using this. /cc @ydaniv who was interested in this type of timeline. |
Thanks, @bramus! I think we may need a new :root {
hover-timeline: --hover-x x;
} |
There have been a lot of cases where I used JS strictly to get the pointer position & store it in First that comes to mind is this entry & exit aware button I also came across this mouse mask effect, which relies on JS for other things as well, but can be reduced to a version that only needs the relative position of the cursor. |
Would this offer a CSS only solution for menu safe triangles too? |
I suspect you'd still need JavaScript to run the logic for the safe area? Fwiw we've been discussing a native safe area mechanism for popovers and interest based triggering (e.g. hover) in OpenUI openui/open-ui#963 |
I was thinking of using an As for syntax it almost feels like this should be wrapped in with anchor somehow. div {
/* Coordinates that indicate the center of the element */
anchor-name: --pointer;
background: transparent radial-gradient(25vw 25vw at calc(((anchor(--pointer pointer-x) / 2) + 0.5) * 100%)
/* ❌ Values need to be manually divided by 2 and be offset by 0.5 due to origins of background (which uses PCS) not aligning with XYCS */
calc((-1 * (anchor(--pointer pointer-y)/ 2) + 0.5) * 100%),
lightblue,
rebeccapurple) no-repeat 0 0;
transform: rotate3d(anchor(--pointer pointer-y),
/* ✅ Values can be used directly */
anchor(--pointer pointer-x),
0,
-15deg);
} (Which after writing this I see is already discussed in #8639) |
Some more recent demos where authors use the pointer position: |
Introduction
To implement effects based on the Pointer's position relative to the hovered element, one needs to resort to JavaScript. See example libraries like Tilt.js, Atropos, etc. that provide this functionality.
I would like CSS to have this ability built in: i.e. have CSS use the Pointer's position, without needing to rely on JavaScript nor a clever but nasty hack that relies on injecting a few 100 extra elements.
This position information could be used for 3D effects, popover information boxes, Houdini code that takes the mouse position as input, etc.
Proposed Solution
The proposed solution is two-fold:
I came up with these:
:hover-3d
pseudo-class--pointer-x
: X-position of the pointer--pointer-y
: Y-position of the pointer--pointer-angle
: Angle from the Origin to the Pointer Position--pointer-distance
: Distance from the Origin to the Pointer PositionSyntax
Demo
Here's a demo that exposes the 4 proposed env vars as Custom Properties, to see what you can do with them
https://codepen.io/bramus/full/porJLgR/250186328bafbb5e63bb1a6f6f2ada044
Considerations / Questions
I've given all of this some thought, which might come in handy in possible future discussions on this.
Nesting
Why a pseudo-class, and why
:hover-3d
?😬 As the relative Pointer Position can only be calculated while hovering I started off from
:hover
and built further upon that. Seemed like a logical thing to do.:hover
:You can't use the calculated values in non
:hover-3d
selectors(Clunky) Workaround: use Custom Properties and have the Env Vars overwrite their values.
🤔 Or would the calculated values also be applied to the targeted element (sans
:hover-3d
) itself?If so: then
:hover-3d
loses some value, as the code could as well go in the regular selector.The choice for
:hover-3d
was purely based on the fact that I saw a 3D demo which sparked this idea. Don't have any strong opinion on this name. It can as well be:hover-with-position-info-yolo-web3-crypto
if that's more in line with how things are named.Coordinate System
I played a bit with the Coordinate System that could be used with this. Main question I had here was: Should the origin be at center-center (X/Y Coordinate System), or at top-left (Page Coordinate System)?
The choice of Coordinate System has some side-effects for CSS Authors:
transform-origin
is50% 50%
I've compared various possible systems, but am personally leaning to the X/Y Coordinate System (XYCS) + range
[-1,1]
system.Page Coordinate System (PCS)
Params
0,0
sits at top-left of the box[0.5,0.5]
--pointer-x
and--pointer-y
:[0,1]
Demo (using Custom Properties): https://codepen.io/bramus/pen/4b04dbf201c6a542d276506503a56e68
Advantages:
Disadvantages:
transform-origin
0.5
before they can be used.X/Y Coordinate System (XYCS) + range
[-0.5,0.5]
Params
0,0
sits at center-center of the box--pointer-x
and--pointer-y
:[-0.5,0.5]
Demo (using Custom Properties): https://codepen.io/bramus/pen/2711c3083d1c9892ad044dacf9526c26
Advantage(s):
transform-origin
0.5
(or50%
) resembles the actual distance that was travelled from the origin--pointer-x
value of0.5
is also “50%
of the width”cqw
😎Disadvantages:
0.5
is not-handy for scaling purposes: you need to multiply the values by 2.background-position
,top
,left
, …X/Y Coordinate System (XYCS) + range
[-1,1]
Params
0,0
sits at center-center of the box--pointer-x
and--pointer-y
:[-1,1]
Demo (using Custom Properties): https://codepen.io/bramus/pen/250186328bafbb5e63bb1a6f6f2ada04
Advantage(s):
transform-origin
1
is handy for scaling purposesDisadvantages:
1
does not resemble the actual distance that was travelled from the origin--pointer-x
value of1
is not “100%
of the width”, but50%
.cqw
😎background-position
,top
,left
, …Can't we just do this with Houdini?
While the calculations to determine the position can indeed be done via Houdini, there's no way to bounce those calculated values back to the CSS. Custom Properties are Input for Worklets, not Output.
(Feel free to correct me on this, would love to see that 🤩)
Which Pointer?
Performance
Privacy
The text was updated successfully, but these errors were encountered: