带有标题的CSS可调整大小的图像

时间:2015-01-07 13:31:20

标签: html css image resize aspect-ratio

我正在尝试获得并排显示的两个图像的HTML布局,并在保持其宽高比的同时填充页面并使图像彼此相邻(即不在每个半部的中心)的页面)。我还想在顶部有一个标题。我几乎已经使用下面的CSS hackery实现了这一点。目前它看起来像这样:

a

如果我水平缩小图像,图像会按预期缩小(注意SO符合图像的宽度,但“选择图像。”文本大小实际上是不变的。)

b

问题是我的图片正在填满整个页面,因为我使用的是CSS vwvh单位(视图宽度和视图高度)。它们允许您将宽度或高度设置为整个视图的百分比,而不是封闭div的百分比,因此我不能将它放在div中(iframe可以工作但是呃)。因为我的标题是绝对定位的,所以当我垂直缩小窗口时,它看起来像这样:

c

我的代码如下。有没有人知道如何解决这个问题而不诉诸javascript大小调整?

*
{
    margin: 0;
    padding: 0;
	/* Fix CSS. */
	box-sizing: border-box;
}

body
{
	margin: 20px;
}

html
{
	background-color: #f4f4f6;
}

.halfContainer
{
    width: 50vw;
    height: 100vh;
    margin: auto;
    padding: 0;
    top: 0;
    bottom: 0;
    position: absolute;
}

#leftContainer
{
    left: 0;
}

#rightContainer
{
    right: 0;
}

/* AR is height/width. */

#leftImage
{
    /* Set to half width, minus padding. 50-padding = 45 */
    width: 45vw; 
	/* Multiply by aspect ratio. 45 * AR = ... */
    /*height: 35vw;*/
    /* Clip by height if necessary, minus padding. 100-padding*2 = 90 */
    max-height: 90vh;
	/* Divide by aspect ratio. 90 / AR = ... */
    /*max-width: 140vh; */
    margin: auto;
    position: absolute;
    top: 0;
    bottom: 0;
    right: 5%; /* Padding */
}


#rightImage
{
    /* Set to half width, minus padding. 50-padding = 45 */
    width: 45vw; 
	/* Multiply by aspect ratio. 45 * AR = ... */
    /*height: 35vw;*/
    /* Clip by height if necessary, minus padding. 100-padding*2 = 90 */
    max-height: 90vh;
	/* Divide by aspect ratio. 90 / AR = ... */
    /*max-width: 140vh;*/
    margin: auto;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 5%;
}

#instructions
{
	margin: auto;
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
}
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<title></title>
</head>
<body>
<center><h1 id="instructions">Choose an image.</h1></center>

<div id="leftContainer" class="halfContainer">
	<img id="leftImage" src="http://www.washingtonpost.com/news/morning-mix/wp-content/uploads/sites/21/2014/09/Grumpy_Cat_Endorsement-017d7-ULFU.jpg"
			style="height: 33.70vw; max-width: 120.15vh;"/>
</div>
<div id="rightContainer" class="halfContainer">
	<img id="rightImage" src="http://upload.wikimedia.org/wikipedia/commons/2/22/Turkish_Van_Cat.jpg"
			style="height: 49.41vw; max-width: 81.95vh;"/>
</div>

</body>
</html>

7 个答案:

答案 0 :(得分:2)

首先,您可以在图片代码上设置max-width: 100%;height: auto;,而不是对每张图片上的高度和最大宽度进行硬编码。

然后,您可以在top: 40px; div上设置.halfContainer,使容器开始向下40像素。

最后,将图片的max-height设置为calc(100vh - 40px);,以便它们始终是页眉和页面底部之间的高度。然后,top: 0;bottom: 0;会确保图片与容器的顶部和底部正确对齐。

&#13;
&#13;
* {
  margin: 0;
  padding: 0;
  /* Fix CSS. */
  box-sizing: border-box;
}
body {
  margin: 20px;
}
html {
  background-color: #f4f4f6;
}
.halfContainer {
  width: 50vw;
  margin: auto;
  padding: 0;
  top: 40px;
  bottom: 0;
  position: absolute;
}
#leftContainer {
  left: 0;
}
#rightContainer {
  right: 0;
}
img {
  max-width: 100%;
  height: auto;
}
#leftImage {
  max-height: calc(100vh - 40px);
  margin: auto;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 5%;
  /* Padding */
}
#rightImage {
  max-height: calc(100vh - 40px);
  margin: auto;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 5%;
}
#instructions {
  margin: auto;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
}
&#13;
<center>
  <h1 id="instructions">Choose an image.</h1>
</center>
<div id="leftContainer" class="halfContainer">
  <img id="leftImage" src="http://www.washingtonpost.com/news/morning-mix/wp-content/uploads/sites/21/2014/09/Grumpy_Cat_Endorsement-017d7-ULFU.jpg" />
