Latest version: 5.4.25 (Change Log)
Release date: November 8th, 2023
Download AJAX-ZOOM Software

Cleverly set height and proportions of the AJAX-ZOOM parent HTML container in responsive layouts

Posted on 2019-01-15

A common mistake when integrating AJAX-ZOOM viewer into a responsive layout is that the parent container misses the height. Browsers calculate the height of an HTML element while building a page. The missing of the calculated height may lead to unexpected results such as the AJAX-ZOOM viewer not showing at all or breaking out of the present layout. This post explains the roots of the issue and suggests several workarounds that are also present within the AJAX-ZOOM example pages.

The main root of the confusion is that a responsive implementation of the AJAX-ZOOM viewer does not have any width or height on its own. Unlike, for example, an image element, the viewer adapts to the parent container and not the other way around. It's like setting the height and width of a child to 100%. The percentage value resolves against the size of the parent container, and if it lacks calculated pixel dimensions, especially the height, the browser is not able to calculate any positive dimensions of the child element.

Usually, the main problem is the indication of the height that leads to a zero calculated height done by a browser. There are barely any issues with the width in practice because HTML elements in which you would insert the viewer mostly have a calculated width despite being empty. In some instances, however, when the width is not defined, and a container is floating or is positioned absolutely or fixed, the width might be missing as well, but this is more seldom. A more common situation that leads to problems with AJAX-ZOOM is that the height of a regular container depends on the contents inside, and therefore it is not set in any way.

As explained earlier, the AJAX-ZOOM viewer tries to adapt to the parent container. Therefore, the parent element's height must be set so that AJAX-ZOOM can read the calculated values and adjust itself accordingly. A missing calculated height may lead to various problems within modern responsive, adaptive, or mixed layouts. In this post, there are several solutions to avoid those problems by preparing the viewer's parent container via CSS or JavaScript.

Before proceeding, it makes sense to define the difference between responsive and adaptive layouts. Compared to detailed and well-elaborated articles, the following definitions may be wrong. However, for the meaning of this topic, they are sufficient.

  • So in our sense, responsive means that an element fluidly adjusts its dimensions.
  • An adaptive container resizes upon the breakpoints within an interval that depends on screen resolution or orientation.

CSS offers the "@media" queries for this. For example, on the current page that uses bootstrap CSS, the outer .container CSS-class is adaptive but e.g. .col-md-6 column within a .row is responsive.

For the following solutions, it does not matter if it is about the AJAX-ZOOM 360-product viewer or image-zoom viewer. Both view types require a sufficiently prepared container for a trouble-free loading of AJAX-ZOOM into it.

Visualization of the problem when CSS height is missing and not calculated

The size of the container with ID example_container_1 is NaN px.

Located to the left or top of this text, there should be a colored container.

					
						.example_container_1 {
							position: relative;
							height: 100%;
						}
					
				

Even though the container's CSS height that is supposed to be the parent container for AJAX-ZOOM is 100%, it is not visible. The container resides within this simplified HTML structure:

					
						<div class="row">
							<div class="col-md-6">
								<div class="example_container_1" id="example_container_1">
								</div>
							</div>
							<div class="col-md-6">
								Text...
							</div>
						</div>
					
				

The height of col-md-6 is not set in any way, so setting 100% for the container with ID example_container_1 is senseless. Press on the button below to load the AJAX-ZOOM viewer into this container.

As you can see, as of the recent AJAX-ZOOM version, the viewer loads and is visible! However, the only reason it loads is because AJAX-ZOOM has detected the parent container's missing height and has set it to some pixel value in a cheeky way. Otherwise, it would not be visible at all. That is the reason why some developers decide they need to change an AJAX-ZOOM option or change the core code of AJAX-ZOOM to change that behavior.

Indeed that would be possible. The option that is responsible for the height is $zoom['config']['picDim'], but it does not suppose to change the real height of the viewer in a responsive environment. By the absence of any calculated height, AJAX-ZOOM takes the height value of this option and sets the height of the container. That makes the viewer neither adaptive nor responsive.

Do NOT try to change the value of the $zoom['config']['picDim'] option to fix this issue. Also, do NOT try to make it optional by passing a parameter to the config file. That is the wrong approach! Rather you should give the parent container a height right away by using CSS or JavaScript.

Anyway, please understand that AJAX-ZOOM sets the parent container's height only in exceptional cases as a last resort. It is doing this by adding the height to the style attribute, which is "strong" in the sense that it overrides rules of a CSS-class defined elsewhere. Additionally to the issues described above, setting a static height may become a problem when the content of the parent container changes, e.g., it changes from standard images to AJAX-ZOOM 360 viewer and back to images again. A likely outcome is that after switching, users end up with a broken layout.

Setting an adaptive CSS height

The size of the container with ID example_container_2 is NaN px.

The container to the left (or top on narrow screens) has a calculated height. Unlike in the example above, it is visible right away. Press on the button below to load the AJAX-ZOOM viewer into this container.

The HTML structure is the same as in the above example.

					
						<div class="row">
							<div class="col-md-6">
								<div class="example_container_2" id="example_container_2">
								</div>
							</div>
							<div class="col-md-6">
								Text...
							</div>
						</div>
					
				

