Make element same width as dynamically sized image?

后端 未结 5 1301
逝去的感伤
逝去的感伤 2021-02-18 23:59

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

相关标签:
5条回答
  • 2021-02-19 00:18

    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

    0 讨论(0)
  • 2021-02-19 00:18

    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

    0 讨论(0)
  • 2021-02-19 00:32

    There's a very little known CSS property that's made for what you require: min-content. What this does, is:

    • Uses intrinsic value, meaning it adapts to it's content.
    • Reduces the width of the container automatically so that an image fits inside it perfectly.
    • If text content needs to wrap inside the container, it should.

    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:

    • Optional
    • Recommended
    • Required

    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.

    0 讨论(0)
  • 2021-02-19 00:35

    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>

    0 讨论(0)
  • 2021-02-19 00:39

    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>

    0 讨论(0)
提交回复
热议问题