使元素的宽度与动态大小的图像相同?

时间:2016-01-30 03:39:08

标签: html css

我有一个响应式幻灯片式布局,每张图片下方都有字幕。

我试图让标题与图像的宽度相同。问题是图像被缩放以垂直放入浏览器,我的标题是在缩放之前获得图像的宽度。

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>

如何制作基于流体图像宽度缩放的标题?
我希望有一个纯粹的CSS解决方案。

更新
事实证明我的上述尝试partially works in chrome and opera, but exhibits some odd behavior。 我没有找到关于这个主题的任何错误报告,但我不禁想知道这是否会被视为浏览器中的错误。

为清楚起见,这里是我的确切要求的简要概述:

  • 标题元素的宽度必须与图像的宽度相同(能够将标题文本左右对齐到图像的边缘是很好的)
  • 图片不得裁剪或拉伸
  • 图像和标题必须都放在容器中(可能是流动的),尽可能使用空间。
  • 上述规则应适用于任何维度的图像
  • 仅CSS(与旧浏览器的兼容性不是主要问题,但它是一个加分)

html标记可以更改。

5 个答案:

答案 0 :(得分:4)

<强>更新

根据您为此问题设置的确切要求,无法仅使用CSS解决此问题。

这是我能想到的最好的。

Fiddle demo 1(文字固定高度,图片完全可见)
Fiddle demo 2(带有动画的图像顶部的半透明可缩放文本)

我主要使用的技巧是使用隐藏的img来弥补空间,然后background-image按比例缩放到最大宽度/高度。

为方便起见,我添加了内联样式background-image,因此可以在html中处理内容。

为了使其完美,需要一个脚本来计算字幕的内容并调整图像的标题缩小/高度。

Snippet demo 1

&#13;
&#13;
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; 
}
&#13;
<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>
&#13;
&#13;
&#13;

Snippet demo 2

&#13;
&#13;
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;
  }
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

尝试utitlizing border属性

#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 #ddd;
  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

答案 2 :(得分:1)

在此fiddle中,我使用不同的display规则获得了预期效果,并使用vh单位进行计算。我删除了多余的标记和CSS,但这应该是一个很好的起点,你可以使用和构建。

代码:

#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: #ddd;
  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>

答案 3 :(得分:0)

根据您的需要制作了一个鲜为人知的CSS属性:min-content。这样做的是:

  • 使用intrinsic value,意味着它适应了它的内容。
  • 自动缩小容器的宽度,使图像完美地适合其内部。
  • 如果文本内容需要包装在容器内,它应该。

阅读这篇文章:Design From the Inside Out With CSS Min-Content

有一件事我并不疯狂的是前缀:

width: -moz-min-content;
width: -webkit-min-content;
width: min-content;

我添加了一些重置并评论了哪些样式:

  • 可选
  • 推荐
  • 必需

重要的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

奖励: https://plnkr.co/edit/gahMFQScxQtkweo1G2jD?p=preview

我已经制作了更长的字幕,并添加了以下CSS来展示如何包装字幕而不是突破或扩展figcaption。

CSS红利

figcaption * {
  white-space: pre-wrap;
  /* RECOMMENDED */
}

虽然不是必需的,但我认为在不久的将来你会想要有没有任何麻烦的字幕。我回顾了其他人:

  • LGSon将实际扩展图像和图形,使用我猜测的解决方案轻松修复。

  • guest271314扩展了文字溢出,我不确定会解决什么问题,因为它不是容器。

  • Ryan Litte扩展了figcaption,我相信我的解决方案也可能解决这个问题。

答案 4 :(得分:0)

这似乎非常适合flexboxes。它们适用于所有现代浏览器(http://caniuse.com/#feat=flexbox)和IE 10/11中的一些特殊CSS,如下所示。

Fiddle(出于某种原因,字幕在IE上的小提琴中延伸,但它在浏览器中有效。)

procedure TfrmTest.TestReadOmniXML;
var
  xml: IXMLDocument;
  iNodePartner, iNodePartnerInvoice, iNodePartnerInvoiceR6, iNodePartnerInvoiceR7 : IXMLNode;
begin
  xml := CreateXMLDoc;
  xml.Load('c:\test.xml');
  iNodePartner := XML.SelectSingleNode('//Partner[K3=' + '0254304' + ']');
  iNodePartnerInvoice := iNodePartner.SelectSingleNode(
  //single query works OK
  './/Racuni/Racun[R2=' + '4-02R0113-12' + ']' 

  //but I need to add these fields also
//    ' and [R3=' + '2014-12-29' + ']' +
//    ' and [R8=' + '802.39' + ']'     
  );

  if Assigned( iNodePartnerInvoice ) then
  begin
    iNodePartnerInvoiceR6 := iNodePartnerInvoice.SelectSingleNode('./R6');
    Label1.Caption := iNodePartnerInvoiceR6.Text;
    iNodePartnerInvoiceR7 := iNodePartnerInvoice.SelectSingleNode('./R7');
    Label2.Caption := iNodePartnerInvoiceR7.Text;
  end;

...

end;

我取出包裹较小物品的#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:#ddd; -ms-flex: 1 1 60%; max-width: 100%; } 内的额外<div>,因为它似乎没必要。

#big_container

另外,如果你还不知道它们,请查看CSS视口单元vw和vh。 http://caniuse.com/#feat=viewport-units