Splidejs / splide

Splide is a lightweight, flexible and accessible slider/carousel written in TypeScript. No dependencies, no Lighthouse errors.
https://splidejs.com
MIT License
4.89k stars 424 forks source link

In small carousel, when all slides are visible, layout shifts 10px on init. #1290

Open SamTyurenkov opened 7 months ago

SamTyurenkov commented 7 months ago

Checks

Version

v4

Description

Right after initialization, .splide__list gets a translateX(10px) for a small slider where all slides are visible image

With same code, when slides exceed container, splide__list gets a translateX(0) on initialization. image

This behaviour seems inconsistent and cause an annoying layout shift after initialization.

Reproduction Link

No response

Steps to Reproduce

    var slider = new Splide( '.interactive_content.splide', {
        type: 'slide',
        autoWidth: true,
        autoHeight: true,
        gap: '10px',
        arrows: false,
        pagination: true,
        drag: 'free',
        dragMinThreshold: {
            mouse: 0,
            touch: 10,
        },
        omitEnd: true,
        focus: 'center',
        trimSpace: 'move',
        padding: '20px',
        breakpoints: {
            1100: {
                padding: '10px',
            },
            993: {
                padding: '8px',
            },
        }
      } ).mount();
.splide {

    &__track {
        overflow: visible;
        max-width: 100%;

        .splide__list {
            align-items: center;
            transform: translateX(0);

            .splide__slide {
                margin-right: 10px;
                border-radius: 5px;
            }
        }
    }

    &__arrows {
        z-index: 10;
        position: relative;
        order: 5;

        .splide__arrow {
            background-color: #78bb80;
            border: 0;
            border-radius: 5px;
            -webkit-box-shadow: -1px 2px 2px rgba(0, 0, 0, .25);
            box-shadow: -1px 2px 2px rgba(0, 0, 0, .25);
            position: absolute;
            cursor: pointer;
            color: #000;
            opacity: 1;
            top: -55px;

            &:hover {
                background-color: #a4d6aa;
            }

            &:disabled {
                background-color: #828282;
            }

            svg {
                width: 10px;
                height: 10px;
                padding: 10px;
            }

            &--prev {

                right: 65px;

                svg {
                    transform: rotate(180deg);
                }
            }

            &--next {
                right: 10px;
            }
        }
    }

    &.no_arrows {
        .splide__arrows {
            display: none;
        }
    }
}

    &.splide {
        .splide_extra_container {
            width: 100%;
            max-width: 100%;
            min-width: 100%;
            box-sizing: border-box;
            flex: 0 0 100%;
            display: flex;
            justify-content: center;
            .splide__pagination {
                position: absolute;
                bottom: 0;
                right: 25%;
                flex: 0 0 calc(46% - 10px);
                box-sizing: border-box;
                justify-content: start;
                padding: 0;

                @media(max-width:992px) {
                    right: 12%; 
                }

                @media(max-width:640px) {
                    flex: 0 0 100%;
                    justify-content: center;
                    bottom: -15px;
                    right: unset;
                    width: 100%;
                }

                button {
                    color: #111;
                    padding: 15px;
                    line-height: 30px;
                    font-weight: 600;
                    box-shadow: -1px 1px 1px rgb(0 0 0 / 25%);
                    border-radius: 5px;
                    margin-left: 1px;
                    border-style: initial;
                    cursor: pointer;
                    text-decoration: none;
                    background: #78bb80;
                    margin: 0 3px;
                    transform: rotate(45deg);
                    transition: all 0.3s ease;
                    opacity: 1;

                    &:hover,
                    &.is-active {
                        background: #a4d6aa;
                        transform: rotate(12deg);
                    }
                }
            }

            .splide__track {
                box-sizing: border-box;
                padding: 0 20px;
                min-height: 400px;
                height: 400px;

                @media(max-width:1100px) {
                    padding: 0 10px;
                }

                @media(max-width:992px) {
                    padding: 0 8px;
                }

                @media(max-width:768px) {
                    min-height: 280px;
                    height: 280px;
                }

                .splide__list {

                    .splide__slide {
                        border-radius: 5px;
                        margin-right: 10px;
                        width: auto;
                        display: flex;
                        align-items: center;
                        overflow: visible;
                        background-color: #111;

                        img {
                            max-height: 400px;
                            transition: all 0.6s ease;
                            display: block;
                            box-shadow: -2px 2px 2px rgb(0 0 0 / 25%);
                            background-color: #d9d9d9;
                            border-radius: 5px;
                            background: #000;

                            @media (max-width: 768px) {
                                max-height: 280px;
                            }
                        }
                    }
                }
            }
        }
    }

Expected Behaviour

no layout shift after initialization

yyywork commented 7 months ago

I am having the same issue like yours as well, It shifts 136.5px for me, It becomes normal after triggering a 'move' event.(But it couldn't be a workaround for my case)

image
bronisMateusz commented 3 weeks ago

@yyywork Have similar issue, but in my case set focus option to 1 solved the problem.

My whole optionset:

new Splide(carousel, {
  type: "loop",
  mediaQuery: "min",
  gap: 20,
  focus: 1,
  breakpoints: {
    1024: {
      perMove: 1,
      perPage: 2,
    },
  },
}).mount();