davidjerleke / embla-carousel

A lightweight carousel library with fluid motion and great swipe precision.
https://www.embla-carousel.com
MIT License
5.8k stars 175 forks source link

Gap missed on last slide item when using loop option with embla__container styled with grid and gap #347

Closed webcredo closed 2 years ago

webcredo commented 2 years ago

Bug is related to

Embla Carousel version

Describe the bug

Gap missed on last slide item when using loop option with embla__container styled with grid and gap

.embla__container {
  user-select: none;
  -webkit-touch-callout: none;
  -khtml-user-select: none;
  -webkit-tap-highlight-color: transparent;

  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 200px;
  gap: 20px;
}

CodeSandbox

https://codesandbox.io/s/embla-carousel-loop-react-forked-4ccfbo

Steps to reproduce

  1. Scroll down to the last item before the loop starts
  2. No gap added after the last item before looped items starts

Expected behavior

Should be gaps between all items

Additional context

It looks like transform was not calculated correctly 9cd5f4ac12f7b3a657373021902716ac

davidjerleke commented 2 years ago

Hi @webcredo,

Thank you for your question. This behavior is expected and not a bug. Embla Carousel works a bit different than other carousel libraries in the sense that it only reads slide positions and sizes (width/height) upon initialisation. If you compare with many other libraries, they set slide widths themselves and also add a lot of styling like position: absolute; and much more. The only two DOM manipulations Embla does are the following:

The benefit of this is that devs get nearly full control over their markup. They can pretty much use any markup and CSS they like. But it also comes with a responsibility: You'll have to solve this yourself. Embla won't interfere with your CSS.

The gap property will apply gap between HTML elements and won't add any gap at the end:

The gap CSS property sets the gaps (gutters) between rows and columns. It is a shorthand for row-gap and column-gap.

There are two ways to solve this:

  1. Set margin-left: your_margin_value; or margin-right: your_margin_value; on all slides.
  2. Use gap but also add margin-left: your_margin_value; to the first slide or margin-right: your_margin_value; to the last slide.

Best, David

webcredo commented 2 years ago

Thank you for response, @davidjerleke

Yes, it is not a problem to use without a grid, but you placed an example here with a grid https://www.embla-carousel.com/guides/slide-container/ this example can work correctly only without gaps and margins on slide items with a loop option, by adding margins to grid-auto-flow with grid-auto-columns change slide size.

For example by using:

.embla__container {
  user-select: none;
  -webkit-touch-callout: none;
  -khtml-user-select: none;
  -webkit-tap-highlight-color: transparent;

  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 80%;
  margin-right: 20px;
}

slide size will be 80%-20px

davidjerleke commented 2 years ago

Hello again @webcredo,

The example is only a minimal example to get you started.

https://www.embla-carousel.com/guides/slide-container/ this example can work correctly only without gaps and margins on slide items with a loop option

That depends on what you mean by “correctly”. If you mean that you always want your slides to be 80% without the margin included, you should be able to use:

grid-auto-columns: calc(80% + 20px)?

But this is still purely CSS related because this is how grid-auto-columns work and not something Embla decides. As I mentioned:

Embla Carousel allows you to use any CSS to stack your slides in the chosen scroll axis, whether it's CSS Grid, flexbox, inline-blocks or anything else.

So the dev is responsible for getting the CSS right and Embla will just read the slide positions and gaps you apply with CSS.

I’m open to suggestions if you think the documentation isn’t clear about this and you would like to propose documentation improvements.

Best, David