From f480e0eafaf60dd3630e76c491ed6f4a4cb2a7da Mon Sep 17 00:00:00 2001 From: Mark Provo Kluit Date: Fri, 2 Oct 2026 13:37:59 +0200 Subject: [PATCH] fix(material): decrease scroll speed centered hero carousel The CSS scroll-driven animations of the centered hero carousel have been reimplemented to decrease the scroll speed so that swiping moves the carousel to the next or previous item instead of many items ahead or before. Furthermore, layout shift is avoided by using translation instead of modifying the inline margin. --- .changeset/wacky-towns-eat.md | 5 + .../MaterialCarouselItemHolder.module.css | 103 +++++++++++++++--- 2 files changed, 93 insertions(+), 15 deletions(-) create mode 100644 .changeset/wacky-towns-eat.md diff --git a/.changeset/wacky-towns-eat.md b/.changeset/wacky-towns-eat.md new file mode 100644 index 00000000..db7239e6 --- /dev/null +++ b/.changeset/wacky-towns-eat.md @@ -0,0 +1,5 @@ +--- +'@solidmaterial/material': patch +--- + +Decrease scroll speed centered hero carousel diff --git a/packages/material/src/components/carousel/MaterialCarouselItemHolder.module.css b/packages/material/src/components/carousel/MaterialCarouselItemHolder.module.css index 92a80b62..44f65369 100644 --- a/packages/material/src/components/carousel/MaterialCarouselItemHolder.module.css +++ b/packages/material/src/components/carousel/MaterialCarouselItemHolder.module.css @@ -36,6 +36,12 @@ initial-value: 0px; } + @property --translate { + syntax: ''; + inherits: true; + initial-value: 0px; + } + @keyframes multi-browse-expand-medium-item { from { --max-width: var(--md-comp-carousel-size-small); @@ -102,7 +108,27 @@ } } - @keyframes hero-expand-last-item { + @keyframes centered-hero-expand-item { + from { + --max-width: var(--md-comp-carousel-size-small); + } + + to { + --max-width: var(--md-comp-carousel-size-large); + } + } + + @keyframes centered-hero-expand-item-translate { + from { + --translate: calc(-1 * (var(--md-comp-carousel-size-large) - var(--md-comp-carousel-size-small))); + } + + to { + --translate: 0; + } + } + + @keyframes centered-hero-expand-last-item { from { --max-width: 0; } @@ -115,10 +141,12 @@ @keyframes centered-hero-collapse-item { from { --max-width: var(--md-comp-carousel-size-large); + --translate: 0; } to { --max-width: calc(var(--md-comp-carousel-size-small)); + --translate: calc(var(--md-comp-carousel-size-large) - var(--md-comp-carousel-size-small)); } } @@ -305,32 +333,77 @@ --md-comp-carousel-count-large: 1; } - margin-inline-end: calc(-1 * (var(--min-width) - max(var(--md-comp-carousel-size-small), var(--max-width)))); - @supports (animation-timeline: view()) { animation: - hero-expand-item linear both, + centered-hero-expand-item linear both, + centered-hero-expand-item-translate linear both, centered-hero-collapse-item linear forwards; animation-timeline: view(x); animation-range-start: - var(--md-comp-carousel-size-small), - exit calc(-1 * (var(--md-comp-carousel-size-small) + var(--md-comp-carousel-container-gap))); - animation-range-end: - calc( - var(--md-comp-carousel-size-large) + var(--md-comp-carousel-container-gap) + - var(--md-comp-carousel-size-small) - ), + entry var(--md-comp-carousel-size-small), + cover + calc( + -1 * + ( + var(--md-comp-carousel-size-large) - var(--md-comp-carousel-size-small) + + var(--md-comp-carousel-container-gap) + ) + ), exit 0%; + animation-range-end: + cover + calc( + var(--md-comp-carousel-size-large) + var(--md-comp-carousel-container-gap) + + var(--md-comp-carousel-size-small) + ), + entry var(--md-comp-carousel-size-small), + exit calc(var(--md-comp-carousel-size-large) - var(--md-comp-carousel-size-small)); + + &:first-child { + --container-width: calc(100cqi - var(--md-comp-carousel-size-small) - var(--md-comp-carousel-container-gap)); + + animation: + centered-hero-expand-item linear both, + centered-hero-collapse-item linear forwards; + animation-timeline: view(x); + animation-range-start: + entry var(--md-comp-carousel-size-small), + exit 0%; + animation-range-end: + cover + calc( + var(--md-comp-carousel-size-large) + var(--md-comp-carousel-container-gap) + + var(--md-comp-carousel-size-small) + ), + exit calc(var(--md-comp-carousel-size-large) - var(--md-comp-carousel-size-small)); + } &:last-child { --container-width: calc(100cqi - var(--md-comp-carousel-size-small) - var(--md-comp-carousel-container-gap)); - animation: hero-expand-last-item linear both; + animation: + centered-hero-expand-item linear both, + centered-hero-expand-item-translate linear both; animation-timeline: view(x); - animation-range-start: normal; - animation-range-end: var(--md-comp-carousel-size-large); - margin-inline-end: 0; + animation-range-start: + entry var(--md-comp-carousel-size-small), + cover + calc( + -1 * + ( + var(--md-comp-carousel-size-large) - var(--md-comp-carousel-size-small) + 2 * + var(--md-comp-carousel-container-gap) + ) + ); + animation-range-end: + var(--md-comp-carousel-size-large), + entry var(--md-comp-carousel-size-small); + } + + sm-carousel-item { + translate: var(--translate); } + scroll-margin-inline-start: calc(var(--md-comp-carousel-container-gap) + var(--md-comp-carousel-size-small)); } }