Let visitors scroll and drag the landing page project gallery - #8
Merged
Merged
Conversation
Dragging the gallery stopped it for good. Pressing on a card focuses it, and the drift held still for anything focused inside the strip — so the card the drag began on kept both the focus and the strip long after the pointer had gone elsewhere. That hold was meant for someone working through the cards with the tab key, who would otherwise have to read a card that was wandering off. `:focus-visible` is the platform's own answer to which of the two just happened, and asking it lets a keyboard visitor keep the strip while a press no longer takes it. A pointer left sitting where a drag ended no longer holds the strip either. Resting on a card to look at it still does, but someone who has just dragged has said where they want the gallery, and their pointer is wherever the drag ran out rather than over anything they meant to stop on. Leaving and coming back arms the hold again. The wait before the drift resumes is now the two seconds asked for, and it no longer applies to the moment the page loads, where a fast first paint could leave the gallery sitting still until the clock it is measured against had passed two seconds of its own. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015aCGjKwtBpk8NdVKxQiCRA
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The gallery on the landing page moved on rails.
UMarqueeanimates its content in CSS, and a CSS animation is not a scroll position, so a trackpad swipe, a touch drag or a mouse drag had nothing to take hold of — anyone wanting a second look at a card that had just gone past had to wait for it to come round again.What changed
A new
DraggableMarqueelays the same repeated content out in a real horizontal scroller and drifts it by nudgingscrollLefta fraction of a pixel each frame. That makes the drift one more writer of a position the visitor can write to as well, so scrolling, swiping, dragging, momentum and the keyboard all work because the browser already does them rather than because they were reimplemented.The infinite loop is the usual trick: the slot is repeated end to end, and since the copies are identical, shifting the scroll position by exactly one copy's width is invisible. Doing that whenever the position leaves the middle copy keeps a whole copy of slack either side, so the strip never reaches an end to stop or bounce at. The copy count adapts to how wide the strip is.
landing/Hero.vueswapsUMarqueefor it. The card markup and itsMotionanimations are untouched.When it holds still
The drift stands aside while the gallery is being used: under a resting pointer, during a drag, while a card is focused by the tab key, for two seconds after any scrolling of the visitor's own, off screen, and entirely for anyone who asks for reduced motion.
Two details there took a second pass. Pressing on a card focuses it, so holding the strip for anything focused inside it meant a drag stopped the gallery for good — the card the drag began on kept the focus long after the pointer had gone.
:focus-visibleis the platform's own answer to whether someone tabbed here or pressed here, and asking it lets a keyboard visitor keep the strip while a press no longer takes it. A pointer left sitting where a drag ended no longer holds it either: resting on a card to look at it still does, but after a drag the pointer is wherever the drag ran out rather than over anything the visitor meant to stop on.Two things worth a look
Mouse-wheel scrolling is not hijacked. Trackpad horizontal scroll, shift+wheel and touch swipe all scroll the strip natively, but a plain vertical wheel still scrolls the page rather than the gallery. Capturing it would trap the page under a hero element. Dragging is the mouse affordance instead, with a
grabcursor. Happy to change this if you would rather the wheel drove it.The duplicated copies are not
inert. That would have been the tidy way to hide them, butinertalso refuses clicks, and the copy under the visitor's pointer is nearly always a clone — it made the visible cards unclickable. They are hidden from assistive technology and taken out of the tab order instead, which says the same thing while leaving them clickable.Testing
Driven in Chromium against a production build.
speedprop/projectsprefers-reduced-motionaria-hiddentypecheckandbuildpass.lintreports the same 41 problems with and without this change — all pre-existing, inapp.vueandabout.vue.The remote itch.zone project images cannot load from the sandbox this was built in, so they showed as alt text in my screenshots. That is environmental and not a change in behaviour.
Generated by Claude Code