javascriptjqueryhtmlcsssafari

Safari's auto margin + translate3d 1px bleed issue


I am working with a slideshow that works similar to this: https://jsfiddle.net/trbwxyso/

<!doctype HTML>
<html>
<head>
    <title></title>
    <style>
        * { margin: 0; padding: 0; }
        body { background: #000; }
        #wrapper { margin: 0 auto; width: 500px; }
        #project_ctr { position: relative; width: 1500px; height: 576px; display: block; background: #000; overflow: hidden; }
        .project { position: absolute; width: 500px; height: 576px; display: block; }
        .ease { transition: 750ms ease all; }
    </style>
    <script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
</head>
<body>
    <div id="wrapper">
        <div id="project_ctr">
            <div class="project" style="background: #f00; left: 0;">
            </div>
            <div class="project" style="background: #fff; left: 500px;">
            </div>
            <div class="project" style="background: #00f; left: 1000px;">
            </div>
        </div>
    </div>
    <script>
        $(document).ready(function() {
            setTimeout(function() {
                $('.project').addClass('ease').css({
                    'transform': 'translate3d(-500px, 0, 0)'
                });
                setTimeout(function() {
                    $('.project').addClass('ease').css({
                        'transform': 'translate3d(-1000px, 0, 0)'
                    });
                }, 2000);
            }, 2000);
        });
    </script>
</body>
</html>

In Safari, (on OS X) if you resize your browser, you will see a 1-pixel shift and bleed of the previous background. I have tried every CSS trick to no avail. It appears to be a Safari-only bug that's replicable, and I can confirm it has been happening for at least two years.

Are there any workarounds?


Solution

  • currentColor to the rescue. I'm aware of how ugly this Safari-only CSS is:

    @media screen and (min-color-index:0) and(-webkit-min-device-pixel-ratio:0) 
    { @media {
        .project:before {
          content: "";
          display: block;
          position: absolute;
          left: -1px;
          top: 0;
          bottom: 0;
          height: 100%;
          width: 1px;
          z-index: 999;
          background: currentColor;
        }
      }
    }
    

    Here, the value currentColor set on background assumes whatever the current slide color is, making the fix scale pretty well.

    https://jsfiddle.net/dgt4uqc4/2/