具有基于视口高度的最大高度的元素。内部图像应该缩放并保持比例

时间:2014-05-11 17:45:20

标签: html css scale viewport

寻找一种方法来确保article元素的高度永远不会超过视口高度的65%。还有一个嵌套在元素内部的图像,必须包含在它的父级的高度,并且能够缩放到最大高度并保持它的比例(是的,图像应该是完全可见的,没有裁剪)。

img和覆盖的div .actions始终具有相同的宽度也很重要。
这只能用css吗?

这只是一个测试用例,还有像这样的其他元素,标记是相同的,但每个元素中元素的比例是唯一的。

演示
http://jsfiddle.net/SpPDp/show/

代码
http://jsfiddle.net/SpPDp/

来源

<article>
    <div class="inner">
        <div class="overlay">
            <div class="actions">
                <div class="text">Text</div>
                <div class="yep">Yep</div>
                <div class="heretoo">Here too</div>
            </div>
        </div>
        <div class="content">
            <img src="http://lorempixel.com/output/abstract-h-g-600-900-4.jpg">                        
        </div>
    </div>
</article>


article {
    float: left;
    width: 40%;
}

article .inner {
   position: relative;
}

article .overlay {
   position: absolute;
   background: #000;
   opacity: 0.7;
   top: 0; right: 0; bottom: 0; left: 0;
   height: 100%;
   overflow: hidden;
}

article .actions {
   text-align: center;
   position: absolute;
   bottom: 1%;
   width: 100%;
   color: #fff;
   background: red;
}

.text {
   float: left;
}

.yep {
    display: inline-block;
}

.heretoo {
   float: right;
}

article img {
   max-width: 100%;
}

5 个答案:

答案 0 :(得分:2)

首先,我要说的是,改变你的html中最微小部分的能力会让你很容易完成结果。

例如,将图像设置为background,并接受应该裁剪的事实,这将使任务变得简单。

但你明确表示:

  • 文章必须是viewport h的最多65%;
  • 它上面的元条应始终与图像具有相同的宽度;
  • 不得裁剪或扭曲图像。

如果你的问题是正确的,我真的希望这样,因为我们都试图解决它,你暗示文章的宽度并不总是相等

解决方案是让图像找出最适合做的事情。首先,我们在vwvh设置最大尺寸,然后我们清除不需要的定位和尺寸的方式,以允许图像的大小上升到容器,然后返回到叠加中的元条。另外,请注意弹性盒的使用。

这是CSS(我没有触及HTML)

article {
  float: left;
  overflow: hidden;
  vertical-align: top;
}

.inner {
  /* older browsers. you should add the other prefixes too. there are polyfills to have broader support, check link later in the answer */
  display: -webkit-box;
  display: -moz-box;
  display: -ms-box;
  display: box;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  -ms-box-orient: vertical;
  box-orient: vertical;
  -webkit-box-direction: reverse;
  -moz-box-direction: reverse;
  -ms-box-direction: reverse;
  box-direction: reverse;

  /* newer */
  display: -webkit-flex;
  display: -moz-flex;
  display: -ms-flex;
  display: flex;
  -moz-flex-direction: column-reverse;
  -ms-flex-direction: column-reverse;
  -webkit-flex-direction: column-reverse;
  flex-direction: column-reverse; /* the meta box is added
after the image container, and the items are arranged in column */


}

.overlay {
  z-index: 2;
  margin: 0 0 -25px; /* magic: this cuts the container by 25px (height of meta bar) */
}

.actions {
  color: #fff;
  background: rgba(200,0,0,0.8);

  /* older */ 
  display: -webkit-box;
  display: -moz-box;
  display: -ms-box;
  display: box;
  -webkit-box-pack: justify; /* distribute the labels */
  -moz-box-pack: justify; 
  -ms-box-pack: justify; 
  box-pack: justify; 
  -webkit-box-direction: normal; /* reset order (it used to be inherited) */
  -moz-box-direction: normal; 
  -ms-box-direction: normal; 
  box-direction: normal; 

  /* newer */
  display: -webkit-flex;
  display: -moz-flex;
  display: -ms-flex;
  display: flex;
  -webkit-justify-content: space-between; /* distribute the labels */
  -moz-justify-content: space-between;
  -ms-justify-content: space-between;
  justify-content: space-between;

  /* move up */
  -webkit-transform: translate(0,-25px);  
  -moz-transform: translate(0,-25px);  
  -ms-transform: translate(0,-25px);  
  transform: translate(0,-25px);  

  box-shadow: 0 -1000px 0 1030px rgba(0,0,0,.6); /* since it
can't actually know the size, the overlay is accomplished with
a shadow. as long as it is not blurred, it won't impact
performances much */
  font-size: 1.4vw; /* the only hard limit now is the width
of the text */
}

.content {
  z-index: -1;
  position: relative;
  /* commenting those 2 last properties has two effects in webkit. 1) it avoids the images to stretch. 2) when you resize your window, the images won't adapt. only on load/refresh. this should be ok though, as window resizing is not really what responsive is most useful for
  --- old code ---
  display: -webkit-box;  
  display: -ms-box; 
  display: -moz-box; 
  display: box; 
   --- new code --- 
  display: -webkit-flex; 
  display: -moz-flex;
  display: -ms-flex;
  display: flex;  */

}

.content img {
  max-width: 40vw; /* and here you finally set the sizes.
note that you can set a min-width too, if you want, but
if you do there will be some image ratio that will force
them to stretch */
  max-height: 65vh;
}

代码:http://jsfiddle.net/frapporti/NssKa/

结果,有许多不同比率的图像:http://jsfiddle.net/frapporti/NssKa/embedded/result/

当然,这只是理论,是你问题的有效答案。

如果你想在制作中使用它,你应该为旧浏览器添加一些好的polyfill,也许你可以添加this polyfill。如您所见,我已经将旧的盒子模型属性添加为后备。

答案 1 :(得分:0)

应该是,没有理由不这样做。百分比高度非常有用。

您需要将其添加到图片代码中:

<img src="whatever.jpg" width="95%">

它可以是任何值,具体取决于您想要的宽度。只要您确保不指定高度,它就会保持比例。

你的CSS应该更改为:

article {
  height:65%;
  max-height:65%;
  /* plus whatever else you want*/
}

只要父级是100%的窗口高度,文章将是65%的窗口beight。显然,如果还有更多,那么文章会更多。

另一种解决方案是JavaScript。但是,既然你要求CSS我就省略了。

答案 2 :(得分:0)

CSS:

article{
    height:65%;
    max-height:65%;
    overflow:scroll; /* or hidden */
}

article .content > img{
    max-height:100%;
    width:auto;
}

JS控制(因为相对元素可能没有百分比高度)

$(function(){
    var $article = $('article');
    var $height = $(window).height() * 0.65;
    $article.css({'height':$height+'px', 'max-height':$height+'px'});
});

答案 3 :(得分:0)

首先应将'inner'设置为65%,然后将'content'和image设置为100%height。像这样,

.inner{
height:65%;
}

.content{
height:100%;
}

.content img{
height:100%;
}

答案 4 :(得分:0)

我使用vanilla Javascript编写了一个解决方案。除非你需要,为什么将jQuery作为依赖? (修辞)。

var viewport = document.documentElement.clientHeight;
var el = document.getElementsByTagName("article");

Array.prototype.forEach.call(el, function(el) {
    el.style.maxHeight = Math.floor((viewport/100)*65)+"px";
});

http://jsfiddle.net/PgtAY/