Zen Cart Logo
Forums / General Questions / Large images displays incorrect size

Large images displays incorrect size

Views: 3,771

Results 1 to 20 of 31
21 Jan 2026, 8:09 AM
#1
dml73 avatar

dml73

Zen Follower

Join Date:
Oct 2007
Posts:
413
Plugin Contributions:
0

Large images displays incorrect size

Bootstrap 3.7.7-beta1
Image Handler 5.3.5

In Admin->Configuration->Images

IH large images maximum width
and
IH large images maximum height

are set to 'empty', also tried '0' and '1024', but when clicking the product image on the product page, it does not display as the size in my images folder which is 1024px.
Example here: https://www.usconverters.com/rs232-rs485-converter-xs201a

Any ideas why?

21 Jan 2026, 10:51 AM
#2
balihr avatar

balihr

Totally Zenned

Join Date:
Oct 2008
Location:
Croatia
Posts:
1,778
Plugin Contributions:
21

Re: Large images displays incorrect size

It's because the modal window limits the size of its contents. Your image IS being loaded as 1024x1024px, but displayed as 480x480 as that's all that fits in the container (responsive).

Modal window is set to max-width: 800px, and then if you look at the structure, you'll get down to div id="slider" class="col-lg-8 offset-lg-2", which means 8/12 of the parent. Add some paddings along the way and you get your 480px. You can change it to col-12 (and remove the offset), but you risk additional images going below the viewport so you'd have to scroll down to click on the additional image thumbnail...

21 Jan 2026, 3:47 PM
#3
chadlly2003 avatar

chadlly2003

Totally Zenned

Join Date:
Jan 2015
Posts:
745
Plugin Contributions:
0

Re: Large images displays incorrect size

balihr:

It's because the modal window limits the size of its contents. Your image IS being loaded as 1024x1024px, but displayed as 480x480 as that's all that fits in the container (responsive).

Modal window is set to max-width: 800px, and then if you look at the structure, you'll get down to div id="slider" class="col-lg-8 offset-lg-2", which means 8/12 of the parent. Add some paddings along the way and you get your 480px. You can change it to col-12 (and remove the offset), but you risk additional images going below the viewport so you'd have to scroll down to click on the additional image thumbnail...

Balihr,

Your very close in solving the issue.

This what needs to be changed

find and remove in the html

col-lg-8 offset-lg-2

find

