Note: I had to revise my answer because the initial solution was incompatible with Firefox (talk about irony). It also caused unexpected behaviors on different browsers due to flexbox usage for centering the image vertically and horizontally.
Let's break it down step by step.
To maintain the aspect ratio of an image while setting maximum dimensions, you can use the following CSS:
.img {
display: block;
max-height: 100%;
max-width: 100%;
height: auto;
width: auto;
}
Centering an element both vertically and horizontally typically involves three lines of code using flexbox. However, this approach led to issues when scaling images on certain browsers. Instead, we opt for text-align: center
for horizontal alignment and employ a technique involving a "Ghost Element" for vertical centering. For more details, refer to this CSS Tricks article. In essence, the centering method looks like this:
.parent {
text-align: center;
white-space: nowrap;
}
.parent:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em;
}
.centered-child {
display: inline-block;
vertical-align: middle;
}
Finally, combining scaling and centering, assuming that the HTML comprises only a single <img class="img" ...>
in the body:
html {
width: 100%;
height: 100%;
}
body {
margin: 0;
width: 100%;
height: 100%;
background-color: #333;
text-align: center;
}
body:before {
content: '';
width: 0;
height: 100%;
display: inline-block;
vertical-align: middle;
white-space: nowrap;
margin-left: -0.25em;
}
.img {
display: inline-block;
vertical-align: middle;
max-height: 100%;
max-width: 100%;
width: auto;
height: auto;
}
Adding Zoom Functionality
To enable image zooming, JavaScript (specifically jQuery) is required.
Preferably, avoid directly altering CSS attributes via JavaScript by defining two additional classes:
.img.is-zoomable {
cursor: zoom-in;
}
.img.is-zoomed {
cursor: zoom-out;
max-height: none;
max-width: none;
}
Upon click, the script toggles the is-zoomed
class, in addition to checking for zoom feasibility upon mouseover to apply the is-zoomable
class if appropriate.
$('.img').on('click', function() {
$(this).toggleClass('is-zoomed');
});
$('.img').on('mouseenter', function() {
var origWidth = this.naturalWidth;
var origHeight = this.naturalHeight;
var currWidth = $(this).width();
var currHeight = $(this).height();
if (origWidth !== currWidth || origHeight !== currHeight) {
$(this).addClass('is-zoomable');
}
});
And there you have it! Check out my CodePen for a practical demonstration.