Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make element same width as dynamically sized image?

Tags:

html

css

I have a responsive slideshow-type layout with captions below each image.

I'm attempting to get the caption to be the same width as the image. The problem is that the image is scaled to fit in the browser vertically, and my captions are the getting the width of the image prior to scaling.

Fiddle

#big_container {
  display:block;
	position:relative;
	width:100%;
	padding-bottom:40%;
	white-space:nowrap;
	overflow-x:scroll;
	overflow-y:hidden;
}
    
#big_container>div {
	position:absolute;
	top:0;
	right:0;
	bottom:0;
	left:0;
}

.little_container {
	display:inline-block;
	height:100%;
	width:100%;
	text-align:center;
}

#big_container figure {
  display:inline-block;
	height:100%;
	margin:0;
}

figure img {
	max-height:calc(100% - 40px); /* subtract height of caption */
}

figcaption {
	display:block;
	width:100%;
	text-align:left;
	box-sizing:border-box;
	margin:0;
	padding:10px;
	line-height:20px;
	background-color:#ddd;
}
<div id="big_container">
  <div>

  <div class="little_container">
      <figure>
        <img src="http://placekitten.com/500/440">
        <figcaption>
          have a kitty!!1
        </figcaption>
      </figure>
  </div>
  
  <div class="little_container">
      <figure>
        <img src="http://placekitten.com/450/400">
        <figcaption>
          moar kitty!
        </figcaption>
      </figure>
  </div>
  
  <div class="little_container">
      <figure>
        <img src="http://placekitten.com/300/440">
        <figcaption>
          too many kitty..
        </figcaption>
      </figure>
  </div>
  
  </div>
</div>

How can I make a caption which is scaled based on the width of a fluid image?
I'm hoping for a pure-css solution.

Update
It turns out my above attempt partially works in chrome and opera, but exhibits some odd behavior. I haven't found any bug reports on the subject, but I can't help wondering if this might be considered a bug in the browser.