@media (min-width: 992px) {
    .modal-lg, .modal-xl {
        max-width: 800px;
    }

repace with

@media (min-width: 992px) {
    .modal-lg, .modal-xl {
        max-width: 1400px;
    }
21 Jan 2026, 6:21 PM
#4
balihr avatar

balihr

Totally Zenned

Join Date:
Oct 2008
Location:
Croatia
Posts:
1,778
Plugin Contributions:
21

Re: Large images displays incorrect size

chadlly2003:

Balihr,

Your very close in solving the issue.

This what needs to be changed

find and remove in the html

col-lg-8 offset-lg-2

> 
> 
> find 
> ```
@media (min-width: 992px) {
    .modal-lg, .modal-xl {
        max-width: 800px;
    }

repace with

@media (min-width: 992px) {
.modal-lg, .modal-xl {
max-width: 1400px;
}


I would disagree. I'm on a 1920x1200 monitor, no zoom or anything, and with the suggestion I made, additional images are at the very bottom (although still visible). Now try a standard 1920x1080 monitor and you're cutting off the thumbnails in the modal. Even with the modal window being 800px, additional images go below the viewport which is bad UX - user should NOT scroll through the modal window to swap images around. If we let the modal go to 1400, sure, the main image is displayed in full size, but even the main image is cut off and thumbnails are miles down... That's a big no-no from me.

A much cleaner solution would be to move the thumbs to the side and display a vertical thumbs carousel instead of horizontal, but I'm not familiar enough with this template to just drop the solution here.
21 Jan 2026, 8:24 PM
#5
chadlly2003 avatar

chadlly2003

Totally Zenned

Join Date:
Jan 2015
Posts:
745
Plugin Contributions:
0

Re: Large images displays incorrect size

balihr:

I would disagree. I'm on a 1920x1200 monitor, no zoom or anything, and with the suggestion I made, additional images are at the very bottom (although still visible). Now try a standard 1920x1080 monitor and you're cutting off the thumbnails in the modal. Even with the modal window being 800px, additional images go below the viewport which is bad UX - user should NOT scroll through the modal window to swap images around. If we let the modal go to 1400, sure, the main image is displayed in full size, but even the main image is cut off and thumbnails are miles down... That's a big no-no from me.

A much cleaner solution would be to move the thumbs to the side and display a vertical thumbs carousel instead of horizontal, but I'm not familiar enough with this template to just drop the solution here.

of course the additional images are going to drop down if you make the image 1400px. But tha'ts what he was asking for.

you can always have 1400px and as you mentioned move the carousel to the left or keep it at the bottom. Simple enough

23 Jan 2026, 7:00 AM
#6
dml73 avatar

dml73

Zen Follower

Join Date:
Oct 2007
Posts:
413
Plugin Contributions:
0

Re: Large images displays incorrect size

Thanks, I would like to give it a try but I can't find:

@media (min-width: 992px) {
.modal-lg, .modal-xl {
max-width: 800px;
}

anywhere. Which file would that be in?

23 Jan 2026, 9:22 AM
#7
shop_suey avatar

shop_suey

Zen Follower

Join Date:
Feb 2014
Location:
Germany
Posts:
375
Plugin Contributions:
0

Re: Large images displays incorrect size

you sure the images are being processed by IH?

23 Jan 2026, 11:24 AM
#8
mprough avatar

mprough

Totally Zenned

Join Date:
Nov 2007
Location:
Woodbine, Georgia, United States
Posts:
4,284
Plugin Contributions:
37

Re: Large images displays incorrect size

Anyone noting the file extension? .webp

I'm with Shop Suey, don't think IH is processing these images all the time

https://www.usconverters.com/rs232-rs485-converter-xs201a

images/xs201a/rs232-rs485-converter.webp

I am getting intermittent loads of IH processing the images & also not like above

23 Jan 2026, 12:31 PM
#9
dml73 avatar

dml73

Zen Follower

Join Date:
Oct 2007
Posts:
413
Plugin Contributions:
0

Re: Large images displays incorrect size

I have selected IH displaying webp images, so I assume IH is handling that. Here are my image settings:
Attachment 21139

23 Jan 2026, 12:42 PM
#10
shop_suey avatar

shop_suey

Zen Follower

Join Date:
Feb 2014
Location:
Germany
Posts:
375
Plugin Contributions:
0

Re: Large images displays incorrect size

IH processes in real-time anything compatible you throw at it and creates for every size quality optimized cached pre-rendered images.
If you decide to change quality or size, you clear the IH cache and IH processes at new access.
This is the magic

Just compare with one of my shop's product image urls and you'll notice the difference imidiately.

24 Jan 2026, 3:44 AM
#11
chadlly2003 avatar

chadlly2003

Totally Zenned

Join Date:
Jan 2015
Posts:
745
Plugin Contributions:
0

Re: Large images displays incorrect size

DML73:

Thanks, I would like to give it a try but I can't find:

@media (min-width: 992px) {
.modal-lg, .modal-xl {
max-width: 800px;
}

anywhere. Which file would that be in?

includes/templates/usc_bs4/css/stylesheet.css
put at the very bottom

   .modal-lg, .modal-xl {
       max-width: 100%;
       margin-left:1rem; 
       margin-right:1rem;
   }

I believe I covered your issue. Let me know if I a missing anything.

24 Jan 2026, 3:48 AM
#12
chadlly2003 avatar

chadlly2003

Totally Zenned

Join Date:
Jan 2015
Posts:
745
Plugin Contributions:
0

Re: Large images displays incorrect size

mprough:

Anyone noting the file extension? .webp

I'm with Shop Suey, don't think IH is processing these images all the time

https://www.usconverters.com/rs232-rs485-converter-xs201a

images/xs201a/rs232-rs485-converter.webp

I am getting intermittent loads of IH processing the images & also not like above

Not sure what you mean. Can you clarify.. i might be able to help out on the issue.

24 Jan 2026, 10:49 AM
#13
mprough avatar

mprough

Totally Zenned

Join Date:
Nov 2007
Location:
Woodbine, Georgia, United States
Posts:
4,284
Plugin Contributions:
37

Re: Large images displays incorrect size

Upon checking several products I see that IH is intermittently not caching

https://www.usconverters.com/rs232-rs485-converter-xs201a
images/xs201a/rs232-rs485-converter.webp

https://www.usconverters.com/serial-rs232-pci-card
bmz_cache/a/anpci232x2-serial-pci-cardjpg.image.1024x1024.webp

I wonder if .webp is fully supported?

24 Jan 2026, 2:18 PM
#14
pilou2 avatar

pilou2

Zen Follower

Join Date:
Jun 2008
Location:
Japan
Posts:
366
Plugin Contributions:
6

Re: Large images displays incorrect size

The standard PHP GD library does not support animated webp files, and I am not sure if it supports either files with transparent background.

24 Jan 2026, 3:41 PM
#15
dml73 avatar

dml73

Zen Follower

Join Date:
Oct 2007
Posts:
413
Plugin Contributions:
0

Re: Large images displays incorrect size

chadlly2003:

includes/templates/usc_bs4/css/stylesheet.css
put at the very bottom

.modal-lg, .modal-xl {
    max-width: 100%;
    margin-left:1rem; 
    margin-right:1rem;
}
> 
> 
> I believe I covered your issue.  Let me know if I a missing anything.

That works! 
I just set:
max-width: 50%;
margin: auto
so the white background doesn't fill the whole screen. 

I also disabled webp images in admin by selecting "no_change" in "IH large images filetype". 
I am using Cloudflare with webp enabled, so I assumed they would convert/display all images as webp. Apparently not. I will contact their support ask ask why.
24 Jan 2026, 9:20 PM
#16
chadlly2003 avatar

chadlly2003

Totally Zenned

Join Date:
Jan 2015
Posts:
745
Plugin Contributions:
0

Re: Large images displays incorrect size

DML73:

That works!
I just set:
max-width: 50%;
margin: auto
so the white background doesn't fill the whole screen.

I also disabled webp images in admin by selecting "no_change" in "IH large images filetype".
I am using Cloudflare with webp enabled, so I assumed they would convert/display all images as webp. Apparently not. I will contact their support ask ask why.

If you remove the following as mentioned on my original post...
It will be more responsive. And will look good on all browsers especially mobile

remove this

col-lg-8 offset-lg-2

includes/templates/usc_bs4/css/stylesheet.css
remove

.modal-lg, .modal-xl {
        max-width: 100%;
        margin-left:1rem; 
        margin-right:1rem;
    }

replace with

.modal-lg, .modal-xl {
        max-width: 100%;
        margin-left:1rem; 
        margin-right:1rem;
    }

 @media (min-width: 992px) {
    .modal-lg, .modal-xl {
        max-width: 50%;
}

see how nice and big the mobile image is now.

24 Jan 2026, 9:53 PM
#17
chadlly2003 avatar

chadlly2003

Totally Zenned

Join Date:
Jan 2015
Posts:
745
Plugin Contributions:
0

Re: Large images displays incorrect size

chadlly2003:

If you remove the following as mentioned on my original post...
It will be more responsive. And will look good on all browsers especially mobile

remove this

col-lg-8 offset-lg-2

> 
> includes/templates/usc_bs4/css/stylesheet.css
> remove
> 
> ```
.modal-lg, .modal-xl {
        max-width: 100%;
        margin-left:1rem; 
        margin-right:1rem;
    }

replace with

.modal-lg, .modal-xl {
max-width: 100%;
margin-left:1rem;
margin-right:1rem;
}

@media (min-width: 992px) {
.modal-lg, .modal-xl {
max-width: 50%;
}

> 
> see how nice and big the mobile image is now.

One little adjustment use this instead and you should be all set

.modal-lg, .modal-xl {
max-width: 100%;
margin-left:1rem;
margin-right:1rem;
}

@media (min-width: 992px) {
.modal-lg, .modal-xl {
width: 50%;
margin:auto;
}
}

25 Jan 2026, 6:59 AM
#18
dml73 avatar

dml73

Zen Follower

Join Date:
Oct 2007
Posts:
413
Plugin Contributions:
0

Re: Large images displays incorrect size

Perfect, thanks a lot, indeed now they are large, almost too large :laugh:
I assume changing "width: 50%;" to "width: 40%;" would make them slightly smaller?

25 Jan 2026, 2:26 PM
#19
balihr avatar

balihr

Totally Zenned

Join Date:
Oct 2008
Location:
Croatia
Posts:
1,778
Plugin Contributions:
21

Re: Large images displays incorrect size

DML73:

Perfect, thanks a lot, indeed now they are large, almost too large :laugh:
I assume changing "width: 50%;" to "width: 40%;" would make them slightly smaller?

I hate saying this, but... Told ya :P

You don't want to be enlarging the container because images are responsive and will always try to fill up as much space as they can, which then results in the bottom part of the image being "out of screen". This is really bad for User Experience and should NEVER be pushed for. If you want to allow people to see details on the photo, you need another library to allow zooming, for example ElevateZoom. If you just want to display larger images, you want to adapt them to the user's viewport. Otherwise, you could upload a 5000x5000px image and let the user go wild with the horizontal and vertical scrollbars...

The "solution" I gave you originally was the simplest, although not the optimal one. Anything more than that was simply going against the above.

I had to install the template on my dev site and play with it because the solution was not a super-simple one. Here's my final version, but please note that it includes modifications to template files as well - the Bootstrap template has some bugs and uses a combination of BS3 and BS4 markup so I opted for BS4.
It's a shame that this template isn't being updated to BS5 - both 3 and 4 are obsolete and quite hard to work with nowadays, especially when there's SO many helpful articles and code snippets available for BS5. All of my work if focused on BS5 so I might be missing something here, in which case I hope someone here will correct me and provide better code.

What this does?
It will always take the full viewport height to display the modal without vertical scroll, thumbs will always be placed at the bottom and the main image will take up all remaining space on top. In other words, it gets as big as possible on the current screen without any elements "dropping out" from the viewport.

Here you go, step by step:
includes/templates/bootstrap/templates/tpl_bootstrap_images.php : moved controls out of carousel-inner, removed .item class, removed container, row and col:

<?php
/**
 * New Modal for popup_image_additional carousel
 *
 * BOOTSTRAP v3.7.6
 *
 * @package templateSystem
 * @copyright Copyright 2003-2016 Zen Cart Development Team
 * @copyright Portions Copyright 2003 osCommerce
 * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
 */
if (!defined('IMAGE_ADDITIONAL_DISPLAY_LINK_EVEN_WHEN_NO_LARGE')) {
    define('IMAGE_ADDITIONAL_DISPLAY_LINK_EVEN_WHEN_NO_LARGE', 'Yes');
}
?>
<!-- Modal -->
<!-- BOOTSTRAP -->
<div class="modal fade bootstrap-slide-modal-lg" tabindex="-1" role="dialog" aria-labelledby="bootStrapImagesModalLabel"
     aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="bootStrapImagesModalLabel"><?= $products_name ?></h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="<?= TEXT_MODAL_CLOSE ?>"><span
                        aria-hidden="true">×</span></button>
            </div>
            <div class="modal-body">

                <div id="productImagesCarousel" class="carousel slide">
                    <!-- main slider carousel items -->
                    <div class="carousel-inner text-center">
                        <?php
                        require DIR_WS_MODULES . zen_get_module_directory('main_product_image.php');
                        ?>
                        <div class="active carousel-item"
                             data-slide-number="0"><?= zen_image($products_image_large) ?></div>
                        <?php
                        require DIR_WS_MODULES . zen_get_module_directory('bootstrap_slide_additional_images.php');

                        if ($flag_show_product_info_additional_images !== '0' && $num_images > 0) {
                            if (is_array($list_box_contents)) {
                                for ($row = 0, $rn = count($list_box_contents); $row < $rn; $row++) {
                                    $params = '';

                                    for ($col = 0, $cn = count($list_box_contents[$row]); $col < $cn; $col++) {
                                        $r_params = '';
                                        if (isset($list_box_contents[$row][$col]['params'])) {
                                            $r_params .= ' ' . (string)$list_box_contents[$row][$col]['params'];
                                        }
                                        if (isset($list_box_contents[$row][$col]['text'])) {
                                            echo '<div' . $r_params . '>' . $list_box_contents[$row][$col]['text'] . '</div>';
                                        }
                                    }
                                }
                            }
                        }
                        ?>

                    </div>
                    <!-- main slider carousel nav controls -->
                    <div id="carousel-btn-toolbar" class="btn-toolbar justify-content-between p-3" role="toolbar">
                        <a class="carousel-control-prev left pt-3" data-slide="prev"
                           data-target="#productImagesCarousel">
                            <i class="fas fa-chevron-left" title="<?= BUTTON_PREVIOUS_ALT ?>"></i>
                        </a>
                        <a class="carousel-control-next right pt-3" data-slide="next"
                           data-target="#productImagesCarousel">
                            <i class="fas fa-chevron-right" title="<?= BUTTON_NEXT_ALT ?>"></i>
                        </a>
                    </div>

                    <ul class="carousel-indicators list-inline mx-auto justify-content-center py-3">
                        <li class="list-inline-item active">
                            <a id="carousel-selector-0" class="selected" data-slide-to="0"
                               data-target="#productImagesCarousel">
                                <?php
                                require DIR_WS_MODULES . zen_get_module_directory('main_product_image.php');
                                ?>
                                <?= zen_image($products_image_large, $products_name, SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT) ?>
                            </a>
                        </li>
                        <?php
                        require DIR_WS_MODULES . zen_get_module_directory('bootstrap_additional_images.php');

                        if ($flag_show_product_info_additional_images !== '0' && $num_images > 0) {
                            if (is_array($list_box_contents) > 0) {
                                for ($row = 0, $rn = count($list_box_contents); $row < $rn; $row++) {
                                    $params = '';

                                    for ($col = 0, $cn = count($list_box_contents[$row]); $col < $cn; $col++) {
                                        $r_params = '';
                                        if (isset($list_box_contents[$row][$col]['params'])) {
                                            $r_params .= ' ' . (string)$list_box_contents[$row][$col]['params'];
                                        }
                                        if (isset($list_box_contents[$row][$col]['text'])) {
                                            echo '<li' . $r_params . '>' . $list_box_contents[$row][$col]['text'] . '</li>';
                                        }
                                    }
                                }
                            }
                        }
                        ?>
                    </ul>
                </div>
            </div>

            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal"><?= TEXT_MODAL_CLOSE ?></button>
            </div>
        </div>
    </div>
</div>

includes/modules/bootstrap/bootstrap_slide_additional_images.php : removed .item class, moved $slideNumber++ to the end as it was causing incorrect data-slide sequence

<?php
/**
 * additional_images module
 *
 * BOOTSTRAP v3.7.1
 *
 * Prepares list of additional product images to be displayed in template
 *
 * @package templateSystem
 * @copyright Copyright 2003-2016 Zen Cart Development Team
 * @copyright Portions Copyright 2003 osCommerce
 * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
 * @version $Id: Author: DrByte  Wed Jan 6 12:47:43 2016 -0500 Modified in v1.5.5 $
 */
if (!defined('IS_ADMIN_FLAG')) {
    die('Illegal Access');
}
$zco_notifier->notify('NOTIFY_MODULES_ADDITIONAL_PRODUCT_IMAGES_START');

$images_array = [];

// do not check for additional images when turned off
if ($products_image !== '' && $flag_show_product_info_additional_images !== '0') {
    $products_image_info = pathinfo($products_image);

    $products_image_extension = $products_image_info['extension'];  //-Note, does not include the leading '.'!
    $products_image_base = $products_image_info['filename'];
    $products_image_directory = $products_image_info['dirname'];

    // -----
    // Additional images in subdirectories *always" require an intervening '_' to match.
    // So do those in the /images root if we're running on zc210 or later and the
    // additional images' "mode" setting indicates that we're running in 'strict' mode,
    // in which case the intervening '_' is also needed.
    //
    zen_define_default('ADDITIONAL_IMAGES_MODE', 'legacy');
    if (ADDITIONAL_IMAGES_MODE === 'legacy' && $products_image_directory === '.') {
        $products_image_base .= '?';
        $products_image_directory = '';
    } else {
        $products_image_base .= '_';
        $products_image_directory .= '/';
    }

    $products_image_directory = DIR_WS_IMAGES . $products_image_directory;

    // Check for additional matching images
    foreach (glob($products_image_directory . $products_image_base . '*.' . $products_image_extension) as $file) {
        $images_array[] = $file;
    }
}

// Build output based on images found
$num_images = count($images_array);
$list_box_contents = [];
$title = '';

if ($num_images !== 0) {
    $row = 0;
    $col = 0;
    $images_auto_added = (int)IMAGES_AUTO_ADDED;
    if ($num_images < $images_auto_added || $images_auto_added === 0) {
        $col_width = floor(100 / $num_images);
    } else {
        $col_width = floor(100 / $images_auto_added);
    }

    $slideNumber = 1;
    $image_extension = '.' . $products_image_extension;
    foreach ($images_array as $file) {
        $products_image_large = str_replace(
            [
                DIR_WS_IMAGES,
                $image_extension,
            ],
            [
                DIR_WS_IMAGES . 'large/',
                IMAGE_SUFFIX_LARGE . $image_extension
            ],
            $file
        );

        // -----
        // This notifier lets any image-handler know the current image being processed, providing the following parameters:
        //
        // $p1 ... (r/o) ... The current product's name
        // $p2 ... (r/w) ... The (possibly updated) filename (including path) of the current additional image.
        //
        $zco_notifier->notify('NOTIFY_MODULES_ADDITIONAL_IMAGES_GET_LARGE', $products_name, $products_image_large);

        $flag_has_large = file_exists($products_image_large);
        $products_image_large = ($flag_has_large === true) ? $products_image_large : $file;
        $flag_display_large = (IMAGE_ADDITIONAL_DISPLAY_LINK_EVEN_WHEN_NO_LARGE === 'Yes' || $flag_has_large === true);
        $base_image = $file;
        $thumb_slashes = zen_image(addslashes($base_image), addslashes($products_name), SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT);
        $thumb_regular = zen_image($base_image, $products_name, SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT);
        $large_link = zen_href_link(FILENAME_POPUP_IMAGE_ADDITIONAL, 'pID=' . $_GET['products_id'] . '&pic=' . $slideNumber . '&products_image_large_additional=' . $products_image_large);

        $slide = zen_image($products_image_large);
        // List Box array generation:
        $list_box_contents[$row][$col] = [
            'params' => 'class="carousel-item" data-slide-number="' . $slideNumber . '"',
            'text' => $slide
        ];
        $col++;
        if ($col >= $images_auto_added) {
            $col = 0;
            $row++;
        }
        $slideNumber++;
    } // end for loop
} // endif

$zco_notifier->notify('NOTIFY_MODULES_ADDITIONAL_PRODUCT_IMAGES_END');

includes/templates/bootstrap/css/product_info.css : new file with all the css required to display the modal properly. If you have an existing file, just append contents.

.modal-dialog {
    height: 100vh;
    margin: 0 auto;
}
.modal-content {
    height: 100vh;
}
.modal-body {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 0 !important;
}
#productImagesCarousel {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    position: relative;
}
#productImagesCarousel .carousel-inner {
    flex: 1 1 auto;
    min-height: 0;
}
#productImagesCarousel .carousel-item {
    height: 100%;
}
#productImagesCarousel .carousel-item img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}
#productImagesCarousel .carousel-indicators {
    position: static !important;
    margin: 0 !important;
    padding: 10px 10px 12px !important;
    flex: 0 0 auto;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 8px;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    background: #fff;
}
#productImagesCarousel .carousel-indicators img {
    height: 70px;
    width: auto;
    display: block;
}
#carousel-btn-toolbar {
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    transform: translateY(-50%);
    z-index: 10;
    pointer-events: none;
}
#carousel-btn-toolbar a {
    pointer-events: auto;
}

