Force div sizing to behave as img

Viewed 55

My goal is to create a div element which sizing follows the sizing of an img in all situation.

I know the dimensions of the image: 300*200 pixels.

Simulate the scaling of the img when img width is 100%: WORKS

img {
  display: block;
  max-width: 100%;
  width: 100%;
}

.image-placeholder {
  display: flex;
  max-width: 100%;
  background: blue;
}

.image-placeholder-inner {
  flex: 1 1 auto;
  position: relative;
}

.image-placeholder-inner img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
<div style="width:200px;" class="simulate-container">

  <div class="image-wrapper">
    <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
  </div>

  <div class="image-placeholder">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>
</div>

<div style="width:400px;" class="simulate-container">

  <div class="image-wrapper">
    <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
  </div>

  <div class="image-placeholder">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>
</div>

Simulate the scaling of the img when img width is auto: FAILS

Fails: The second blue rectangle should not be width 100%. .image-placeholder should have style="max-width:300px;" to solve this.

img {
  display: block;
  max-width: 100%;
  width: auto;
}

.image-placeholder {
  display: flex;
  max-width: 100%;
  background: blue;
}

.image-placeholder-inner {
  flex: 1 1 auto;
  position: relative;
}

.image-placeholder-inner img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
<div style="width:200px;" class="simulate-container">

  <div class="image-wrapper">
    <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
  </div>

  <div class="image-placeholder">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>
</div>

<div style="width:400px;" class="simulate-container">

  <div class="image-wrapper">
    <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
  </div>

  <div class="image-placeholder">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>

  <div class="image-placeholder" style="max-width:300px;">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>
</div>

Another solution to support width:auto and width: 100% is flexbox.

.flex {
  display: flex;
  flex-flow: column;
  align-items: flex-start;
}

img {
  display: block;
  max-width: 100%;
  width: 100%;
  /* width: auto; It does not matter in this example */
}

.image-placeholder {
  display: flex;
  max-width: 100%;
  background: blue;
}

.image-placeholder-inner {
  flex: 1 1 auto;
  position: relative;
}

.image-placeholder-inner img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
<div class="flex simulate-container" style="width:200px;">

  <div class="image-wrapper">
    <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
  </div>

  <div class="image-placeholder">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>
</div>

<div class="flex simulate-container" style="width:400px; background: yellow;">

  <div class="image-wrapper">
    <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
  </div>

  <div class="image-placeholder">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>
</div>

It might seem that the div sizing behaves as the img, but it is not. If we put this div into a grid or into a flex, the sizing will be different.

With Flexbox: FAILS Fail: The first blue box does not scale down.

.flex {
  display: flex;
  flex-wrap: wrap;

  justify-content: flex-start;
}

img {
  display: block;
  max-width: 100%;
  width: 100%;
}

.image-placeholder {
  display: flex;
  max-width: 100%;
  background: blue;
}

.image-placeholder-inner {
  flex: 1 1 auto;
  position: relative;
}

.image-placeholder-inner img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
<div class="simulate-container" style="width:200px;">
    <div class="flex">
      <div class="flex-item">

        <div class="image-wrapper">
          <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
        </div>
      </div>
      <div class="flex-item">

        <div class="image-placeholder">

          <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
            <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
          </div>
        </div>
      </div>
  </div>
</div>

<div class="simulate-container" style="width:400px; background: yellow;">
    <div class="flex">
      <div class="flex-item">

        <div class="image-wrapper">
          <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
        </div>
      </div>
      <div class="flex-item">

        <div class="image-placeholder">

          <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
            <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
          </div>
        </div>
      </div>
  </div>
</div>

With Grid: FAILS Fail: The blue box and the image has the same initial size. While the image scales down, the blue box still shows as full. They should have the same size over all three test.

.grid {
  display: grid;
  grid-template-columns: auto auto 1fr;
}

img {
  display: block;
  max-width: 100%;
  width: 100%;
}

.image-placeholder {
  display: flex;
  max-width: 100%;
  background: blue;
}

.image-placeholder-inner {
  flex: 1 1 auto;
  position: relative;
}

.image-placeholder-inner img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
<div class="simulate-container" style="width:200px;">
    <div class="grid">
      <div class="grid-item">

        <div class="image-wrapper">
          <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
        </div>
      </div>
      <div class="grid-item">

        <div class="image-placeholder">

          <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
            <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
          </div>
        </div>
      </div>
  </div>
</div>

<div class="simulate-container" style="width:400px; background: yellow;">
    <div class="grid">
      <div class="grid-item">

        <div class="image-wrapper">
          <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
        </div>
      </div>
      <div class="grid-item">

        <div class="image-placeholder">

          <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
            <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
          </div>
        </div>
      </div>
  </div>
</div>

<div class="simulate-container" style="width:800px; background: yellow;">
    <div class="grid">
      <div class="grid-item">

        <div class="image-wrapper">
          <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
        </div>
      </div>
      <div class="grid-item">

        <div class="image-placeholder">

          <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
            <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
          </div>
        </div>
      </div>
  </div>
</div>

The issue is somehow related to the fact that the div width:300px has different meaning compared to an img width:300px. I want to mimic the img behaviour, but I'm stuck trying. Is it impossible or is there a different way to overcome this situation?

My other idea would be to use an SVG as it behaves as image does, but would be better to solve this with plain div.

1 Answers

Did you tried canvas?

Other option is to use javascript combined with DOM change events and css width/height "px" properties or offset properties (offsetWidth and offsetHeight) to emulate it... but it will be heavy charge option, I only use js for more extreme cases.

Related