保持 div 宽高比并居中,无论父级的宽高比如何

问题描述 投票:0回答:2

我发现这个CSS代码可以让我保持div的长宽比。

.container {
  width: 100%;
  height: 100%;
  background-color: red;
  position: absolute;
 }


.wrapper {
  width: 100%;
  /* whatever width you want */
  display: inline-block;
  position: relative;
  top: 50%;
  transform: translate(0%, -50%);
}
.wrapper:after {
  padding-top: 56.25%;
  /* 16:9 ratio */
  display: block;
  content: '';
}
.main {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
 /* fill parent */
  background-color: deepskyblue;
  /* let's see it! */
  color: white;
}

参见这个 JSFiddle 示例:https://jsfiddle.net/1uyo07tg/3/

我想要一个仅 css 的解决方案(不使用 VW 或 VH)来保持此宽高比,即使父级宽于所讨论的宽高比(在本例中为 16:9)。

换句话说,即使父级 (.container) 拉伸得比 16:9 更宽,我也希望蓝色 div 保持在 16:9 比例。

澄清 - 我想要一些纯CSS解决方案,让子div始终保持固定比例,垂直和水平居中,无论父div的大小或纵横比如何,并且不使用vw,vh。我很确定这需要 JS 代码(我有),但只是想看看是否有人有一个纯 css 的巧妙技巧。

底线 - 仅在 CSS 中寻找 this 功能,没有 vh 或 vw。

希望这是有道理的。 有什么想法吗?

提前致谢, 萨尔

html css responsive-design aspect-ratio
2个回答
16
投票

CSS “包含” 用于元素。保持纵横比

CSS contain with aspect ratio for elements

  • position: absolute
    设置为
    top,right,bottom,left
    位置,或者仅将
    inset
    规则设置为
    0
  • 设置
    margin: 0
    使其居中
  • 设置纵横比CSS属性
  • 最后,将
    max-width
    max-height
    设置为
    100%
    以实现 contain 魔法

/* QuickReset */ * { margin: 0; box-sizing: border-box; }

#parent {
  /* This can be just any element with responsive W/H */
  min-height: 100vh;
  background-color: red;
  position: relative;
}

#aspectRatio {
  background-color: #0bf;
  position: absolute;
  inset: 0;    /* or use: top:0; right:0; bottom:0; left:0;*/
  margin: auto;
  max-width: 100%;
  max-height: 100%;
  aspect-ratio: 16 / 9;
}
<div id="parent">
  <div id="aspectRatio">Lorem</div>
</div>

这是另一个例子固定页眉和页脚,长宽比正文

JavaScript 解决方案:

如果您对复杂性和计算感兴趣,我在这里创建了一个 JS 实现:

JS contain with aspect ratio for elements

const contain = (EL, rx, ry) => {
  // We need to rely on JS since Firefox is still experimental with aspect-ratio
  // https://stackoverflow.com/a/66721382/383904

  const scale = 1.0; // 1 = max parent size. 0.8 = scale down
  const margin = 0;  // PX gutter around the box

  rx *= scale;
  ry *= scale;
  const parent = EL.parentElement;
  const pw = parent.offsetWidth * scale - margin;
  const ph = parent.offsetHeight * scale - margin;
  // If H should apply instead of W and vice versa
  const isSwap = pw / ph > rx / ry;
  const w = isSwap ? (ph / ry) * rx : pw;
  const h = isSwap ? ph : (pw / rx) * ry;
  EL.style.cssText = `width: ${w}px; height: ${h}px;`;
};


const ELS_aspectRatio = document.querySelectorAll(".ar-box");
const applyContain = () => ELS_aspectRatio.forEach(EL => contain(EL, 16, 9));

window.addEventListener("resize", applyContain);
applyContain();
* { margin: 0; box-sizing: border-box; }

/* DEMO ONLY: This can be any responsive parent with any responsive unit! */
#parent { 
  width: 100vw;
  height: 100vh;
  background-color: red;
  display: flex;
  justify-content: center;
  align-items: center;
}

.ar-box {
  background-color: #0bf;
}
<div id="parent">
  <div class="ar-box">Contain using JS</div>
</div>


-1
投票
body,html {
  margin: 0;
  height: 100%;
  width: 100%;
}
.container {
  width: 100%;
  height: 100%;
  background-color: red;
  overflow: hidden;
}     
.wrapper {
  width: 100%;
  max-width: calc(100vh / 0.5625);
  padding-top: 56.25%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: deepskyblue;
}

.main
甚至没有必要

© www.soinside.com 2019 - 2024. All rights reserved.