However, it's still not as good as it could/should be. There's quite some rework to do, but I believe the best layout would be to put the thumbnails to the side (on large and medium screens only, of course). I've played with it a bit and got this, but it's not a complete solution and needs a lot more attention to get it perfected...

Attachment 21142

26 Jan 2026, 12:52 AM
#20
chadlly2003 avatar

chadlly2003

Totally Zenned

Join Date:
Jan 2015
Posts:
745
Plugin Contributions:
0

Re: Large images displays incorrect size

balihr:

I hate saying this, but... Told ya :P

You don't want to be enlarging the container because images are responsive and will always try to fill up as much space as they can, which then results in the bottom part of the image being "out of screen". This is really bad for User Experience and should NEVER be pushed for. If you want to allow people to see details on the photo, you need another library to allow zooming, for example ElevateZoom. If you just want to display larger images, you want to adapt them to the user's viewport. Otherwise, you could upload a 5000x5000px image and let the user go wild with the horizontal and vertical scrollbars...

The "solution" I gave you originally was the simplest, although not the optimal one. Anything more than that was simply going against the above.

I had to install the template on my dev site and play with it because the solution was not a super-simple one. Here's my final version, but please note that it includes modifications to template files as well - the Bootstrap template has some bugs and uses a combination of BS3 and BS4 markup so I opted for BS4.
It's a shame that this template isn't being updated to BS5 - both 3 and 4 are obsolete and quite hard to work with nowadays, especially when there's SO many helpful articles and code snippets available for BS5. All of my work if focused on BS5 so I might be missing something here, in which case I hope someone here will correct me and provide better code.