</div>
<div id="rightContainer" class="halfContainer">
  <img id="rightImage" src="http://upload.wikimedia.org/wikipedia/commons/2/22/Turkish_Van_Cat.jpg" />
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

我重构了你的代码来提出这个解决方案。这样可以使用background-imagebackground-size属性来调整图像大小。我也离开了vhvw来调整其他元素的大小,但您可以在.wrapper中更改它。好处是它是纯CSS解决方案;没有JS。稍加修补就可以满足您的需求。如果有任何疑虑,请告诉我。

&#13;
&#13;
* { margin:0; padding:0; box-sizing:border-box; }
body { margin:20px; height:calc(100% - 40px); width:calc(100% - 40px); }
html { height:100%; width:100%; }

.wrapper { position:relative; height:100%; width:100%; background-color: #f4f4f6; }
.title { text-align:center; height:2.4em; overflow:hidden; }

.left, .right { padding:15px; height:calc( 100% - 2.4em); width:50%; position:absolute; }
.left .imgCanvas, .right .imgCanvas { width:100%; height:100%; background-repeat:no-repeat; background-size:contain;  }

.left { right:50%; }
.left .imgCanvas { float:right; background-position:right;}
.right { left:50%;  }
.right .imgCanvas { float:left; background-position:left; }
&#13;
<div class="wrapper">
  <div class="title">
    <h1>Choose an image</h1>
  </div>
  <div class="left">
    <div class="imgCanvas" style="background-image:url('http://placekitten.com/g/500/3000')"></div>
  </div>
  <div class="right">
    <div class="imgCanvas" style="background-image:url('http://placekitten.com/g/3000/500')"></div>
  </div>
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

如果您使用background-image(并且在IE9中有效),您可以让自己更好地控制照片调整大小的方式,并使您的HTML和CSS更加简单 - 以下是:

第1步 - 将此问题分解为更小的问题

现在,您正在尝试定位两个不同的图像,同时考虑周围环境。通过将您的图像放在我将调用<div>的{​​{1}}内,可以将其分解为两个更简单的问题。通过这种方式,我们可以解决#displayArea与解决图像放置分开的问题。

所以现在我们正试图解决更容易的问题:

  1. 制作我们的#displayArea - 它应占用尽可能多的屏幕,而不会覆盖顶部的标题
  2. #displayArea内放置两张并排显示的图片,并在保持宽高比的同时填充页面并保持图像彼此相邻
  3. 第2步 - 制作我们的#displayArea

    我们希望#displayArea占用尽可能多的空间。让我们从宽度开始。在您的css中,您将#displayArea的宽度设置为.halfContainer,但您还要将50vw设置为body的保证金 - 这意味着如果我们制作了{{1} } 20px宽,由于左边距和右边距,整个页面最终会变为#displayArea宽。

    为了让您以后更改页边距而无需更新其他CSS,我建议您通过将其宽度设置为100vw100vw + 40px填充所有可用空间。< / p>

    接下来我们需要设置#displayArea高度。有很多方法可以做到这一点,但它们都分为两类 - 一类允许标题具有动态高度,另一类具有固定高度。我将假设标题的固定高度没问题,但是如果您希望标题具有动态高度(例如允许其中的文本换行),请确实需要一个不同的解决方案。

    如果我们假设一个固定的高度,比如100%,那么使用CSS #displayArea我们可以将40px的高度设置为视口的高度减去标题区域减去身体边缘。它看起来像这样:

    calc()

    第3步 - 制作两张图像

    因为我们已经完成了一些设置#displayArea的艰苦工作,所以这一步非常简单。虽然我们当然可以使用您提供的HTML进行此操作,但我建议您考虑在此项目中使用height: calc(100vh - 40px - 40px) /* 40px header, 40px for 2x20px top/bottom margin */ 。控制css的数量可以准确地显示背景图像的显示方式,可以节省大量时间和麻烦 - 例如,当这些图像由于浏览器窗口缩小而变小时,您希望它们是垂直居中的,还是始终为尽可能高吗?使用css background-image很容易。

    在下面的代码中,我使用了一个类#displayArea,因此图像div可以共享样式。然后我使用他们独特的ID来设置我想要的每个特定图像。

    这是完成的CSS和HTML(注意HTML现在有多简单)。

    background-image
    .half

答案 3 :(得分:1)

我知道你已经选择了答案,但无论如何我想给你这个选项。

由于您使用的是vhvw测量但未定义标题高度,因此如果不使用JavaScript动态检测标题的大小,您现在无法做的事情是不可能的调整列的大小。此时,您可能只是使用JavaScript来处理它并忘记视口单元。

话虽如此,这里是一个JavaScript解决方案,我相信,它将呈现内容的确切呈现方式:

&#13;
&#13;
window.onload = function() {
    window.left = document.getElementById("leftImage"),
   window.right = document.getElementById("rightImage"),
    window.head = document.getElementById("instructions"),
   window.leftW = parseInt(window.getComputedStyle(left, null).getPropertyValue('width')),
  window.rightW = parseInt(window.getComputedStyle(right, null).getPropertyValue('width')),
   window.leftH = parseInt(window.getComputedStyle(left, null).getPropertyValue('height')),
  window.rightH = parseInt(window.getComputedStyle(right, null).getPropertyValue('height'));

console.log(leftW);
    resize(leftW, rightW, leftH, rightH);
}

window.onresize = function() {
    resize(leftW, rightW, leftH, rightH);
}

function resize(leftW, rightW, leftH, rightH) {
    var winW = window.innerWidth,
      hcPadW = (winW * .025 * 2),
        winH = window.innerHeight,
      hcPadH = (winH * .025 * 2),
        colW = (winW / 2),
        colH = (winH - parseInt(window.getComputedStyle(head, null).getPropertyValue('height'))),
        colR = ((colW - hcPadW) / (colH - hcPadH)),
       leftR = (leftW / leftH),
      rightR = (rightW / rightH);
    
    if(colR < leftR) {
        left.style.width = (colW - hcPadW) + 'px';
        left.style.height = (((colW - hcPadW) * leftH) / leftW) + 'px';
    } else {
        left.style.height = (colH - hcPadH) + 'px';
        left.style.width = (((colH - hcPadH) * leftW) / leftH) + 'px';
    }
    
    if(colR < rightR) {
        right.style.width = (colW - hcPadW) + 'px';
        right.style.height = (((colW - hcPadW) * rightH) / rightW) + 'px';
    } else {
        right.style.height = (colH - hcPadH) + 'px';
        right.style.width = (((colH - hcPadH) * rightW) / rightH) + 'px';
    }
}
&#13;
* {
    margin: 0;
    padding: 0;
}

html, body {
    height: 100vh;
}

#wrapper {
    height: 100vh;
    background-color: #dedede;
    display: table;
}