It has, however, a standard height of 400px. Additionally, the CSS contains @media queries. Depending on the width and height of the viewport, the height changes. If you go with this solution, you should create your own rules that fit with your layout.

Resize the browser to validate that the size of the parent container changes and the AJAX-ZOOM viewer's size adapts accordingly.

					
						.example_container_2 {
							position: relative;
							width: 100%;
							height: 400px;
						}

						@media (min-width: 992px) and (min-height: 768px) {
							.example_container_2 {
								height: 300px;
							}
						}

						@media (min-width: 1023px) and (min-height: 768px) {
							.example_container_2 {
								height: 450px;
							}
						}

						@media (min-width: 1679px) and (min-height: 992px) {
							.example_container_2 {
								height: 500px;
							}
						}

						@media (max-height: 480px) {
							.example_container_2 {
								height: 300px;
							}
						}
					
				

Setting a responsive CSS height with CSS viewport units

The size of the container with ID example_container_3 is NaN px.

As initially differentiated, a responsive element fluidly adjusts its dimensions. The fluid adjustment in this example refers to the height only because this page's layout is adaptive.

					
					.example_container_3 {
						position: relative;
						width: 100%;
						height: 400px;
						height: 50vh;
						min-height: 300px;
						max-height: 545px;
					}
					
				

Press on the button below to load the AJAX-ZOOM viewer into this container.

Nowadays, the viewport-units (vw, vh, vmin, vmax) are widely supported. The vh unit means 1/100th of the viewport height. Other words this is a percentage value relative to the height of the browser's inner-window.

So in the above CSS, the height is 50% of the window height. The minimal and maximal heights are limited to fixed pixel values, but this is optional. Of course, you can add @media queries and finetune the CSS for your layout.

Fixed CSS height with responsive CSS max-height

The size of the container with ID example_container_4 is NaN px.

You can also use the viewport-units to limit the height responsively. It is convenient not just for the AJAX-ZOOM viewer but even a simple image that should be visible as a whole. The container has a fixed height of 545 pixels, but it is limited to at most 75% of the browser's inner-window height. Resize the browser window to see the effect.

					
						.example_container_4 {
							position: relative;
							width: 100%;
							height: 545px;
							max-height: 75vh;
						}
					
				

Press on the button below to load the AJAX-ZOOM viewer into this container.

Alternatively, there is a possibility to calculate the height with CSS by mixing the viewport-units and pixel values.

					
						max-height: calc(90vh - 70px);
					
				

The above means that the container's height should be no larger than 90% of the browser's inner-window height minus 70 pixels. It makes sense if, for example, you have a navigation bar that is always visible at the top of the window, and you want to subtract its fixed height.

Setting a responsive CSS height to achieve specific proportions (aspect ratios) of the parent container by using CSS only.

The size of the container with ID example_container_5 is NaN px.

The above solutions do not keep fixed proportions of the container, which you might want to set depending on your images' aspect ratio. Bootstrap CSS has .embed-responsive and .embed-responsive classes to achieve that. However, you do not necessarily need to use the entire Bootstrap CSS library for this. All you need is to define three CSS-classes and create a structure with two nested containers:

					
						<div class="az_embed-responsive az_embed-responsive-test">
							<div class="az_embed-responsive-item" id="example_container_5">
							</div>
						</div>
					
				

Press on the button below to load the AJAX-ZOOM viewer into this container. Resize the browser window to confirm that the proportions stay the same.

The CSS for the three classes looks as following:

					
						.az_embed-responsive {
							position: relative;
							box-sizing: border-box;
							width: 100%;
							height: 0;
							display: block;
							padding: 0;
							overflow: hidden;
						}

						.az_embed-responsive-item {
							box-sizing: border-box;
							position: absolute;
							top: 0;
							bottom: 0;
							left: 0;
							width: 100%;
							height: 100%;
							border: 0;
						}

						.az_embed-responsive-test {
							padding-top: 75%;
						}
					
				

Apparently, it needs an explanation as the height of the .az_embed-responsive container is set to 0px. What happens here is that this outer container has a second CSS class. We name this class az_embed-responsive-test. Bootstrap's native classes that correspond to the ".az_embed-responsive-test" class are, e.g. .embed-responsive-4by3, .embed-responsive-1by1 or embed-responsive-21by9. The difference between them is only the CSS padding-top value with a percentage as the unit. For whatever hardly understandable reason, it creates vertical padding related to the width of the same element. If you set padding-top to 100%, you create a square (1 by 1). If you set padding-top to 50%, you create a rectangle with an aspect ratio 2 by 1. The actual reason is that within the CSS "box model", a margin or padding specified as a percentage calculates based on the calculated WIDTH of the same element, and this rule also applies to a vertical margin or padding!

Creating padding, however, does not do the trick alone. You cannot put your content in this element directly and maintain the aspect ratio because the calculated CSS height is still 0 pixels. The inner container of .az_embed-responsive with .az_embed-responsive-item class does the trick by being positioned absolutely and having width and height of 100%, as well as top and left coordinates defined. Since the .az_embed-responsive is relatively positioned, the boundaries of the absolute positioned child container are indicated by the top container. Also, because it is positioned absolutely, it overlays the padding by breaking out of the layout. Thus you get a container whereinto you can place something without destroying the aspect ratio.

