css - 使用 flexbox 并保持纵横比,即使内容大小不同

标签 css responsive-design flexbox aspect-ratio

SO 上有很多关于保持元素的纵横比(有或没有 flexbox)的问题。但是,我的问题略有不同,因为我想覆盖子图像元素的纵横比:

  1. 确保图像完全覆盖元素(object-fit: cover)
  2. 确保元素是 1:1(即正圆)
  3. 确保溢出的图像被隐藏

换句话说,图像必须表现得像一个元素的背景(虽然我不能将它们用作背景图像),其纵横比始终为 1:1 并且响应

在下面的示例中,除了 <a> 之外一切正常元素适应它们的图像后代。但我希望它们保持 1:1 的比例,这样我就能得到完美的圆圈。 (不过,第一行中间的一个必须比其余的大。)

HTML 无法更改,但我可以使用现代 CSS 属性,例如 object-fit 和 flexbox。 (只要最新版本的 Chrome/Firefox 支持它。)

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.img-gallery {
  background: #fafafa;
  padding: 24px;
  min-width: 320px;
  width: 90%;
  margin: 0 auto;
}

.img-gallery .row {
  display: flex;
  flex-wrap: nowrap;
  justify-content: space-around;
  align-items: center;
}

.img-gallery a {
  display: block;
  text-decoration: none;
  background-image: linear-gradient(60deg, #004494 0%, #7db9e8 78%, #c2dfed 100%);
  overflow: hidden;
  border-radius: 50%;
  padding: 3px;
  flex: 1;
  margin: 0 24px;
  transition: padding 200ms;
}

.img-gallery a:hover,
#s_country .img-gallery .row:first-of-type a:nth-child(2):hover {
  padding: 0;
}

.img-gallery a:hover span {
  transform: scale(1.25);
}

.img-gallery .row:first-of-type a:not(:nth-child(2)) {
  width: 30%;
  width: calc((60% - 96px) / 2);
}

.img-gallery .row:first-of-type a:nth-child(2) {
  flex: 2;
  padding: 4px;
}

.img-gallery span {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 50%;
  position: relative;
  overflow: hidden;
  transition: transform 250ms;
  z-index: 2;
}