#instructions, .hidden {
    display: table-row;
}

.hidden {
    visibility: hidden;
}

#instructions {
    text-align: center;
    background-color: #9a9a9a;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
}

#cols {
    display: table-row;
}

.halfContainer {
    display: table-cell;
    width: 50vw;
    height: 100%;
    padding: 2.5vh 2.5vw;
    vertical-align: middle;
}

#leftContainer {
    background-color: #797979;
    text-align: right;
}
&#13;
<div id="wrapper">
    <div class="hidden"><h1>Choose an image.</h1></div>
    <div id="instructions"><h1>Choose an image.</h1></div>
    <div id="cols">
        <div id="leftContainer" class="halfContainer"><img id="leftImage" src="http://www.washingtonpost.com/news/morning-mix/wp-content/uploads/sites/21/2014/09/Grumpy_Cat_Endorsement-017d7-ULFU.jpg" class="image" /></div><div id="rightContainer" class="halfContainer"><img id="rightImage" src="http://upload.wikimedia.org/wikipedia/commons/2/22/Turkish_Van_Cat.jpg" class="image" /></div>
    </div>
</div>
&#13;
&#13;
&#13;

JSFiddle:http://jsfiddle.net/rLuf9zso/

这里更简化一条路线,将JavaScript降至最低限度:

&#13;
&#13;
window.onload = function() {
    var mH = document.getElementsByClassName('image');
    for(var i = 0; i < mH.length; i++) {
        mH[i].style['maxHeight'] = 'calc(94vh - ' + parseInt(window.getComputedStyle(document.getElementById('instructions'), null).getPropertyValue('height')) + 'px)';
    }
}
&#13;
* {
    margin: 0;
    padding: 0;
}

html, body {
    height: 100vh;
}

#wrapper {
    height: 100vh;
    display: table;
}

#instructions, .hidden {
    display: table-row;
}

.hidden {
    visibility: hidden;
}

#instructions {
    text-align: center;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
}

#cols {
    display: table-row;
}

.halfContainer {
    display: table-cell;
    width: 50vw;
    height: 100%;
    padding: 2.5vh 2.5vw;
    vertical-align: middle;
}

#leftContainer {
    text-align: right;
}

.image {
    min-height: 0;
    min-width: 0;
    max-width: 40vw;
    margin: auto;
}
&#13;
<div id="wrapper">
    <div class="hidden"><h1>Choose an image.</h1></div>
    <div id="instructions"><h1>Choose an image.</h1></div>
    <div id="cols">
        <div id="leftContainer" class="halfContainer"><img id="leftImage" src="http://www.washingtonpost.com/news/morning-mix/wp-content/uploads/sites/21/2014/09/Grumpy_Cat_Endorsement-017d7-ULFU.jpg" class="image" /></div><div id="rightContainer" class="halfContainer"><img id="rightImage" src="http://upload.wikimedia.org/wikipedia/commons/2/22/Turkish_Van_Cat.jpg" class="image" /></div>
    </div>
