5

How can I make a div's sizing properties behave exactly like they do for image tags, if the div's background is an image?

The idea is to duplicate the way an image tag behaves in this code snippet:

div{
  background-color: #2DBCFF;
  text-align:center;
  box-sizing: border-box;
  font-size:0;
}
img{
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  vertical-align: middle;
}
<div style="width:300px; height: 150px; line-height: 150px;"><!-- <<<CSS props controlled
 and changed with JS

--><img src="https://i.stack.imgur.com/o23xS.jpg"><!--

--></div>

NOTE :

the div's height and width properties are changed with JS

FOR CLARITY :

I want the CSS properties width, height, max-width, and max-height properties behave the same as if the div tag was an image tag. (aspect ratio preserved, size of div is based on image, etc...)

John Slegers
  • 45,213
  • 22
  • 199
  • 169
  • 1
    What do you mean? Behave how? – StudioTime Feb 20 '16 at 11:34
  • width, height, max-width, and max-height properties behave the same in relation to the image –  Feb 20 '16 at 11:35
  • So you want to use width and height of image and set it as width and height of div and also set that img as background of that div? – Nenad Vracar Feb 20 '16 at 11:43
  • yes with concerns to aspect ration, but with max height and max width props –  Feb 20 '16 at 11:44
  • Somewhat similar [question](http://stackoverflow.com/questions/1495407/maintain-the-aspect-ratio-of-a-div-with-css). – alesc Feb 20 '16 at 11:58
  • @DaMaxContent Is this what you are looking for https://jsfiddle.net/Lg0wyt9u/65/? You enter image url with data attr and it takes width and height and sets it as `max-width` and `max-height` of div – Nenad Vracar Feb 20 '16 at 12:01

2 Answers2

4

There was a lot of modification done to this faux img (.imgDiv), the reason why it's harder than it should be is because img is a replaced element and div is not, this article will explain the differences (author's second language is English, but the grammatical errors do not hinder comprehension.)

Example 1. & 2. The following are the original img (.control) and .imgDiv:

// Example 1. `.control`: `position: relative` was added for demo purposes.

  .control {
    position: relative;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    vertical-align: middle;
  }

  .imgDiv {
    position: relative;
    display: inline-block;
    width: 100%;
    height: 100%;
    vertical-align: middle;
    background-image: url(https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png);
    background-repeat: no-repeat;
    background-size: contain; 
    background-position: center;
  }

In short, if you want to mimic a replaced element, you should use a replaced element. What determines a replaced element's dimensions is not itself, but what it has (ie content of an img would be a png file), a non-replaced element is not determined by it's content (ie div). So I figured a video element would be a more suitable img replacement.

Example 3. & 4. A quick breakdown:

 // Do not copy this code, I broke it into pieces so you don't have to scroll

 <div class="case" style="width:300px; height: 150px; line-height: 150px;">

  <video id="vid1"

     poster="https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png" 

     width="300" height="150"></video>

</div>

// Do not copy this code, I broke it into pieces so you don't have to scroll

<video id="vid2"

   poster="https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"

   src="https://glpjt.s3.amazonaws.com/so/av/vs8s3.mp4" 

   width="100%" height="auto">

</video> 
  • Attributes:
    • poster: This attribute accepts a path to an image then displays the image until the video element plays. Without going any further, we can see that thevideo element can stand in for img easily.
    • controls: They are removed since we are only interested in the image aspects of the video element.
    • src: I assigned this attribute a small video (86.6KB). I don't think we need it, I just added it in for testing.
    • width and height: A video element by itself can be responsive just by setting width to 100% and height to auto.

Plunker

Snippet

<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <title>35522592</title>
  <style>
    body {
      counter-reset: exp;
    }
    span.txt:before {
      counter-increment: exp;
      content: "Example " counter(exp)". ";
    }
    .box {
      position: relative;
      display: inline-table;
      min-width: 300px;
      min-height: 150px;
      margin: 5% auto;
    }
    .case {
      position: relative;
      background-color: #2DBCFF;
      text-align: center;
      box-sizing: border-box;
      font-size: 0;
      margin: 20px;
    }
    .control {
      position: relative;
      max-width: 100%;
      max-height: 100%;
      width: auto;
      height: auto;
      vertical-align: middle;
    }
    .imgDiv {
      position: relative;
      display: inline-block;
      width: 100%;
      height: 100%;
      vertical-align: middle;
      background-image: url(https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png);
      background-repeat: no-repeat;
      background-size: contain;
      background-position: center;
    }
    .big {
      font-size: 24px;
    }
    .txt {
      margin: 0 0 15px 20px;
    }
    #vid1,
    #vid2 {
      fit-object: contain;
    }
    #b2 {
      background: #F06;
      min-width: 40vw;
      max-width: 100%;
      height: auto;
    }
  </style>
</head>

<body>
  <section class="box">
    <div class="case" style="width:300px; height: 150px; line-height: 150px;">
      <img class="control" src="https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png">
    </div>
    <span class="txt">This is the image<b class="big">&#8679;</b> from the OP.</span>
    <div class="case" style="width:300px; height: 150px; line-height: 150px;">
      <div class="imgDiv"></div>
    </div>
    <span class="txt">This div <b class="big">&#8679;</b> uses the property background-image.</span>
    <div class="case" style="width:300px; height: 150px; line-height: 150px;">
      <video id="vid1" poster="https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png" width="300" height="150"></video>
    </div>
    <span class="txt"><b class="big">&#8679;</b>This is a video  element it only has an image, no video.</span>
  </section>

  <section class="box" id="b2">
    <video id="vid2" poster="https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png" src="https://glpjt.s3.amazonaws.com/so/av/vs8s3.mp4" width="100%" height="auto"></video>
    <span class="txt">This is a video  element <b class="big">&#8679;</b>it has an image and a video.</span>
  </section>
</body>

</html>
Roland Soós
  • 3,125
  • 4
  • 36
  • 49
zer00ne
  • 41,936
  • 6
  • 41
  • 68
  • the link to the article is no longer working. do you have another one? and can you please take a look at my (similar) question? thanks! https://stackoverflow.com/questions/60167477/align-the-bottom-of-a-child-element-with-the-parents-baseline/60175226 – cipak Feb 12 '20 at 11:48
  • Here is the article: https://web.archive.org/web/20170210160818/http://richkode.me/something-about-css/ – Roland Soós Mar 25 '20 at 06:47
2

If what you mean is that the div width and height change with respect to the aspect ratio like the image then you can rely on CSS by using padding like this:

div {
  width: 100%;
  max-width: 300px;
  height: 0;
  box-sizing: content-box;
  padding-bottom: 50%; /* Aspect ratio of the width/height */
}

No JS needed.

Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
Ahmad Alfy
  • 13,107
  • 6
  • 65
  • 99
  • I have looked into that. Problem: max-width needs to be width of parent element like it was for the image tag in my snippent. Also, does not use max-height property. –  Feb 20 '16 at 11:40
  • Then change `max-width` to be 100% ... This will make it the same width of the parent. – Ahmad Alfy Feb 20 '16 at 11:41
  • max-height is still an issue. –  Feb 20 '16 at 11:42