【问题标题】:Div that fits into parent and maintains an aspect ratio适合父级并保持纵横比的 Div
【发布时间】:2018-10-21 06:16:38
【问题描述】:

我有一个保持纵横比的div 元素:它根据其宽度计算其高度(使用填充技巧)。我想做的是把这个div 放到另一个中,通过垂直和水平的最大可用空间,没有裁剪。我认为最接近我想要的是object-fit: contain - 仅限img

我希望 div 在保持纵横比的同时尽可能覆盖最大高度和宽度。没有垂直或水平裁剪。

是否甚至可以仅使用 CSS?如果有,怎么做?

更新: 一个很好的article,目前的情况。

代码(可以是任何其他解决方案,不必在此 sn-p 上构建):

html,
body {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}

.container {
  position: relative;
  width: 100%;
}

.container:before {
  content: "";
  display: block;
  width: 50%;
  padding-top: 50%;
}

.embed {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: red;
}
<div class="container">
  <div class="embed">
    this should accommodate all the available space and maintain aspect ratio, no crop when width is too wide
  </div>
</div>

【问题讨论】:

  • 你试过width:100%; 吗?
  • 请添加您的代码!
  • @Adam - 添加代码
  • 你想让 div 覆盖屏幕的100%
  • 我想拉伸到一侧达到最大值。

标签: html css css-position aspect-ratio


【解决方案1】:

好吧,看来只能靠 CSS 解决了。如果有人感兴趣,我已经整理了一个 React component 来完成这项工作(测试和更好的自述文件,当我有时间的时候)。

它将其子元素包装成div,并使用 JavaScript 计算该 div 的宽度和高度,以便在保持给定纵横比的同时容纳可用空间。它基本上会拉伸包装纸,直到其中一侧达到最大值。

重大更新已找到CSS only solution

【讨论】:

  • 欢迎提供解决方案的链接,但请确保您的答案在没有它的情况下有用:add context around the link 这样您的其他用户就会知道它是什么以及为什么会出现,然后引用最相关的内容您链接到的页面的一部分,以防目标页面不可用。 Answers that are little more than a link may be deleted.
  • 您的“突破性更新”基于视口宽度/高度,而不是父元素的。
【解决方案2】:

到目前为止,我设法实现的唯一解决方法是将子元素包装到 svg 的 foraignObject 标记中:

const container = document.getElementById('container');
document.getElementById('btn').addEventListener('click', () => {
  container.style.height = container.style.height === '100px' ? '200px' : '100px';
});
body {
  margin: 1rem;
}

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

button {
  margin-bottom: 1rem;
}


#container {
  background-color: #ffceaf;
  width: 400px;
}

svg {
  background-color: #b8d6ff;
  height: auto;
  width: auto;
  max-width: 100%;
  max-height: 100%;
  overflow: hidden;
}

#content {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  border: solid;
}
<button id="btn">Change parent height</button>

<div id="container" style="height: 100px;">
  <svg width="15000" height="5000">
    <foreignObject width="100%" height="100%">
      <div id="content">
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
        content content content content content content content
      </div>
    </foreignObject>
  </svg>
</div>

这个解决方案有缺点:

  • 浏览器兼容性(IE/Edge 不正确支持 foraignObject)
  • 这不是最佳实践。包含来自不同 XML 命名空间的元素可能会导致更多问题(?)。

我觉得在这里使用 JS 可能是更好的选择。

【讨论】:

    【解决方案3】:

    aspect-ratiooverflow:hidden 在 Chromium 88、Firefox 87Safari Technology Preview 118 是你的朋友。

    html,
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 100%;
    }
    
    .container {
      display: grid;
      resize: both;
      overflow: hidden;
      border: black 2px solid;
      min-width: 50px;
      min-height: 50px;
    }
    
    .embed {
      width: 100%;
      aspect-ratio: 1/1;
      overflow: hidden;
      border: 2px red solid;
      box-sizing: border-box;
      display: flex;
      max-height: 100%;
      margin: auto;
    }
    
    .embed > div {
      margin: auto;
    }
    <div class="container">
      <div class="embed">
        <div>1:1</div>
      </div>
    </div>

    【讨论】:

    • 这是一个很棒的解决方案。我很惊讶它直到现在还没有被选中或收到任何其他赞成票。
    猜你喜欢
    • 1970-01-01
    • 2020-03-16
    • 1970-01-01
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    相关资源
    最近更新 更多