</div>
&#13;
&#13;
&#13;

JSFiddle:http://jsfiddle.net/18ynkzd0/

两者之间的主要区别在于兼容性。第一个,使用更广泛的JavaScript,将在大多数主流浏览器中兼容多个版本,而第二个遵循您忽略IE 8/9和Android 4.1 / .3等浏览器的原始方案。

关于这些选项需要记住的是,可以从div#instructions检索标题的高度,但图像上的定位不受其影响。由于标题已定位,因此它的高度不会影响图像位置的渲染。为了补偿,我添加了div#hidden相同的值/ CSS并将其可见性设置为隐藏。这将添加内联所需的高度而不显示它。如果您更改显示的标题,请确保更新隐藏的div以匹配。

我希望这会有所帮助。 ^^

答案 4 :(得分:0)

这可能是一个黑客,但您可以在标题下方放置<div style="height:50px"></div>

您必须使用标题的高度替换高度。

答案 5 :(得分:0)

好的,现在回答略有不同。我在您的代码中添加了以下内容:

@media (max-height: 500px) {
    .halfContainer {
        top: 100px;
        overflow: auto;
    }
}

一旦屏幕高度低于200px,这将按下图像。自动溢出不允许滚动。你可能会看到更少的图像。

*
{
    margin: 0;
    padding: 0;
	/* Fix CSS. */
	box-sizing: border-box;
}

body
{
	margin: 20px;
}

html
{
	background-color: #f4f4f6;
}

.halfContainer
{
    width: 50vw;
    height: 100vh;
    margin: auto;
    padding: 0;
    top: 0;
    bottom: 0;
    position: absolute;
}

@media (max-height: 500px) {
    .halfContainer {
        top: 100px;
        overflow: auto;
    }
}

#leftContainer
{
    left: 0;
}

#rightContainer
{
    right: 0;
}

/* AR is height/width. */

#leftImage
{
    /* Set to half width, minus padding. 50-padding = 45 */
    width: 45vw; 
	/* Multiply by aspect ratio. 45 * AR = ... */
    /*height: 35vw;*/
    /* Clip by height if necessary, minus padding. 100-padding*2 = 90 */
    max-height: 90vh;
	/* Divide by aspect ratio. 90 / AR = ... */
    /*max-width: 140vh; */
    margin: auto;
    position: absolute;
    top: 0;
    bottom: 0;
    right: 5%; /* Padding */
}


#rightImage
{
    /* Set to half width, minus padding. 50-padding = 45 */
    width: 45vw; 
	/* Multiply by aspect ratio. 45 * AR = ... */
    /*height: 35vw;*/
    /* Clip by height if necessary, minus padding. 100-padding*2 = 90 */
    max-height: 90vh;
	/* Divide by aspect ratio. 90 / AR = ... */
    /*max-width: 140vh;*/
    margin: auto;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 5%;
}

#instructions
{
	margin: auto;
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
}
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<title></title>
</head>
<body>
<center><h1 id="instructions">Choose an image.</h1></center>

<div id="leftContainer" class="halfContainer">
	<img id="leftImage" src="http://www.washingtonpost.com/news/morning-mix/wp-content/uploads/sites/21/2014/09/Grumpy_Cat_Endorsement-017d7-ULFU.jpg"
			style="height: 33.70vw; max-width: 120.15vh;"/>
</div>
<div id="rightContainer" class="halfContainer">
	<img id="rightImage" src="http://upload.wikimedia.org/wikipedia/commons/2/22/Turkish_Van_Cat.jpg"
			style="height: 49.41vw; max-width: 81.95vh;"/>
</div>

</body>
</html>

答案 6 :(得分:0)

&#13;
&#13;
.halfContainer
{
   float:left;
   margin: 10px;
   overflow: hidden;
   height: 150px;
}

.halfContainer img
{
    
    
   max-width: 100%; max-height: 100%;
    
}
&#13;
<!DOCTYPE html>
<html lang="en">
 <head>
  <title> test </title>
  <meta charset="">
 
  </head>
 <body>

<center><h1 id="instructions">Choose an image.</h1></center>

<div class="halfContainer">
	<img src="http://www.washingtonpost.com/news/morning-mix/wp-content/uploads/sites/21/2014/09/Grumpy_Cat_Endorsement-017d7-ULFU.jpg"/>
</div>
<div class="halfContainer">
	<img src="http://upload.wikimedia.org/wikipedia/commons/2/22/Turkish_Van_Cat.jpg"/>
</div>


 </body>
</html>
&#13;
&#13;
&#13;