When using the new CSS feature object-fit
, how can I access the resulting dimensions that the browser has chosen by JavaScript?
So let's assume foo.jpg
is 100x200 pixels. The browser page / viewport is 400px wide and 300px high. Then given this CSS code:
img.foo { width: 100%; height: 100%; object-fit: contain; object-position: 25% 0; }
The browser would now show the image on the very top with correct aspect ration stretching to the very bottom on the second quarter from the left. This results in those image dimensions:
So what JavaScript call (jQuery allowed) would give me those numbers that I've calculated manually? (Note: the CSS information themselves are not known by the JavaScript as the user could overwrite them and even add stuff like min-width
)
To play with the code I've created a fiddle: https://jsfiddle.net/sydeo244/
The object-fit CSS property sets how the content of a replaced element, such as an <img> or <video> , should be resized to fit its container. You can alter the alignment of the replaced element's content object within the element's box using the object-position property.
contain - The image keeps its aspect ratio, but is resized to fit within the given dimension. cover - The image keeps its aspect ratio and fills the given dimension. The image will be clipped to fit. none - The image is not resized.
Adding a Background to an Image With object-fit: contain # We would benefit from that when also using object-fit: contain . In the example below, we have a grid of images. When the aspect ratios of the image and the container are different, the background color will appear.
For object-fit to work, the image itself needs a width and height . In the OP's CSS, the images do not have width and/or height set, thus object-fit cannot work.
Thanks to @bfred I didn't have to make the initial method.
Here is an extended (and rewritten) version of his, that does calculate the object-position
values as well.
function getRenderedSize(contains, cWidth, cHeight, width, height, pos){ var oRatio = width / height, cRatio = cWidth / cHeight; return function() { if (contains ? (oRatio > cRatio) : (oRatio < cRatio)) { this.width = cWidth; this.height = cWidth / oRatio; } else { this.width = cHeight * oRatio; this.height = cHeight; } this.left = (cWidth - this.width)*(pos/100); this.right = this.width + this.left; return this; }.call({}); } function getImgSizeInfo(img) { var pos = window.getComputedStyle(img).getPropertyValue('object-position').split(' '); return getRenderedSize(true, img.width, img.height, img.naturalWidth, img.naturalHeight, parseInt(pos[0])); } document.querySelector('#foo').addEventListener('load', function(e) { console.log(getImgSizeInfo(e.target)); });
#container { width: 400px; height: 300px; border: 1px solid blue; } #foo { width: 100%; height: 100%; object-fit: contain; object-position: 25% 0; }
<div id="container"> <img id="foo" src="http://dummyimage.com/100x200/000/fff.jpg"/> </div>
Side note
It appears that object-position
can have more than 2 values, and when, you need to adjust (or add) which parameter returns the left position value
There's an npm package called intrinsic-scale
that will calculate that for you, but it doesn't support the equivalent of object-position
: https://www.npmjs.com/package/intrinsic-scale
This is the whole code:
// adapted from: https://www.npmjs.com/package/intrinsic-scale function getObjectFitSize(contains /* true = contain, false = cover */, containerWidth, containerHeight, width, height){ var doRatio = width / height; var cRatio = containerWidth / containerHeight; var targetWidth = 0; var targetHeight = 0; var test = contains ? (doRatio > cRatio) : (doRatio < cRatio); if (test) { targetWidth = containerWidth; targetHeight = targetWidth / doRatio; } else { targetHeight = containerHeight; targetWidth = targetHeight * doRatio; } return { width: targetWidth, height: targetHeight, x: (containerWidth - targetWidth) / 2, y: (containerHeight - targetHeight) / 2 }; }
And the usage would be:
getObjectFitSize(true, img.width, img.height, img.naturalWidth, img.naturalHeight);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With