What this does?
It will always take the full viewport height to display the modal without vertical scroll, thumbs will always be placed at the bottom and the main image will take up all remaining space on top. In other words, it gets as big as possible on the current screen without any elements "dropping out" from the viewport.

Here you go, step by step:
includes/templates/bootstrap/templates/tpl_bootstrap_images.php : moved controls out of carousel-inner, removed .item class, removed container, row and col:

<?php /** * New Modal for popup_image_additional carousel * * BOOTSTRAP v3.7.6 * * @package templateSystem * @copyright Copyright 2003-2016 Zen Cart Development Team * @copyright Portions Copyright 2003 osCommerce * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0 */ if (!defined('IMAGE_ADDITIONAL_DISPLAY_LINK_EVEN_WHEN_NO_LARGE')) { define('IMAGE_ADDITIONAL_DISPLAY_LINK_EVEN_WHEN_NO_LARGE', 'Yes'); } ?> <!-- Modal --> <!-- BOOTSTRAP --> <div class="modal fade bootstrap-slide-modal-lg" tabindex="-1" role="dialog" aria-labelledby="bootStrapImagesModalLabel" aria-hidden="true"> <div class="modal-dialog modal-lg"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="bootStrapImagesModalLabel"><?= $products_name ?></h5> <button type="button" class="close" data-dismiss="modal" aria-label="<?= TEXT_MODAL_CLOSE ?>"><span aria-hidden="true">×</span></button> </div> <div class="modal-body">
            <div id="productImagesCarousel" class="carousel slide">
                <!-- main slider carousel items -->
                <div class="carousel-inner text-center">
                    <?php
                    require DIR_WS_MODULES . zen_get_module_directory('main_product_image.php');
                    ?>
                    <div class="active carousel-item"
                         data-slide-number="0"><?= zen_image($products_image_large) ?></div>
                    <?php
                    require DIR_WS_MODULES . zen_get_module_directory('bootstrap_slide_additional_images.php');

                    if ($flag_show_product_info_additional_images !== '0' && $num_images > 0) {
                        if (is_array($list_box_contents)) {
                            for ($row = 0, $rn = count($list_box_contents); $row < $rn; $row++) {
                                $params = '';

                                for ($col = 0, $cn = count($list_box_contents[$row]); $col < $cn; $col++) {
                                    $r_params = '';
                                    if (isset($list_box_contents[$row][$col]['params'])) {
                                        $r_params .= ' ' . (string)$list_box_contents[$row][$col]['params'];
                                    }
                                    if (isset($list_box_contents[$row][$col]['text'])) {
                                        echo '<div' . $r_params . '>' . $list_box_contents[$row][$col]['text'] . '</div>';
                                    }
                                }
                            }
                        }
                    }
                    ?>

                </div>
                <!-- main slider carousel nav controls -->
                <div id="carousel-btn-toolbar" class="btn-toolbar justify-content-between p-3" role="toolbar">
                    <a class="carousel-control-prev left pt-3" data-slide="prev"
                       data-target="#productImagesCarousel">
                        <i class="fas fa-chevron-left" title="<?= BUTTON_PREVIOUS_ALT ?>"></i>
                    </a>
                    <a class="carousel-control-next right pt-3" data-slide="next"
                       data-target="#productImagesCarousel">
                        <i class="fas fa-chevron-right" title="<?= BUTTON_NEXT_ALT ?>"></i>
                    </a>
                </div>

                <ul class="carousel-indicators list-inline mx-auto justify-content-center py-3">
                    <li class="list-inline-item active">
                        <a id="carousel-selector-0" class="selected" data-slide-to="0"
                           data-target="#productImagesCarousel">
                            <?php
                            require DIR_WS_MODULES . zen_get_module_directory('main_product_image.php');
                            ?>
                            <?= zen_image($products_image_large, $products_name, SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT) ?>
                        </a>
                    </li>
                    <?php
                    require DIR_WS_MODULES . zen_get_module_directory('bootstrap_additional_images.php');

                    if ($flag_show_product_info_additional_images !== '0' && $num_images > 0) {
                        if (is_array($list_box_contents) > 0) {
                            for ($row = 0, $rn = count($list_box_contents); $row < $rn; $row++) {
                                $params = '';

                                for ($col = 0, $cn = count($list_box_contents[$row]); $col < $cn; $col++) {
                                    $r_params = '';
                                    if (isset($list_box_contents[$row][$col]['params'])) {
                                        $r_params .= ' ' . (string)$list_box_contents[$row][$col]['params'];
                                    }
                                    if (isset($list_box_contents[$row][$col]['text'])) {
                                        echo '<li' . $r_params . '>' . $list_box_contents[$row][$col]['text'] . '</li>';
                                    }
                                }
                            }
                        }
                    }
                    ?>
                </ul>
            </div>
        </div>

        <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal"><?= TEXT_MODAL_CLOSE ?></button>
        </div>
    </div>
