最大可能尺寸的图像和div扩展以填充空间

时间:2016-12-29 02:43:00

标签: html css css3 flexbox

我确定之前已经问过这个问题,但我找不到确切问题的答案。

我想要一个非常简单的布局:

-------------------
      header
-------------------
         |
 content | graphic
         |
-------------------

其中:

  • 标题高度由字体大小设置;
  • 内容具有固定的最小宽度;
  • 图片尽可能大,因为这两个约束和保留纵横比(即它会高出屏幕减去标题,除非这会使内容面板太窄);
  • 考虑到那些三个约束,内容尽可能宽。

[编辑添加:]

  • 垂直:当宽度+宽高比约束导致它比最大高度短时,图像垂直居中
  • 水平:图像总是很难对着屏幕右侧(除了任何手动添加的填充),内容总是一直向上到图像的左侧(除了任何手动添加的填充之外)。< / LI>

我尝试过使用flexbox并满足前三个限制条件,但我无法让内容窗格水平增长以填充图像未使用的空间。我得到的最好的结果是使用下面的HTML和CSS,但正如您在下面的屏幕截图中看到的,这会导致内容div和图像占用相同的大小,而不是内容div将图像推送到正确的。 (这是两者都设置flex = 1的预期行为,所以我不希望它起作用;但至少这给我的图像大小表现得我喜欢)。

Screenshot

我使用的是https://jsfiddle.net/uv566jc3/

&#13;
&#13;
.grid {
  border: solid 1px #e7e7e7;
  height: 95vh;
  display: flex;
  flex-direction: column;
}
.header {
  flex: 0;
}
.grid__row {
  flex: 1;
  display: flex;
  flex-direction: row;
}
.grid__item {
  flex: 1;
  padding: 12px;
  border: solid 1px #e7e7e7;
}
img {
  flex: 1;
  object-fit: contain;
  overflow: hidden;
  border: solid 1px #e7e7e7;
}
&#13;
<div class="grid">
  <div class="header">Some header stuff
  </div>
  <div class="grid__row">
    <div class="grid__item">1</div>
    <img id="pic" src="https://s27.postimg.org/oc7sozu7n/clouds.png">
  </div>