For clarity, here's a brief outline of my exact requirements:

  • Caption element must be the same width as the image (it'd be nice to be able to left or right align the caption text to the edge of the image)
  • Image must not be cropped or stretched
  • Image and caption must both fit in their container (which may be fluid), using as much room as possible.
  • Above rules should hold true for images of any dimension
  • CSS only (compatibility with old browsers not a major concern, but it is a plus)

The html markup can be changed.

like image 295
gandalf3 Avatar asked Jan 30 '16 03:01

gandalf3


People also ask

How do you change the size of a dynamic image in HTML?

One of the simplest ways to resize an image in the HTML is using the height and width attributes on the img tag. These values specify the height and width of the image element. The values are set in px i.e. CSS pixels.

How do I make div width auto adjust?

Using width, max-width and margin: auto; Then, you can set the margins to auto, to horizontally center the element within its container. The element will take up the specified width, and the remaining space will be split equally between the two margins: This <div> element has a width of 500px, and margin set to auto.

How do I set dynamic width?

Answer: Use the JavaScript width() method You can set the width of a <div> box dynamically using the jQuery width() method.

How do I auto-resize an image to fit a div container?

To auto-resize an image or a video to fit in a div container use object-fit property. It is used to specify how an image or video fits in the container. object-fit property: This property is used to specify how an image or video resize and fit the container.

How do I make the background image fit my screen size?

Using CSS, you can set the background-size property for the image to fit the screen (viewport). The background-size property has a value of cover . It instructs browsers to automatically scale the width and height of a responsive background image to be the same or bigger than the viewport.


1 Answers

Updated

Based on the exact requirements you set for this question, it can't be solved with CSS only.

This is the best I was able to come up with.

Fiddle demo 1 (fixed height for text, image fully visible)
Fiddle demo 2 (semitransparent scaleable text on top of image with animation)

The trick I mainly used is having a hidden img to make up for the space and then a background-image to scale to maximum width/height with kept ratio.

I added the inline style background-image for convenience, so content can be handled within the html.

To make it perfect, a script is needed, which calculate the caption's content and adjust the image's/caption's reduction/height.

Snippet demo 1

html, body {
  margin: 0;
  white-space: nowrap;
  overflow-y: hidden;
}
.container {
  display: inline-block;
  white-space: normal;
  width: 100%;
}
.wrap {
  margin: 0 auto;
  display: table;
}
.image {
  display: table-cell;
  background-position: center bottom;
  background-repeat: no-repeat;
  background-size: contain; 
}
.image img {
  visibility: hidden;
  max-width: 100vw;
  min-width: 100%;
  height: calc(100vh - 80px);
}
.caption {
  display: table-caption;
  caption-side: bottom;
  height: 40px;
  line-height: 22px;
  padding: 8px;
  background-color: #ddd;
  overflow: hidden;
}
.right {
  text-align: right; 
}
<div class="container">
  <div class="wrap">
    <div class="image" style="background-image: url('http://placekitten.com/450/300')">
      <img src="http://placekitten.com/450/300">
    </div>
    <div class="caption right">
      moar kitty!
      moar kitty!
      moar kitty!
    </div>
  </div>
</div>

<div class="container">
  <div class="wrap">
    <div class="image" style="background-image: url('http://placekitten.com/500/440')">
      <img src="http://placekitten.com/500/440">
    </div>
    <div class="caption">
      have a kitty!!1
      have a kitty!!1
      have a kitty!!1
      have a kitty!!1
      have a kitty!!1
      have a kitty!!1
      have a kitty!!1
    </div>
  </div>
</div>

<div class="container">
  <div class="wrap">
    <div class="image" style="background-image: url('http://placekitten.com/300/440')">
      <img src="http://placekitten.com/300/440">
    </div>
    <div class="caption">
      too many kitty..
      too many kitty..
      too many kitty..
    </div>
  </div>
</div>

Snippet demo 2

html, body {
  margin: 0;
  white-space: nowrap;
  overflow-y: hidden;
}
.container {
  position: absolute;
  height: 100%;
  display: inline-block;
  white-space: normal;
  width: 100%;
  background: white;
  opacity: 0;
}
.wrap {
  margin: 0 auto;
  display: table;
}
.image {
  display: table-cell;
  background-position: center bottom;
  background-repeat: no-repeat;
  background-size: contain; 
}
.image img {
  visibility: hidden;
  max-width: 100vw;
  min-width: 100%;
  height: 100vh;
}

.caption-wrap {
  display: table-caption;
  caption-side: bottom;
  position: relative;
}
.caption {
  position: absolute;  
  left: 0;
  right: 0;
  bottom: 100%;
  height: auto;
  line-height: 22px;
  padding: 8px;
  background-color: rgba(0,0,0,0.6);
  color: white;
}
.right {
  text-align: right; 
}
.center {
  text-align: center; 
}

.container:nth-child(3) {
  animation: xfade 12s 0s infinite;
}
.container:nth-child(2) {
  animation: xfade 12s 4s infinite;
}
.container:nth-child(1) {
  animation: xfade 12s 8s infinite;
}

@keyframes xfade{
  17% {
    opacity:1;
  }
  45% {
    opacity:0;
  }
  92% {
    opacity:0;
  }
}
<div class="container">
  <div class="wrap">
    <div class="image" style="background-image: url('http://placekitten.com/450/300')">
      <img src="http://placekitten.com/450/300">
    </div>
    <div class="caption-wrap">
      <div class="caption right">
        moar kitty!
        text .. right aligned
      </div>
    </div>
  </div>
</div>

<div class="container">
  <div class="wrap">
    <div class="image" style="background-image: url('http://placekitten.com/500/440')">
      <img src="http://placekitten.com/500/440">
    </div>
    <div class="caption-wrap">
      <div class="caption">
        have a kitty!!1
        have a kitty!!1
        text .. left aligned
      </div>
    </div>
  </div>
</div>

<div class="container">
  <div class="wrap">
    <div class="image" style="background-image: url('http://placekitten.com/300/440')">
      <img src="http://placekitten.com/300/440">
    </div>
    <div class="caption-wrap">
      <div class="caption center">
        text .. centered
      </div>
    </div>
  </div>
</div>
like image 122
Asons Avatar answered Oct 28 '22 03:10

Asons