</div>
</div> ``` > > **includes/modules/bootstrap/bootstrap_slide_additional_images.php** : removed .item class, moved $slideNumber++ to the end as it was causing incorrect data-slide sequence > ``` <?php /** * additional_images module * * BOOTSTRAP v3.7.1 * * Prepares list of additional product images to be displayed in template * * @package templateSystem * @copyright Copyright 2003-2016 Zen Cart Development Team * @copyright Portions Copyright 2003 osCommerce * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0 * @version $Id: Author: DrByte Wed Jan 6 12:47:43 2016 -0500 Modified in v1.5.5 $ */ if (!defined('IS_ADMIN_FLAG')) { die('Illegal Access'); } $zco_notifier->notify('NOTIFY_MODULES_ADDITIONAL_PRODUCT_IMAGES_START');

$images_array = [];

// do not check for additional images when turned off
if ($products_image !== '' && $flag_show_product_info_additional_images !== '0') {
$products_image_info = pathinfo($products_image);

$products_image_extension = $products_image_info['extension'];  //-Note, does not include the leading '.'!
$products_image_base = $products_image_info['filename'];
$products_image_directory = $products_image_info['dirname'];

// -----
// Additional images in subdirectories *always" require an intervening '_' to match.
// So do those in the /images root if we're running on zc210 or later and the
// additional images' "mode" setting indicates that we're running in 'strict' mode,
// in which case the intervening '_' is also needed.
//
zen_define_default('ADDITIONAL_IMAGES_MODE', 'legacy');
if (ADDITIONAL_IMAGES_MODE === 'legacy' && $products_image_directory === '.') {
    $products_image_base .= '?';
    $products_image_directory = '';
} else {
    $products_image_base .= '_';
    $products_image_directory .= '/';
}

$products_image_directory = DIR_WS_IMAGES . $products_image_directory;

// Check for additional matching images
foreach (glob($products_image_directory . $products_image_base . '*.' . $products_image_extension) as $file) {
    $images_array[] = $file;
}

}