</div>
&#13;
&#13;
&#13;

  • 网格样式是包含标题和grid__row;
  • 的列方向的flexbox
  • 标题有弹性0,即高度由内容设置;
  • grid__row具有flex 1,即填充标题后留下的高度;也是行方向的flex容器,包含grid__item和img。
  • grid__item具有flex 1,即填充可用宽度;
  • img有flex 1并使用object-fit = 1(它获取我需要的图像大小调整属性)和overflow = hidden(我不知道它在做什么,但如果我离开它将img容器水平扩展2倍。

我还没有明确地在jsfiddle的grid__item项目上设置min-width,但我并没有预料到会有任何不同。

有没有一种简单的方法可以在CSS中获得我想要的东西?如果这是重复的话,请道歉。

9 个答案:

答案 0 :(得分:2)

我已根据您的需要编辑了您的解决方案的代码?我不确定..

https://jsfiddle.net/vjLps7qs/6/

变成:

  .container {
    width: calc(100vw);
    height: 100vh;
    overflow: hidden;
  }

  .top {
    height: 1.25em;
    padding: 3px;
    background: yellow;
    display: flex;
    flex-direction: row;
  }

  .innerCtr {
    height: 100%;
    overflow: hidden;
  }

  .left {
    height: 100%;
    background: red;
    overflow: hidden;
  }

  .right {
    max-height: 100%;
    max-width: 80%;
    calc(100% - 1.25rem);
    background: blue;
    float: right;
    object-fit: contain;
    overflow: hidden;
    position: relative;
    top: calc(50% - 1.25rem);
    transform: translateY(-52%) scale(0.95);
  }

添加了calc,由all major browsers

支持
  .right {
    calc(100% - 1.25rem);
    top: calc(50% - 1.25rem);
  }

同样,如果那不是你想要的东西,我很抱歉,但这个帖子难以导航。

答案 1 :(得分:1)

flex: 1因子

grid__row弹性容器(行方向)中,两个弹性项目grid__itemimg - 均已应用flex: 1

这意味着两个项目将在容器中均匀划分可用空间。换句话说,50/50,就像你的插图一样。

我的建议:从flex: 1删除img

object-fit: contain

产生的空白

使用object-fit: contain保留图像的纵横比,并缩放以适合框内。

因此,左侧和/或右侧(纵向拟合)或顶部和/或底部(横向拟合)可能有空白。

这可能是你看到&#34; padding&#34;图像左侧和右侧的空间。

如果您尝试cover,则会使用所有空格,但会进行裁剪(demo)。

以下是object-fithttps://stackoverflow.com/a/37127590/3597276

的更多信息

overflow: hidden效果

关于你的意见:

  

...溢出=隐藏(我不明白它在做什么,   但如果我把它留下来,img容器会水平扩展   因素2)。

这很可能是由于灵活项目的最小尺寸算法

默认情况下,弹性项目不能小于其内容的大小。

但是,可以使用overflow: hidden覆盖此功能。

此处有更多详情: Why doesn't flex item shrink past content size?

答案 2 :(得分:1)

此示例使用float概念:

肖像图片:

&#13;
&#13;
* {
  box-sizing: border-box;
}
body {
  margin: 0px;
}
.header {
  width: 100%;
  height:8vh;
  border: 1px solid #aaa;
}
.main-content {
  width: 100%;
  border: 1px solid #aaa;
  padding: 0px;
}
.main-content > .left {
  float: left;
  width: 50%;
}
.main-content > .right {
  float: right;
  width: 50%;
}
.main-content > div {
  min-height: 50%;
  max-height: 90%;
}
.main-content > .right > img {
  max-width: 100%;
  max-height: 90vh;
}
.main-content:after,
.main-content:before {
  display: table;
  clear: both;
  content: "";
}
&#13;
<div class="header">
  Some Header stuff..
  <br>
</div>
<div class="main-content">

  <div class="left">
    Somehitng on the left
  </div>
  <div class="right">
    <img src="https://s-media-cache-ak0.pinimg.com/236x/41/89/8c/41898cae6d9edd8737dfef07ab50ea57.jpg" />
  </div>
</div>
&#13;
&#13;
&#13;

风景图片:

&#13;
&#13;
* {
  box-sizing: border-box;
}
body {
  margin: 0px;
}
.header {
  width: 100%;
  height: 8vh;
  border: 1px solid #aaa;
}
.main-content {
  width: 100%;
  border: 1px solid #aaa;
  padding: 0px;
}
.main-content > .left {
  float: left;
  width: 50%;
}
.main-content > .right {
  float: right;
  width: 50%;
}
.main-content > div {
  min-height: 50%;
  max-height: 90%;
}
.main-content > .right > img {
  max-width: 100%;
  max-height: 90vh;
}
.main-content:after,
.main-content:before {
  display: table;
  clear: both;
  content: "";
}
&#13;
<div class="header">
  Some Header stuff..
  <br>
</div>
<div class="main-content">

  <div class="left">
    Somehitng on the left
  </div>
  <div class="right">
    <img src="http://www.w3schools.com/css/img_fjords.jpg" />
  </div>
</div>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

您应该从图片中删除flex并将其包装在容器内以满足您的要求。

我已经修改了你的代码以实现相同的目标。请检查更改。

<强>更新

我已更新我的回答并立即使用display: inline-flex。应该满足您的所有要求。

&#13;
&#13;
.grid {
  border: solid 1px #e7e7e7;
  height: 95vh;
  display: flex;
  flex-direction: column;
}

.header {
  flex: 0;
}

.grid__row {
  flex: 1;
  display: flex;
  flex-direction: row;
}

.grid__item {
  flex: 1;
  padding: 12px;
  border: solid 1px #e7e7e7;
}

.img_ctr {
  border: solid 1px #e7e7e7;
  display: inline-flex;
}

 img {
  height: 100%;
} 
&#13;
<div class="grid">
  <div class="header">Some header stuff
  </div>
  <div class="grid__row">
    <div class="grid__item">1</div>
    <div class="img_ctr">
      <img id="pic" src="https://s-media-cache-ak0.pinimg.com/236x/41/89/8c/41898cae6d9edd8737dfef07ab50ea57.jpg">
    </div>
  </div>
</div>
&#13;
&#13;
&#13;

答案 4 :(得分:0)

这可能是您的问题的解决方案吗?请参阅小提琴here

#pic {
       background: url('http://lorempixel.com/400/200/sports/1/') no-repeat; 
       position: absolute; 
       left: 440px; 
       right: 0; 
       top: 0; 
       bottom: 0; 
     }

我将图像作为具有cover属性的背景图像。这样,无论您如何调整大小,图像都会占据容器的整个宽度和高度。

答案 5 :(得分:0)

我使用max-widthmax-height对图像应用限制,但保留了宽高比。我还将图像包含在一个独立的div中,以允许缩小和增长两个分开的部分。

这可能是你正在寻找的吗? https://jsfiddle.net/johnnykb/pu1vpL3q/2/

极高和极宽的图像都可以完美地缩放以适合图像容器,如果图像足够小而不会增长超过内容部分最小宽度所允许的范围,则容器会缩小。

HTML:

<div class="grid">
  <div class="header">Some header stuff
  </div>
  <div class="grid__row">
    <div class="content">1</div>
    <div class="image">
      <img id="pic" src="http://placekitten.com/200/2000">
    </div>
  </div>
</div>

CSS:

.grid {
  border: solid 1px #e7e7e7;
  height:95vh;
  display: flex;
  flex-direction: column;
}

.header {
  flex: 0;
}

.grid__row {
  flex: 1;
  display: flex;
  flex-direction:row;
}

