SergioM
SergioM

Reputation: 1605

iOS8 webkit-overflow-scrolling:touch with overlay

I currently have an app with UIWebView that has a scrollable div with the webkit-overflow-scrolling:touch property. When the side menu is open, I place an overlay (another div) on top of the content to give a dimming effect.

The problem is that when the menu is open (and the overlay in place) when the user pans, the scrollable div actually scrolls when the overlay should be stopping this form happening.

Now, in iOS7, the solution was to add the webkit-overflow-scrolling:touch; to the overlay. That works like a charm, but in iOS8 it doesn't.

Here is a link to an example of the problem. If run on iOS 7 it works as expected, if run on iOS 8 the content in the back will scroll.

.scrollable {
    width:100%;
    height:200px;
    -webkit-overflow-scrolling:touch;
    overflow:scroll;
}

.overlay {    
    position:absolute;
    width:100%;
    overflow:scroll;
    height:200px;
    -webkit-overflow-scrolling:touch;
    background-color:black;
    opacity:.5;
    transform: translate3d(0,0,0);
    -webkit-transform: translate3d(0,0,0); 
    z-index:10;
}

https://jsfiddle.net/SergioM/57f2da87/9/

I also tried setting the overflow-x property of the scrollable div to hidden/auto when the menu is opened but that adds a terrible flicker.

Any suggestion will be much appreciated.

Thanks.

Upvotes: 6

Views: 1624

Answers (2)

Jan
Jan

Reputation: 2853

i don't think this is possible by only using css in the current safari/webkit-version of iOS8.

But you should be able to prevent the scrolling with javascript.

$( ".showHide" ).click( function() {
    $( ".overlay" ).toggle();
});

$( ".overlay" ).on( 'touchstart touchmove', function( event ) {
    if ( $( this ).is( ":visible" ) ) {
        event.preventDefault();
    }
});

Update:

i played a little around and came up with another possible solution that could be helpful for you.

HTML:

<button class="showHide">show/hide overlay</button>
<br/>
<br/>
<div class="scrollable">
    <div class="overlay"></div>
    1
    <br/>2
    <br/>3
    <br/>4
    <br/>5
    <br/>6
    <br/>7
    <br/>8
    <br/>9
    <br/>10
    <br/>11
    <br/>12
    <br/>13
    <br/>14
    <br/>15
    <br/>16
    <br/>17
</div>

CSS:

.scrollable {
    width:100%;
    height:200px;
    -webkit-overflow-scrolling:touch;
    overflow:scroll;
    position: relative
}
.overlay {
    content: ' ';
    position:absolute;
    top: 0;
    left: 0;
    width:100%;
    height:100%;
    background-color:black;
    opacity:.5;
    transform: translate3d(0,0,0);
    -webkit-transform: translate3d(0,0,0); 
    transition: opacity 300ms ease;
    z-index:10;
}

Javascript:

$( ".showHide" ).click( function () {
    $( ".overlay" ).toggle( { duration: 0, complete: function() {
        if ( $( ".overlay" ).is( ":visible" ) ) {
            $( ".overlay" ).css( 'top', $( ".scrollable" ).scrollTop() );
            $( ".scrollable" ).css( 'overflow', 'hidden' );
        } else {
            $( ".scrollable" ).css( 'overflow', 'scroll' );
        }
    }});
});

Example: JSFiddle

Upvotes: 0

SergioM
SergioM

Reputation: 1605

Well after trying many different options I came up with a work around that is good enough for now.

I added a div inside the overlay that is vertically 1% bigger. That now warranties that the event is handled by the overlay and not passed on to the container at the back. This also allows me to listen to events natively such as pan (horizontally), the vertical ones wont come up but that is ok for now.

.overlayInner {
    color:red;
    height:101%;
    margin-left:30px;
}

here is a link to the fiddle.The margin is unnecessary, just to avoid the number to overlap.

http://jsfiddle.net/SergioM/57f2da87/15/

Upvotes: 5

Related Questions