Context
I am making an image gallery slider (horizontal slider). I have a wrapper div .wrap
set to 100% width and height of the window. I have another child div .image_wrap
that wraps an <img>
. It's dimensions are responsive so that that it's width and height vary depending on the orientation of the viewport; landscape or portrait. These dimensions are determined using media queries. The image is also responsive so that it's height or width is 100% of .image_wrap
. If the viewport is landscape, then .image_wrap
will have it's height set to 90vh
and it's width will remain auto
. If the viewport is portrait, then the situation is reversed. Now, I need the auto
values set on both .image_wrap
and <img>
because I want to always maintain the aspect ratio of each image, as they can vary in size and orientation.
Problem
As for the div .description
, I want it's width to always be the same as .image_wrap
. Since, at times, .image_wrap
will have a width of auto
, the inner text of <p>
will cause .description
width to increase, thus causing .image_wrap
width to increase beyond the width of <img>
. Normally, the text is brief and this is not a problem as you can see in the first example image below. But when the text gets longer, my problem arises, as you can see in the second example image below. I have my CSS set up with width at 100%
for the appropriate selectors. .bg
is just a background div with an opacity to darken and add semi-transparency for .description
.
What I've tried
Since I am using the flexbox model for my styling, I have tried various approaches:
flex-grow:1;
on.description
. But that affects height not width.I even tried removing the flex properties on
.description
and using traditional methods for it's children. But I still get a larger width on.image_wrap
than<img>
.I started thinking that because I am creating all elements dynamically in Javascript, that my browser is just loading the DOM first and then adding CSS rules. So I tried playing around with inline styles before and after the DOM loads the elements to see what happens. Either way the width of
.image_wrap
seems to never change on the current image. Note that the page is already loaded. The user triggers creation of the gallery with an onclick event.
My Markup
<html>
<body>
<div class="wrap">
<div class="image_wrap">
<img src="myimage.jpg" />
<div class="description">
<div class="bg"></div>
<p>I am a description and I want to wrap when I am too long. I am a description and I want to wrap when I am too long.</p>
</div>
</div>
</div>
</body>
</html>
My CSS
.wrap {
display:flex;
width:100%;
height:100%;
margin:0px;
border:0px;
padding:0px;
justify-content:center;
align-items:center;
}
.image_wrap {
display:flex;
width:auto;
height:auto;
max-width:90vw;
max-height:90vh;
margin:0px;
border:0px;
padding:0px;
flex-direction:column;
}
img {
width:auto;
height:auto;
margin:0px;
border:0px;
align-self:center;
}
.description {
display:block;
position:relative;
width:100%;
max-width:100%;
height:auto;
margin:-20vh 0px 0px 0px;
border:0px;
padding:0px;
box-sizing:border-box;
align-self:center;
}
.description .bg {
display:block;
position:absolute;
left:0px;
top:0px;
width:100%;
height:100%;
margin:0px;
border:0px;
padding:0px;
background-color:Black;
opacity:0.5;
z-index:0;
}
.description p {
position:relative;
width:100%;
margin:0px;
border:0px;
padding:1em;
color:White;
font-size:2.5vh;
text-align:center;
box-sizing:border-box;
flex-grow:1;
z-index:1;
}
@media (orientation: landscape) {
.image_wrap { height:90vh;}
img { height:100%; }
}
@media (orientation: portrait) {
.image_wrap { width:90vw; }
img { width:100%; }
}
My Javascript
This is just some of the commands. The script is large and there are no inline styles, so I didn't see the need to show the rest. I can provide more of the script upon request.
image_wrap.appendChild(img) ;
image_wrap.appendChild(description) ;
description.appendChild(bg) ;
description.appendChild(p) ;
wrap.appendChild(image_wrap) ;
What I want
I want .description
to have a width that is always the same as <img>
. If the text is too long to fit into .image_wrap
then it should wrap. Since .image_wrap
sometimes has a width of auto
, the inner text of <p>
forces the width of .image_wrap
to increase. I do not want that, but I need the width to be auto so that it's dimensions are the same as the image. Example images below.
[![enter image description here][3]][3]
[3]:
.wrap {
display:flex;
width:100%;
height:100%;
margin:0px;
border:0px;
padding:0px;
justify-content:center;
align-items:center;
}
.image_wrap {
display:flex;
width:auto;
height:auto;
max-width:90vw;
max-height:90vh;
margin:0px;
border:0px;
padding:0px;
flex-direction:column;
}
img {
width:auto;
height:auto;
margin:0px;
border:0px;
align-self:center;
}
.description {
display:block;
position:relative;
width:100%;
max-width:100%;
height:auto;
margin:-20vh 0px 0px 0px;
border:0px;
padding:0px;
box-sizing:border-box;
align-self:center;
}
.description .bg {
display:block;
position:absolute;
left:0px;
top:0px;
width:100%;
height:100%;
margin:0px;
border:0px;
padding:0px;
background-color:Black;
opacity:0.5;
z-index:0;
}
.description p {
position:relative;
width:100%;
margin:0px;
border:0px;
padding:1em;
color:White;
font-size:2.5vh;
text-align:center;
box-sizing:border-box;
flex-grow:1;
z-index:1;
}
@media (orientation: landscape) {
.image_wrap { height:90vh;}
img { height:100%; }
}
@media (orientation: portrait) {
.image_wrap { width:90vw; }
img { width:100%; }
}
<html>
<head>
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body>
<div class="wrap">
<div class="image_wrap">
<img src="https://i.stack.imgur.com/SBpCq.jpg" />
<div class="description">
<div class="bg"></div>
<p>I am a description and I want to wrap when I am too long. I am a description and I want to wrap when I am too long.</p>
</div>
</div>
</div>
</body>
</html>