.img-gallery img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.img-gallery span::before {
  content: "";
  background-image: linear-gradient(60deg, transparent 48%, #ffc5e7 100%);
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 2;
  border-radius: 50%;
  opacity: .72;
}
<div class="img-gallery">
  <div class="row">
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/b3/9c/54/b39c54776074d07ee0b567826768730a.jpg" id="img-1-3"></span></a>
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d6/df/51/d6df512a2f15f517767b4d82d2d97a4c.jpg" id="img-1-4"></span></a>
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/ec/a9/dd/eca9dd106a04cdbee399870252ef711f.jpg" id="img-1-5"></span></a>
  </div>
  <div class="row">
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/7d/01/19/7d0119a2fec989e208f288326c7cad0f.jpg" id="img-1-6"></span></a>
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d8/c3/32/d8c332d09b03673845b2e92a48816233.jpg" id="img-1-7"></span></a>
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/88/3b/dd/883bddab14168f5f0807fec021002d8d.jpg" id="img-1-8"></span></a>
  </div>
  <div class="row">
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/8e/4f/bb/8e4fbb89b155d15521b80d1baf9290d1.jpg" id="img-1-9"></span></a>
  </div>
</div>


说明 Terry 的代码何时不起作用的代码:横向图片。

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.img-gallery {
  background: #fafafa;
  padding: 24px;
  min-width: 320px;
  width: 90%;
  margin: 0 auto;
}

.img-gallery .row {
  display: flex;
  flex-wrap: nowrap;
  justify-content: space-around;
  align-items: center;
}

.img-gallery a {
  display: block;
  text-decoration: none;
  background-image: linear-gradient(60deg, #004494 0%, #7db9e8 78%, #c2dfed 100%);
  overflow: hidden;
  border-radius: 50%;
  padding: 3px;
  flex: 1;
  margin: 0 24px;
  transition: padding 200ms;
}

.img-gallery .row:first-of-type a:not(:nth-child(2)) {
  width: 30%;
  width: calc((60% - 96px) / 2);
}

.img-gallery .row:first-of-type a:nth-child(2) {
  flex: 2;
  padding: 4px;
}

.img-gallery span {
  height: 0;
  display: block;
  border-radius: 50%;
  position: relative;
  padding-bottom: 100%;
  overflow: hidden;
  transition: transform 250ms;
  z-index: 2;
}

.img-gallery img {
  width: 100%;
  object-fit: cover;
  transition: transform 250ms;
}

.img-gallery a:hover img {
  transform: scale(1.25);
}

.img-gallery span::before {
  content: "";
  background-image: linear-gradient(60deg, transparent 48%, #ffc5e7 100%);
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 2;
  border-radius: 50%;
  opacity: .72;
}
<div class="img-gallery">
  <div class="row">
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/b3/9c/54/b39c54776074d07ee0b567826768730a.jpg" id="img-1-3"></span></a>
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d6/df/51/d6df512a2f15f517767b4d82d2d97a4c.jpg" id="img-1-4"></span></a>
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/ec/a9/dd/eca9dd106a04cdbee399870252ef711f.jpg" id="img-1-5"></span></a>
  </div>
  <div class="row">
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/7d/01/19/7d0119a2fec989e208f288326c7cad0f.jpg" id="img-1-6"></span></a>
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d8/c3/32/d8c332d09b03673845b2e92a48816233.jpg" id="img-1-7"></span></a>
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/13/7c/3d/137c3d3bd9f25aa9d2677136d9336d74.jpg" id="img-1-8"></span></a>
  </div>
  <div class="row">
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/8e/4f/bb/8e4fbb89b155d15521b80d1baf9290d1.jpg" id="img-1-9"></span></a>
  </div>
</div>

最佳答案

保持响应元素的宽高比,您可以使用 padding technique
请注意,您不应该在 flex 子项的底部/顶部填充百分比,see here for more info
你可以制作一个 responsive squares 网格并添加 border-radius 使它们成为圆形。

对于图像,object-fit: cover; 属性完全满足您的需求:保持图像原始纵横比并完全覆盖元素。
我将第一张图片更改为风景图片,以表明该技术也适用于这些图片。

这是一个如何实现目标的示例(我删除了一些 CSS 以保持演示简单):

*,*::before,*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.img-gallery {
  background: #fafafa;
  padding: 24px;
  min-width: 320px;
  width: 90%;
  margin: 0 auto;
}

.img-gallery .row {
  display: flex;
  flex-wrap: nowrap;
  justify-content: space-around;
  align-items: center;
}

.img-gallery a {
  display: block;
  position:relative;
  text-decoration: none;
  background-image: linear-gradient(60deg, #004494 0%, #7db9e8 78%, #c2dfed 100%);
  overflow: hidden;
  border-radius: 50%;
  flex: 1;
  margin: 24px;
}
.img-gallery a::before{
  content:'';
  display:block;
  padding-bottom:100%;
}


.img-gallery .row:first-of-type a:not(:nth-child(2)) {
  width: 30%;
  width: calc((60% - 96px) / 2);
}

.img-gallery .row:first-of-type a:nth-child(2) {
  flex: 2;
}

.img-gallery span {
  position:absolute;
  top:3px;left:3px;right:3px;bottom:3px;
  border-radius: 50%;
  overflow: hidden;
  transition: transform 250ms;
}

.img-gallery img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition:transform 0.5s;
}
.img-gallery a:hover img{
  transform:scale(1.25);
}
<div class="img-gallery">
  <div class="row">
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://farm7.staticflickr.com/6217/6216951796_e50778255c.jpg" id="img-1-3"></span></a>
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d6/df/51/d6df512a2f15f517767b4d82d2d97a4c.jpg" id="img-1-4"></span></a>
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/ec/a9/dd/eca9dd106a04cdbee399870252ef711f.jpg" id="img-1-5"></span></a>
  </div>
  <div class="row">
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/7d/01/19/7d0119a2fec989e208f288326c7cad0f.jpg" id="img-1-6"></span></a>
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d8/c3/32/d8c332d09b03673845b2e92a48816233.jpg" id="img-1-7"></span></a>
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/88/3b/dd/883bddab14168f5f0807fec021002d8d.jpg" id="img-1-8"></span></a>
  </div>
  <div class="row">
    <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/8e/4f/bb/8e4fbb89b155d15521b80d1baf9290d1.jpg" id="img-1-9"></span></a>
  </div>
</div>

请注意,您需要根据需要支持的浏览器为转换和转换属性添加供应商前缀。请参阅 transformstransitions 的 canIuse。

关于css - 使用 flexbox 并保持纵横比,即使内容大小不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44009015/

相关文章:

html - 强制包含图像 DIV 的主 DIV float 中心

html - 元名称 ="viewport"和 @media : activate CSS based upon width of actual page

html - 使用 flexbox 的响应式表格

css - 包含其他 div 的 div 的背景图像?

javascript - .load 和 .slideDown 在第一次运行时不起作用

html - Outlook 2010 不在签名中包含样式标签

html - 将 “Position: fixed” div 设置为与父 div 相同的宽度(flexbox 元素)

html - 是否可以让基于 flexbox 列的列表中的第一项为 100% 而其他项不是?

jquery - 如果未选中单选框,如何验证单选框的数量并突出显示它?

css - 如何使用 JSF Framework 在 Java 中更改 dataTable header 的背景颜色?