.content {
  flex-grow: 1;
  padding: 12px;
  border: solid 1px #e7e7e7;
  min-width: 400px;
}

.image {
  flex-shrink: 1;
  padding: 12px;
  border: solid 1px #e7e7e7;
  text-align: center;
}

img {
  overflow: hidden;
  border: solid 1px #e7e7e7;
  max-height: 100%;
  max-width: 100%;
}

答案 6 :(得分:0)

注意:这是我迄今为止找到的最佳答案,但赏金仍然开放 - 见下文。

我找到了一个使用float的答案。看到 https://jsfiddle.net/wwhyte/vjLps7qs/;用http://placekitten.com/1600/900替换图像以查看横向行为。

CSS:

  .container {
    width: calc(100vw);
    height: 100vh;
    overflow: hidden;
  }

  .top {
    height: 1.25em;
    background: yellow;
  }

  .innerCtr {
    height: 100%;
    overflow: hidden;
  }

  .left {
    height: 100%;
    background: red;
    overflow: hidden;
  }

  .right {
    max-height: 100%;
    max-width: 80%;
    background: blue;
    float: right;
    object-fit: contain;
    overflow: hidden;
    position: relative;
    top: 50%;
    transform: translateY(-52%) scale(0.95);
  }

HTML:

<div class="container">
  <div class="top">
  </div>
  <div class="innerCtr">
    <img class="right" src="http://placekitten.com/1600/900">
    <div class="left">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</div>
  </div>
</div>

认为正在发生的事情是:

  • 在正确的班级:
    • max-height,max-width和object-fit为我提供了我需要的缩放。
    • float:right给出我需要的位置。 (我从昨天发现的一篇文章中得到了这个,但现在丢失了,如果我重新找到它,我会编辑这个答案以提供归属信息。)
    • 转换的灵感来自垂直对齐的文章:http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/
    • 95%比例提高了图像的可见度。
  • 在左侧班级中,身高:100%给出了我想要的面板尺寸
  • innerCtr类为图像提供父级以计算其高度
  • 容器类使视口适合浏览器窗口。

即使这不是很理想。顶栏的高度与图像的高度之间存在一些奇怪的相互作用,因此图像的底部被推出显示器。推出的数量小于但与顶杆的高度有关 - 我还没有完全调查过。如果你删除顶部栏,上面的CSS表现完美。我用95%的比例和对Y变换稍作调整来解决这个问题,但是在小窗口尺寸下这仍然表现不正确 - 图像不是完全垂直居中的。我原以为在容器类上设置height = calc(100vh-1.25em)可能会解决这个问题,但实际上它会破坏图像的垂直缩放,所以它现在只能水平缩放。这是完全意外行为! 如果有人可以让垂直居中工作正常,那么赏金仍然是开放的

感谢大家提出的所有建议!

答案 7 :(得分:0)

关于从图像中移除flex的答案是在正确的轨道上,flex是针对不是内容的容器。这是一个有效的例子..

.grid {
  border: solid 1px #e7e7e7;
  height:95vh;
  display: flex;
  flex-direction: column;
}

.header {
  flex: 0;
}

.grid__row {
  flex: 1;
  display: flex;
  flex-direction:row;
}

.grid__item {
  white-space:nowrap;
  padding: 12px;
  border: solid 1px #e7e7e7;
}

img {
  object-fit:contain;
  border: solid 1px #e7e7e7;
  max-width:75%;
}

Fiddle

答案 8 :(得分:0)

我已在你的答案中修正了一些细节,现在我相信它的工作正常。

演示有2个版本,一个用于风景图像,另一个用于肖像。

我在悬停图像时设置动画,以显示它正确缩放以保持居中

body {
    margin: 0px;
  }

  .container {
    width: calc(100vw);
    height: 50vh;
  }

  .top {
    height: 1.25em;
    background: yellow;
  }

  .innerCtr {
    height: calc(100% - 1.25em);  /* important to have the heuight ok */
    position: relative;     /* make the dimension inheritable */
  }

  .left {
    height: 100%;
    background: red;
    overflow: hidden;
  }

  .right {
    max-height: 100%;
    max-width: 80%;
    background: blue;
    float: right;
    object-fit: contain;
    top: 50%;
    position: relative;
    transform: translateY(-50%) scale(0.95) ;
}

.right:hover {
    animation: zoom 4s infinite;  
}

@keyframes zoom {
    from {transform: translateY(-50%) scale(0.98) }
    to {transform: translateY(-50%) scale(0) }
}
<div class="container">
  <div class="top">
  </div>
  <div class="innerCtr">
    <img class="right" src="http://placekitten.com/1600/900">
    <div class="left">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</div>
  </div>
</div>
<div class="container">
  <div class="top">
  </div>
  <div class="innerCtr">
    <img class="right" src="http://placekitten.com/900/1600">
    <div class="left">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</div>
  </div>
</div>