Wednesday, March 29, 2017

img width relative to containing div

Leave a Comment

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 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;  }    #image2 {    position: absolute;    left: 25%;    top: 10%;    width: 10%;    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% 

Is there a calc() method or similar I can implement to ease 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. Thanks for the current answers however neither solve the issue as of yet.

Note: The html can be reconfigured in any way to achieve this.

3 Answers

Answers 1

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

Answers 2

I realize that the question prompts for a pure CSS solution, but I liberally interpreted that as meaning "no JavaScript".

In that vein, here's a solution using an embedded SVG:

<svg xmlns="http://www.w3.org/2000/svg"        xmlns:xlink="http://www.w3.org/1999/xlink"       width="100%" viewBox="0 0 700 300">           <image x="0" y="0"        xlink:href="http://placehold.it/700x300/ff00f0/ffffff"/>    <image x="10%" y="10%"        xlink:href="http://placehold.it/206x115"/>  </svg>

Answers 3

The best approach I think would be to eliminate width & use scale to fit the div, but the problem is scale transform do not accept any unit value, such as % or px or vw/vh!

.common_img_class{     transform: scale(calc(100vw/700)); /* this won't work! */     /* Idea here is to let image take is original width & then scale with respact to base image scaling. Base image scaling is detenined by *window_width/base_image _width*, here base image width is 700 as per you example */ } 

Thus second best I can think of is to eliminate manual calculation of percent. Use calc() function to do that for you.

#firsrt_img{     width: calc((206/700) * 100%); } #second_img{     width: calc((306/700) * 100%); } 

Here you still have to write width for all but atleast spared from percent or ratio calculation.

Note:
If anyone can help with first approach, their inputs are welcome.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment