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 i
Try utitlizing border
property
#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: block;
height: 100%;
margin: 0;
}
/*
set `border` to `45px` as background for `figacption`
set `border-left`, `border-right`, `border-top` to `0px`
*/
img {
max-height: calc(100% - 40px);
border: 45px solid #ffffd;
border-left: 0px;
border-right: 0px;
border-top: 0px;
}
/*
set `figcaption` elements
set `top` to `-50px` to center `content`
in vertical middle of `border`,
set `width` to `calc(100% / 3)` : number of `figure` elements
set `left` to `calc(100% / 3)` : position `content` at
horizontal center of `:after` , `border`
*/
figcaption {
top: -50px;
display: block;
position: relative;
background-color: transparent;
padding: 10px;
line-height: 20px;
box-sizing: border-box;
width: calc(100% / 3);
left: calc(100% / 3);
}
<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>
jsfiddle https://jsfiddle.net/601a5uqv/11/ , plnkr http://plnkr.co/edit/kHnA3GUTiGu3jm4tE8l4?p=preview
This seems like a good fit for flexboxes. They work in all the modern browsers (http://caniuse.com/#feat=flexbox) and in IE 10/11 with some special CSS as noted below.
Fiddle (For some reason the captions are stretching in IE on the Fiddle but it works in the browser.)
#big_container {
position:absolute;
top:0;
right:0;
bottom:0;
left:0;
padding-bottom: 40px;
display: flex;
flex-flow: horizontal;
align-items: flex-start;
justify-items: space-around;
flex-wrap: no-wrap;
/* For IE 10, 11 */
display: -ms-flexbox;
flex-direction: row;
-ms-flex-wrap: nowrap;
}
.little_container {
display:inline-block;
height:100%;
min-width: 100vw;
text-align:center;
display: flex;
flex-flow: vertical;
align-items: center;
justify-content:center;
flex-direction: column;
/* For IE 10, 11 */
display: -ms-flexbox;
-ms-flex-wrap: nowrap;
-ms-flex-direction: column;
-ms-flex-pack: start;
-ms-flex-align: center;
}
figure {
width: -moz-min-content;
width: -webkit-min-content;
position: relative;
text-align:center;
display: flex;
flex-direction: column;
flex-wrap: no-wrap;
align-items: stretch;
justify-content:center;
margin:auto;
/* For IE 10, 11 */
display: -ms-flexbox;
-ms-flex-direction: row;
-ms-flex-wrap: wrap;
-ms-flex-pack: center;
-ms-flex-align: center;
-ms-flex-line-pack: center;
}
figure img {
display:block;
text-align:left;
box-sizing: border-box;
margin:0;
max-height:calc(100% - 40px); /* subtract height of caption */
-ms-flex: 0 0 calc(100%-40);
display: block;
}
figcaption {
display:block;
text-align:left;
box-sizing: border-box;
margin:0;
padding:10px;
line-height:20px;
background-color:#ffffd;
-ms-flex: 1 1 60%;
max-width: 100%;
}
I took out the extra <div>
inside #big_container
that wrapped the smaller items because it did not seem necessary.
<div id="big_container">
<div class="little_container">
<figure>
<img src="http://placekitten.com/500/440">
<figcaption>
I has kitty!!
</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>
I has too many kitty. but I still need moar. Oh! No!!!!! I cannot get enuf!
</figcaption>
</figure>
</div>
</div>
Also, if you don't already know about them, look into the CSS Viewport units vw and vh. http://caniuse.com/#feat=viewport-units
There's a very little known CSS property that's made for what you require: min-content
. What this does, is:
Read this article: Design From the Inside Out With CSS Min-Content
There is one thing I'm not crazy about is the prefixes:
width: -moz-min-content;
width: -webkit-min-content;
width: min-content;
I added some resets and commented on which styles are:
Important CSS
figure {
height: 100%;
width: -moz-min-content;
/* REQUIRED */
width: -webkit-min-content;
/* REQUIRED */
width: min-content;
/* REQUIRED */
}
DEMO: https://plnkr.co/edit/6e1hYkK6lB2KVS3uvQy2?p=preview
BONUS: https://plnkr.co/edit/gahMFQScxQtkweo1G2jD?p=preview
I have made the captions longer and added the following CSS to show how you can wrap your captions and not breakout or extend the figcaption.
CSS Bonus
figcaption * {
white-space: pre-wrap;
/* RECOMMENDED */
}
Although not a requirement, I assume that in the near future you'll want to have captions that wrap without any hassle. I reviewed the others:
LGSon's will actually extend the image and figcaption, easily fixed with my solution I'm guessing.
guest271314's extends text overflow, I'm not sure what would fix that since it's not a container.
Ryan Litte's extends the figcaption, I believe that my solution could probably fix that as well.
In this fiddle, I've gotten the desired effect using different display
rules, as well as calculating using the vh
unit. I stripped out superfluous markup and CSS, but this should be a good starting point that you can use and build on.
Code:
#big_container {
white-space: nowrap;
}
.little_container {
display: inline-block;
width: 100%;
}
figure {
display: table;
margin: 0 auto;
}
img {
height: calc(100vh - 40px);
}
figcaption {
display: table-caption;
caption-side: bottom;
background-color: #ffffd;
padding: 10px;
line-height: 20px;
}
<div id="big_container">
<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>
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: #ffffd;
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>