// Build output based on images found
$num_images = count($images_array);
$list_box_contents = [];
$title = '';

if ($num_images !== 0) {
$row = 0;
$col = 0;
$images_auto_added = (int)IMAGES_AUTO_ADDED;
if ($num_images < $images_auto_added || $images_auto_added === 0) {
$col_width = floor(100 / $num_images);
} else {
$col_width = floor(100 / $images_auto_added);
}

$slideNumber = 1;
$image_extension = '.' . $products_image_extension;
foreach ($images_array as $file) {
    $products_image_large = str_replace(
        [
            DIR_WS_IMAGES,
            $image_extension,
        ],
        [
            DIR_WS_IMAGES . 'large/',
            IMAGE_SUFFIX_LARGE . $image_extension
        ],
        $file
    );

    // -----
    // This notifier lets any image-handler know the current image being processed, providing the following parameters:
    //
    // $p1 ... (r/o) ... The current product's name
    // $p2 ... (r/w) ... The (possibly updated) filename (including path) of the current additional image.
    //
    $zco_notifier->notify('NOTIFY_MODULES_ADDITIONAL_IMAGES_GET_LARGE', $products_name, $products_image_large);

    $flag_has_large = file_exists($products_image_large);
    $products_image_large = ($flag_has_large === true) ? $products_image_large : $file;
    $flag_display_large = (IMAGE_ADDITIONAL_DISPLAY_LINK_EVEN_WHEN_NO_LARGE === 'Yes' || $flag_has_large === true);
    $base_image = $file;
    $thumb_slashes = zen_image(addslashes($base_image), addslashes($products_name), SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT);
    $thumb_regular = zen_image($base_image, $products_name, SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT);
    $large_link = zen_href_link(FILENAME_POPUP_IMAGE_ADDITIONAL, 'pID=' . $_GET['products_id'] . '&pic=' . $slideNumber . '&products_image_large_additional=' . $products_image_large);

    $slide = zen_image($products_image_large);
    // List Box array generation:
    $list_box_contents[$row][$col] = [
        'params' => 'class="carousel-item" data-slide-number="' . $slideNumber . '"',
        'text' => $slide
    ];
    $col++;
    if ($col >= $images_auto_added) {
        $col = 0;
        $row++;
    }
    $slideNumber++;
} // end for loop

} // endif

