Reputation:
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.sstatic.net/o23xS.jpg"><!--
--></div>
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...)
Upvotes: 6
Views: 5700
Reputation: 13381
We no longer need to rely on padding hacks to maintain the aspect ratio. Thankfully, CSS now provides us with a new property aspect-ratio
that can be used to achieve the needed result and it's universally supported across the browsers
div {
width: 100%;
aspect-ratio: 16 / 9;
}
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.
Upvotes: 3
Reputation: 44088
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>
video
element plays. Without going any further, we can see that thevideo
element can stand in for img
easily.video
element.video
element by itself can be responsive just by setting width to 100% and height to auto.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">⇧</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">⇧</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">⇧</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">⇧</b>it has an image and a video.</span>
</section>
</body>
</html>
Upvotes: 4