4

if you look at this fiddle( http://jsfiddle.net/5ajYD/ ) with an android browser you see that the PNG that makes up the flowers has a white background.

On all other browsers it shows perfectly normal, except the android browser. I've googled on this problem but the only thing I can find is a problem with png banding and related to android app programming.

This reminds me of the issues MSIE 6 has with transparant images, and I find it very strange that this happens.

Does anyone know a fix for this issue on android browsers? I can't use non transparant background because of the gradient differences in different browsers.

What I have tried so far:

  • I have already tried using "multiple" backgrounds both posistioned at location 0px 0px, but that doens't work
  • I've tried adding a gradient to to the div with the flowers, but that failed too and broke in other browsers.

I find it very mystifying that this kind of issue shows up on a modern browser... even a nokia n95 gets it right....

The android version I’m testing against/found this with is android 2.3.4(Sony Ericsson Xperia Arc S LT18i)

This is what I see with the fiddle in the android browser on the phone

http://t.co/mofPkqjf

Tschallacka
  • 27,901
  • 14
  • 88
  • 133
  • 1
    I'm not sure about others, but I'm not seeing the images loading in your fiddle even with FF or Chrome (to see what it is supposed to look like). – ScottS Jul 09 '12 at 14:28
  • There is no image with flowers loaded on your fiddle. There is a box where it looks like an image tried to load. – Alex W Jul 09 '12 at 18:31
  • With these guys. Getting a 403 Forbidden response when trying to browse to the images in question. Please make them publicly accessible or find another place to host them. http://www.elsediendegroot.nl/wp-content/themes/twentyeleven/images/greenflowers.png – MusikAnimal Jul 10 '12 at 02:36
  • My apologies. It's still a site in development. I've updated the permissions to let images through. You should be able to see the fiddle. – Tschallacka Jul 10 '12 at 12:19
  • Have you tried exporting the png differently from Fireworks or a similar program? Maybe the Android browser likes certain options over others in its treatment of pngs... – Krimo Jul 10 '12 at 14:35
  • Have you tried exporting the file as an 8-bit PNG rather than a 24-bit PNG? It may not look great but it should work. Alternatively could you get away with saving the file as a transparent gif with the tranparency colour set to white? – Billy Moat Jul 10 '12 at 15:23
  • That's not possible. An 8 bit png doesn't support semi transparant pixels, and almost the entire flower image is composed out of semi transparant pixels. The designer would kill me. It's only android that's messing up, the rest of the browsers all have no issues displaying. Even ie 5.5 and ie6, symbian browser and safari on iphone.. only the android browser messes it up. – Tschallacka Jul 10 '12 at 16:51
  • Which version of Android are you testing against? – Jeffery To Jul 10 '12 at 19:39
  • android version 2.3.4, I’ve updated the question. – Tschallacka Jul 10 '12 at 21:49
  • What's with the retag? The original [css] tag was fine; the question has nothing to do with selectors. – BoltClock Jul 11 '12 at 18:19
  • I've tried the fiddle using the Android emulator (with Samsung Galaxy S2 (2.3.1) and Motorola Droid RAZR (2.3.3) AVDs) and it looks the same as it does in desktop browsers. Can you post a screenshot? Which device(s) are you testing with? – Jeffery To Jul 11 '12 at 18:38
  • I’ve added the screenshot and phone specification to the question – Tschallacka Jul 11 '12 at 21:02
  • @MichaelDibbets, Can you test this [**jsFiddle**](http://jsfiddle.net/2eYmw/) that has a single change to the image; It's the same image but without PNG interlace. I don't think this will matter but you never know. – arttronics Jul 13 '12 at 06:49
  • I just tested on an old android 1.6 and the background is renderered correctly unless I zoom out too far. Is it possibly a zoom issue for you? – Stobor Jul 16 '12 at 03:55

2 Answers2

1

Use HTML5 Canvas to create an alphaJPEG, a JPEG layered under an equivalent PNG with an alpha channel.

<head>
  <style>img[data-alpha-src]{visibility: hidden;}</style>
</head>
<body>
  <img src="image.jpg" data-alpha-src="alpha.png" />
  <!--...-->
  <script src="ajpeg.js"></script>
</body>

ajpeg.js

(function() {

  var create_alpha_jpeg = function(img) {

    var alpha_path = img.getAttribute('data-alpha-src')
    if(!alpha_path) return

    // Hide the original un-alpha'd
    img.style.visiblity = 'hidden'

    // Preload the un-alpha'd image
    var image = document.createElement('img')
    image.src = img.src
    image.onload = function () {

      // Then preload alpha mask
      var alpha = document.createElement('img')
      alpha.src = alpha_path
      alpha.onload = function () {

        var canvas = document.createElement('canvas')
        canvas.width = image.width
        canvas.height = image.height
        img.parentNode.replaceChild(canvas, img)

        // For IE7/8
        if(typeof FlashCanvas != 'undefined') FlashCanvas.initElement(canvas)

        // Canvas compositing code
        var context = canvas.getContext('2d')
        context.clearRect(0, 0, image.width, image.height)
        context.drawImage(image, 0, 0, image.width, image.height)
        context.globalCompositeOperation = 'xor'
        context.drawImage(alpha, 0, 0, image.width, image.height)

      }
    }
  }

  // Apply this technique to every image on the page once DOM is ready
  // (I just placed it at the bottom of the page for brevity)
  var imgs = document.getElementsByTagName('img')
  for(var i = 0; i &lt; imgs.length; i++)
    create_alpha_jpeg(imgs[i])

})();

In the head element I linked to FlashCanvas:

<!--[if lte IE 8]><script src="flashcanvas.js"></script><![endif]-->

... and I threw in this to avoid a flicker of the un-alpha’d JPEG:
Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
1

I had a big facepalm moment.

I've been battling with this for two months now and I simply couldn't figure out the logic. The problem was in the econtainer element that it had a parameter: width:100%.

What happens is that it only renders the width up to the actual page width of the viewport.

So if you have a browser screen on mobile that's 480px wide, it'll set width to 480px, render a gradient of 480px, and not rerender when you scroll sideways.

The problem was solved by adding a min-width:1200px; and now it renders properly!

Thank you all for looking into this...

Tschallacka
  • 27,901
  • 14
  • 88
  • 133