$zco_notifier->notify('NOTIFY_MODULES_ADDITIONAL_PRODUCT_IMAGES_END');

> 
> **includes/templates/bootstrap/css/product_info.css** : new file with all the css required to display the modal properly. If you have an existing file, just append contents.
> ```
.modal-dialog {
    height: 100vh;
    margin: 0 auto;
}
.modal-content {
    height: 100vh;
}
.modal-body {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 0 !important;
}
#productImagesCarousel {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    position: relative;
}
#productImagesCarousel .carousel-inner {
    flex: 1 1 auto;
    min-height: 0;
}
#productImagesCarousel .carousel-item {
    height: 100%;
}
#productImagesCarousel .carousel-item img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}
#productImagesCarousel .carousel-indicators {
    position: static !important;
    margin: 0 !important;
    padding: 10px 10px 12px !important;
    flex: 0 0 auto;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 8px;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    background: #fff;
}
#productImagesCarousel .carousel-indicators img {
    height: 70px;
    width: auto;
    display: block;
}
#carousel-btn-toolbar {
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    transform: translateY(-50%);
    z-index: 10;
    pointer-events: none;
}
#carousel-btn-toolbar a {
    pointer-events: auto;
}

However, it's still not as good as it could/should be. There's quite some rework to do, but I believe the best layout would be to put the thumbnails to the side (on large and medium screens only, of course). I've played with it a bit and got this, but it's not a complete solution and needs a lot more attention to get it perfected...

Attachment 21142

balihris I was just doing what he asked for. But i dont disagree with you. So here the solution to
keep the product images and secondary image displayed in the viewport

includes/templates/usc_bs4/css/stylesheet.css
put at the very bottom

.modal-body .container {
   max-width:600px
}

Attachment 21143