GameKyuubi
GameKyuubi

Reputation: 731

Why are items in my web image gallery disappearing on ios?

I have a gallery of images in a scrolling layout on a website. On PC, all the images show. On Android, all the images show. On iPhone, using the same browser as on Android (Chrome or Firefox), when scrolling through the images some of them don't appear, or only half-appear until they are scrolled offscreen and then back again. The images still exist in the layout and can still be tapped to open the lightbox. Why is this happening? I'm using lozad.js to try to solve this problem (because I thought it might be just loading too much data at once) but the problem existed before I implemented lozad. Here's my code for each image:

.gallery {
  padding-top: 13px;
  z-index: 3;
  position: relative;
  overflow: scroll;
  -webkit-overflow-scrolling: touch;
  height: calc(100vh - 13px);
}

.thumbnail {
  min-height: 25%;
  width: 25%;
  margin: 10px;
  border-radius: 10px;
}

/** LIGHTBOX MARKUP **/
.lightbox {
  /** Default lightbox to hidden */
  display: none;
  /** Position and style */
  position: fixed;
  z-index: 999;
  width: 100%;
  height: 100%;
  text-align: center;
  top: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.8);
}

.lightbox img {
  /** Pad the lightbox image */
  max-width: 90%;
  max-height: 80%;
  margin-top: 5%;
}

.lightbox:target {
  /** Remove default browser outline */
  outline: none;
  /** Unhide lightbox **/
  display: block;
}
<div id="mobile" class="gallery">
  <!-- thumbnail image wrapped in a link -->
  <a href="#img1-mobile">
    <img src="thumb/lo/1.jpg" data-src="thumb/hi-mobile/1.jpg" class="lozad thumbnail">
  </a>
  <!-- lightbox container hidden with CSS -->
  <a href="#_" class="lightbox" id="img1-mobile">
    <img src="img/lo/1.jpg" data-src="img/hi/1.jpg" class="lozad">
  </a>
  <!-- thumbnail image wrapped in a link -->
  <a href="#img2-mobile">
    <img src="thumb/lo/2.jpg" data-src="thumb/hi-mobile/2.jpg" class="lozad thumbnail">
  </a>
  <!-- lightbox container hidden with CSS -->
  <a href="#_" class="lightbox" id="img2-mobile">
    <img src="img/lo/2.jpg" data-src="img/hi/2.jpg" class="lozad">
  </a>
  <!-- thumbnail image wrapped in a link -->
  <a href="#img3-mobile">
    <img src="thumb/lo/3.jpg" data-src="thumb/hi-mobile/3.jpg" class="lozad thumbnail">
  </a>
  <!-- lightbox container hidden with CSS -->
  <a href="#_" class="lightbox" id="img3-mobile">
    <img src="img/lo/3.jpg" data-src="img/hi/3.jpg" class="lozad">
  </a>
  ...
</div>

Upvotes: 0

Views: 669

Answers (1)

MTCoster
MTCoster

Reputation: 6145

Here’s a hacky but effective fix:

#mobile img {
  transform: translate3d(0, 0, 0);
}

But why does this work?

Because it’s a mobile browser engine, WebKit WebCore cuts a lot of corners when performing Composite and Paint stages. It does this in the name of battery life, and generally that’s a great tradeoff. By applying a 3D transformation (even a null one), these two stages are passed off to the hardware-accelerated (read: more power hungry) graphics engine.

In your case, this corner-cutting occurs when an image is off-screen up until the point it’s interacted with by the user (clicking on it does the trick).

Since these calls only occur when the page requires a repaint (scrolling & zooming mostly), the penalty to your users battery-wise should be minimal.


It turns out mobile versions of WebKit have struggled with image-heavy pages for almost 6 years. The solution there, incidentally, is effectively the same. Sometimes the old ways still work best :p

Upvotes: 1

Related Questions