However, the above does not need to be fully understood for using it. Just create the nested div elements and set the padding-top to the desired proportion. Given an aspect ratio of, e.g., 16:9, you can calculate the value as 9/16*100. That is 56.25%. The value can be above 100%. For portraits, e.g., 9:16, the value is 16/9*100, which is about 177.7778%. You could also use the calc CSS function to take into account certain UI elements of the viewer, which are not responsive, e.g.

					
						.az_embed-responsive-test {
							padding-top: calc(56.25% + 48px);
						}
					
				

A significant drawback of this approach is that you cannot responsively limit the height of this composition with standard CSS. The outer .az_embed-responsive container still has a calculated height of 0px, so max-height can't be applied to it, and unfortunately, there are no CSS properties such as min-padding or max-padding. Although you can limit the height of the inner .az_embed-responsive-item container by max-height CSS value, it does not reduce the dimensions or, better to say, the room that the outer container claims for itself. So when the max-height CSS limitation effectively applies, you end up with an extensive space below the inner container with the actual content. The JavaScript solution in the next section fixes this problem.

Creating a responsive container with a fixed aspect ratio and limit the height by using CSS and JavaScript

The size of the container with ID example_container_6 is NaN px.

As described in the last paragraph of the previous section, there is no easy way to set a max-height for the containers that preserve an aspect ratio. To achieve this, we have created a simple JavaScript plugin.

The HTML and CSS are the same as in the previous section except that .az_embed-responsive-test class is not present, and the outer container with .az_embed-responsive class has got an ID to differentiate it from other instances on this page.

					
						<div class="az_embed-responsive" id="az_embed-responsive-js">
							<div class="az_embed-responsive-item" id="example_container_6">
							</div>
						</div>
					
				

Press on the button below to load the AJAX-ZOOM viewer into this container. Resize the browser window to confirm that the proportions stay the same and decrease when the resulting value of 80% from the height of the window is smaller than the height of the container with the viewer.

Opposingly to the previous solution, the .az_embed-responsive-test CSS class is redundant, and it is not present in the HTML of this instance because the padding-top that creates the proportions is set with JavaScript now!

Limiting the viewer's height makes even more sense for portrait-orientated images, a standard in the fashion niche. When a user deliberately zooms and pans, it is different than when the displayed image is too large and is not visible as a whole on the screen.

Below is the file with the JavaScript plugin that you need to include in your HTML once. It manages the padding of the outer container, and you can set all the limits that were not easily possible to set in previous solutions.

					
						<!-- Helper plugin to deal with embed-responsive class -->
						<script type="text/javascript" src="/axZm/extensions/jquery.axZm.embedResponsive.js"></script>
					
				

As with any jQuery plugin, the jquery.axZm.embedResponsive plugin applies to a selector. Here, the outer container with the id ajaxZoomContainerParent is the selector. It is, however, applicable to any other ID or a different selector. The plugin is part of the AJAX-ZOOM package, so you do not have to download it separately.

					
						<script type="text/javascript">
						jQuery("#ajaxZoomContainerParent").axZmEmbedResponsive({
							// Aspect ratio e.g. 16:9
							ratio: '20:15',

							// Defines padding bottom, 100 results in 1:1 proportion
							prc: false,

							// Limit against the height of the browser window (%)
							heightLimit: 80,

							// Substract pixel value from heightLimit
							deduct: 20,

							// Minimal height of the container
							minHeight: 150,

							// Override options depending on window width
							maxWidthArr: [
								/*
								{
									maxWidth: 768,
									ratio: '1:1',
									prc: false,
									heightLimit: 80,
									deduct: 20,
									minHeight: 150,
								}
								*/
							]
						});
						</script>
					
				

The options ratio and prc are just alternative ways to define the proportions of the container. You can choose between the two options. To the maxWidthArr option, which is an array, you can add objects containing the same main options. The extra maxWidth option in each of the objects defines the breakpoints. It is the equivalent of using e.g. the @media (max-height: 768px) in CSS meaning that you can override CSS values depending on the width of the viewport of the browser's window.

You can apply jQuery.axZmEmbedResponsive to a container more than once without previously destroying it. The plugin does it automatically, and even when AJAX-ZOOM viewer is already present in the inner container, it adjusts to the new dimensions automatically as well.

Comments (1)

Yermo 2019-12-11 18:09:56
Yermo Thank you for taking the time to write this article. This is the most thorough explanation of this topic I have been able to find anywhere on the web and is of great help.

Vielen dank!

-- Yermo

Leave a Comment

Looking for a place to add a personal image? Visit www.gravatar.com to get Your own gravatar, a globally-recognized avatar. After you're all setup, your personal image will be attached every time you comment.

To use live-support-chat, you need to have Skype installed on your device. In case live support over Skype is not available immediately, please leave us a message or send an email by using the contact form.

We answer every inquiry or question that relates to the AJAX-ZOOM software!

Live-Support-Chat