Aosis
Aosis

Reputation: 311

Issue with browser resizing in CSS scroll snap

I am trying to implement a book view where one page is visible at one time and user can swipe through each page to navigate. All pages are of equal size and I have to show each page on 100% viewport width. My problem is that when I am on a page no X and I try to resize my browser window, I end up on some other page no. I want it to remain at page no X only. This does not happen when I am on first or last page. I have created a fiddle for this. https://jsfiddle.net/8y5swhj9/.

<!DOCTYPE html>
    <html>
    <head>
        <title>POC</title>
        <style type="text/css">
            .container {
                -webkit-box-sizing: border-box;
                box-sizing: border-box;
                display: -webkit-box;
                display: -ms-flexbox;
                display: flex;
                -ms-flex-item-align: start;
                outline: none;
                -webkit-overflow-scrolling: touch;
                -ms-overflow-style: none;
                overflow-x: scroll;
                overflow-y: hidden;
                overflow-y: -moz-hidden-unscrollable;
                -ms-scroll-chaining: none;
                -ms-scroll-snap-coordinate: 100vw 0;
                scroll-snap-coordinate: 100vw 0;
                -ms-scroll-snap-destination: 100vw 0;
                scroll-snap-destination: 100vw 0;
                -ms-scroll-snap-points-x: snapInterval(0%, 100%);
                -ms-scroll-snap-points-x: repeat(100vw);
                scroll-snap-points-x: repeat(100vw);
                -ms-scroll-snap-type: mandatory;
                -ms-scroll-snap-type: x mandatory;
                scroll-snap-type: x mandatory;
                scroll-snap-type: mandatory;
                scrollbar-width: none;
                width: 100%;
            }
            .page {
                align-items: center;
                display: flex;
                height: 100%;
                justify-content: center;
                min-width: 100%;
                position: relative;
                scroll-snap-align: start;
                width: 100%;
                box-shadow: inset 0 0 20px #000000;
            }
        </style>
    </head>
    <body>
        <div class="container" style="height: 359px;">
            <div class="page">
                <h1>1</h1>
            </div>
            <div class="page">
                <h1>2</h1>
            </div>
            <div class="page">
                <h1>3</h1>
            </div>
            <div class="page">
                <h1>4</h1>
            </div>
            <div class="page">
                <h1>5</h1>
            </div>
            <div class="page">
                <h1>6</h1>
            </div>
            <div class="page">
                <h1>7</h1>
            </div>
            <div class="page">
                <h1>8</h1>
            </div>
            <div class="page">
                <h1>9</h1>
            </div>
            <div class="page">
                <h1>10</h1>
            </div>
        </div>
    </body>
    </html>

In this code, if you move to a center position, say page no 6 and then resize the browser window widthwise, you will see that the entire content starts flowing and we end up on some random page no.

I am taking inspiration from https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_menu_hor_scroll. This has a horizontally scrollable menu. I have created a fiddle for this: https://jsfiddle.net/xyzasmb2/ This problem does not happen here.

I am not able to understand and fix this issue. Can some one please help?

Upvotes: 0

Views: 1357

Answers (2)

TheStrangeCereal28
TheStrangeCereal28

Reputation: 1

Exactly like Pete said, the problem is the ScrollLeft position. You could try a function that on window.onresize execute an addition.

window.onload = reorder;

function reorder(){
element.scrollLeft +=1}

Because it's mandatory the scrolling it will reorder if you resize it. Everytime you resize it, will add 1, then order mandatory x in a loop. So always it resize it will stay centered.

Upvotes: 0

Pete
Pete

Reputation: 61

The problem is that the content scales with the container as it's a multiple of container's width ... while the scrollLeft position remains unchanged, in pixels from the left edge. The only way to fix this that I can think of at the moment is detecting a resize of the container, but you can only bind to window's resize, not individual element's resize events ... except for using some trickery: How to detect DIV's dimension changed?

I wish there was a way to specify the scrollLeft position as % of the total width as that would have solved this problem.

Upvotes: 2

Related Questions