What is the most efficient way to calculate the width of an image relative to it's containing div in css?
I have the following snippet which sets #image1.width
to a percentage that is relative to the width of its parent. I'm using a percentage because I need the image to scale proportionately to the parent when the screen is resized.
div { position: relative; display: block; width: 100%; } #image1 { position: absolute; left: 10%; top: 10%; width: 29.43%; height: auto; } #under { width: 100%; }
<div> <img id="image1" src="http://placehold.it/206x115"> <img id="under" src="http://placehold.it/700x300/ff00f0/ffffff"> </div>
It is currently working as intended, except that I have to manually calculate the width percentage for every single image. i.e.
#image1 dimensions == 206x115 #under dimensions == 700x300 new #image1.width % == #image1.width / #under.width == 206/700 == ~29.43%
What I want to know is if there id a calc()
method or similar I can implement to ease/streamline this process?
I was going to use width: calc(100% / 700)
however this obviously will not work when the screen size changes.
To re-iterate, it is imperative that the #under
image scales with the screen size and the #image
remains proportionate.
I want the natural image ratios preserved with one another (i.e. an image that is one quarter the size of the other will remain as such at all browser widths).
Note: The html
can be reconfigured in any way to achieve this.
Target browsers: Chrome, Firefox, Edge.
Comment on @Obsidian Age's answer (end of first bounty 31.03.17):
Unfortunately @Obsidian Age's answer is not correct - it is close but not quite and I just wanted to clarify this here... Below is a snippet from his answer... Note that I think it is a good answer, just clarifying why it has not been accepted:
:root { --width: 90vw; // Must be viewport-driven } #image1 { width: calc(var(--width) / 3); // The 3 can be replaced with any float }
Setting --width: 90vw
what happens if body
or div
have a max-width
set? This is also very hard to calculate for all devices when factoring in viewport-scaling
.
#image1 { width:calc(var(--width) / 3); }
This equates to calc(90vw / 3)
which is 30vw
which would equate to 30% of the images width. But how do we work out the number to divide by? Well it's back to where we started... width:calc(var(--width) * calc(206/700*100));
And this is why I have not accepted this answer.
To auto-resize an image or a video to fit in a div container use object-fit property. It is used to specify how an image or video fits in the container. object-fit property: This property is used to specify how an image or video resize and fit the container.
Those images on the site you linked to are actual size, so the simple answer is just to resize the image. You can't really do this without "stretching" the image if the image happens to be less than 300px wide or tall, but you can do it without changing the ratio, which is what I think you mean.
If you try to put an image inside a <div> element that has borders, you will see an extra white space (around 3px) at the bottom of image. It happens because image is an inline-level element so browser adds some whitespace under the baseline to adjust other inline elements.
Unfortunately, CSS has no parent selector. While you can't make an element relative to the parent directly with CSS, what you can do with pure CSS is set a variable that both elements make use of:
:root { --width: 90vw; // Must be viewport-driven }
Now you can use this variable as both the (fixed) width of the parent element, and the calculation-driven width of the child:
#under { width: var(--width); } #image1 { width: calc(var(--width) / 3); // The 3 can be replaced with any float }
Note that the variable must either be a fixed unit, or be relative to the viewport. If it were percentage-based, both #under
and #image1
would base their width off of their respective parents. In order to have this work responsively, it must be based off of the viewport.
:root { --width: 90vw; } div { position: relative; display: block; width: 100%; } #image1 { position: absolute; left: 10%; top: 10%; width: calc(var(--width) / 3); height: auto; } #image2 { position: absolute; left: 25%; top: 10%; width: 10%; height: auto; } #under { width: var(--width); }
<div> <img id="image1" src="http://placehold.it/206x115"> <img id="under" src="http://placehold.it/700x300/ff00f0/ffffff"> </div>
I've also created a JSFiddle of this here, where you can see both elements scale when the viewport resizes.
Hope this helps! :)
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