Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

img width relative to containing div

Tags:

html

css

Original Question

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.



Goals

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.



Post Bounty Review

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.

like image 459
Zze Avatar asked Mar 14 '17 05:03

Zze


People also ask

How do I force an image to fit in a div?

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.

How do I fit a div image without stretching it?

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.

Why is there space between image and div?

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.


1 Answers

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! :)

like image 97
Obsidian Age Avatar answered Oct 06 '22 22:10

Obsidian Age