Forum Moderators: phranque

Message Too Old, No Replies

Positioned images don't show on the first pageview

         

csdude55

3:54 am on May 22, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I have a series of transparent images that I layer on top of one another to create a radar map. By default they're 600x550px, but I want them to shrink down to fit the page on smaller viewports (eg, mobile).

I put them in a DIV container with position: relative, then style the container with max-width: 600px and width: 100%.

Then I load the first image with width: 100%, then subsequent images are given position: absolute; top: 0; left: 0. They're loaded in a PHP loop, so I use the counter to set a z-index, too.

The problem I'm having, though, is that the first time I load the page, the container loads with no height, so I get a thin black line. After that, though, subsequent page loads show it just fine.

(Before anyone gets upset, these images are being loaded from an external site WITH PERMISSION, but that means that I have no control over the sizes or anything)

I tried to add a jQuery fix at the end to automagically "fix" the height based on the height of the image, but that doesn't seem to have any impact.

Here's the code, with names changed and some of the images removed to make it easier to read. Any suggestions on how I could make it load correctly?

<style>
#container {
position: relative;

max-width: 600px;
width: 100%;

border: 1px solid #333;
border-radius: 10px;

overflow: hidden
}

.abs { position: absolute }
</style>

<div id="container">
<img src="foo.jpg" alt=""
style="width: 100%">

<img src="bar.gif" alt=""
class="abs" style="top: 0; left: 0; z-index: 1; width: 100%">

<img src="example.gif" alt=""
class="abs" style="top: 0; left: 0; z-index: 2; width: 100%">
</div>

<script>
$('#container').height($('#container img').height());
</script>

tangor

6:42 am on May 22, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Don't have a "code" answer, but my shortcut get'er done method is a transparent image loaded from MY system BEFORE the others are loaded... being local that will set the div height.

not2easy

2:08 pm on May 22, 2020 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



I don't see anything regarding image size except the inline "width: 100%" which can lead to distorted image (aspect ratio) when they don't fit the slot. There should be an image tag in the <style> section:
img {max-width: 100%;} 
to ensure they resize to the container without distortion. It would apply to all images on the page, but that is likely to be a better UX. If it means a lot of rework you could use the #container.img tag instead.

lucy24

5:14 pm on May 22, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



which can lead to distorted image (aspect ratio) when they don't fit the slot

You need to specify the height, as in
img {max-width: 100%; height: auto;}
inside the @media envelope of your choice.

csdude55

12:27 am on May 23, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Don't have a "code" answer, but my shortcut get'er done method is a transparent image loaded from MY system BEFORE the others are loaded... being local that will set the div height.

@tangor, how do you do that when you don't know the final height? Or can I just do it the same as the others, and the fact that it's loading locally instead of remote be the key?

After @lucy24 mentioned height: auto, I remembered that I DID have that... somewhere. So I used Chrome Dev Tools to get all of the styles assigned to it, and I DO have max-width: 100% and height: auto in the main stylesheet:

element.style {
width: 100%;
}
section img {
max-width: 100%;
height: auto;
}
img {
border: 0;
vertical-align: top;
}
Style Attribute {
font-size: 100%;
}
section, p, .arialSmall {
font-size: 12px;
}
html, body {
font-family: Arial, Tahoma, Helvetica, sans-serif;
color: #000;
background: #313943;
height: 100%;
margin: 0;
}


My next thought is a return to JavaScript / jQuery... I could determine the width of the parent container, then divide it by the default width to find the ratio. Then I could force the height; eg:

var ratio = $('#container').width() / 600;
$('#container').height($('#container').height() * ratio);

But that doesn't help if they manually adjust their window size or anything, so it's not perfect. I just can't quite figure out why it's giving me attitude!

not2easy

12:36 am on May 23, 2020 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Can you check headers while it loads to follow the image loads and see what would/should be showing up at what point?

csdude55

7:14 pm on May 24, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Well, I've been trying but since this is an intermittent issue it's kinda tricky... I've been leaving it open since my last post and refreshing it every 1,000 seconds using PHP:

header("Refresh: 1000;");

I haven't seen it mess up since, but I don't know if it's because of something I've done or if the images at the source just haven't changed (so it's been coming from cache for the last 40+ hours).

The last change I made was to use cURL to read the headers, and only show the image if the header is an image:

// this is a function I've had in my variables.php script for awhile,
// so it's just here for reference
function getFile($url, $getInfo=false) {
$t = false;

if (strpos($url, 'http') === 0) {
$ch = curl_init(filter_var($url, FILTER_VALIDATE_URL));
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36');
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 180);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$t = curl_exec($ch);

if ($getInfo && $t) {
$arr = curl_getinfo($ch);
$t = $arr['http_code'] === 200 ? $arr[$getInfo] : false;
}

curl_close($ch);
}

return $t;
}

// and then in this script
$img = [
'list of image paths',
'to be shown'
];

$i = 0;
foreach ($img as $src) {
$headers = getFile($src, 'content_type');

if (strpos($headers, 'image/') === 0) {
$thisClass = $i === 0 ? false : "top: 0; left: 0; z-index: $i' class='abs";
$i++;

echo <<<EOF
<img src="$src" alt=""
style='width: 100%; $thisClass'>

EOF;
}
}

tangor

3:31 pm on May 25, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



@tangor, how do you do that when you don't know the final height?


Because the transparent place holder image is known to be x,y in size and loads first?

YMMV