使用CSS保持div的宽高比

时间:2009-09-29 23:11:05

标签: html css css3 responsive-design aspect-ratio

我想创建一个div,可以随着窗口宽度的变化更改其宽度/高度。

是否有任何CSS3规则允许高度根据宽度而变化,同时保持其宽高比

我知道我可以通过JavaScript完成此操作,但我更喜欢只使用CSS。

div keeping aspect ratio according to width of window

36 个答案:

答案 0 :(得分:1228)

只需使用<div>的百分比值创建包装padding-bottom,如下所示:

div {
  width: 100%;
  padding-bottom: 75%;
  background: gold; /** <-- For the demo **/
}
<div></div>

这将导致<div>的高度等于其容器宽度的75%(纵横比为4:3)。

这取决于填充的事实:

  

百分比是根据生成的框的包含块[...]的宽度计算的(来源:w3.org,强调我的)

其他宽高比和100%宽度的填充底部值:

aspect ratio  | padding-bottom value
--------------|----------------------
    16:9      |       56.25%
    4:3       |       75%
    3:2       |       66.66%
    8:5       |       62.5%

在div中放置内容:

为了保持div的纵横比并防止其内容被拉伸,您需要添加一个绝对定位的子项并将其拉伸到包装器的边缘:

div.stretchy-wrapper {
  position: relative;
}

div.stretchy-wrapper > div {
  position: absolute;
  top: 0; bottom: 0; left: 0; right: 0;
}

Here's a demo以及更深入的demo

答案 1 :(得分:373)

vw个单位:

您可以将vw单位用于元素的宽度和高度。这允许基于视口宽度保留元素的宽高比。

  

vw:视口宽度的1/100。 [ MDN

或者,您也可以使用vh作为视口高度,甚至可以使用vmin / vmax来使用视口尺寸的较小/较大(讨论here)。

示例:1:1宽高比

&#13;
&#13;
div {
  width: 20vw;
  height: 20vw;
  background: gold;
}
&#13;
<div></div>
&#13;
&#13;
&#13;

对于其他宽高比,您可以使用下表根据元素的宽度计算高度值:

aspect ratio  |  multiply width by
-----------------------------------
     1:1      |         1
     1:3      |         3
     4:3      |        0.75
    16:9      |       0.5625

示例:方形div的4x4网格

&#13;
&#13;
body {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}
div {
  width: 23vw;
  height: 23vw;
  margin: 0.5vw auto;
  background: gold;
}
&#13;
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
&#13;
&#13;
&#13;

这是一个Fiddle with this demo,这是一个制作responsive grid of squares with verticaly and horizontaly centered content的解决方案。


对vh / vw单元的浏览器支持是IE9 +,请参阅canIuse for more info

答案 2 :(得分:25)

我已经找到了使用CSS执行此操作的方法,但您必须小心,因为它可能会根据您自己的网站流量而改变。我这样做是为了在我的网站的流体宽度部分内嵌入具有恒定宽高比的视频。

假设您有这样的嵌入式视频:

<object>
     <param ... /><param ... />...
     <embed src="..." ...</embed>
</object>

然后,您可以将所有内容放在带有“视频”类的div中。此视频类可能是您网站中的流媒体元素,因此它本身没有直接的高度限制,但是当您调整浏览器大小时,它将根据网站的流量改变宽度。这将是您可能尝试在保持视频的某个宽高比的同时获取嵌入视频的元素。

为了做到这一点,我在“视频”类div中的嵌入对象之前放置了一个图像。

!!!重要的是,图像具有您希望保持的正确宽高比。此外,请确保图像的大小至少与您期望的视频(或者您维护A.R.的任何内容)一样大,以便根据您的布局获得。这将避免在调整百分比大小时图像分辨率中的任何潜在问题。例如,如果您想保持3:2的宽高比,请不要只使用3px x 2px图像。它可能在某些情况下有效,但我没有测试过,它可能是一个好主意,可以避免。

您应该已经拥有这样的最小宽度,例如为网站的流体元素定义的宽度。如果没有,最好这样做是为了避免在浏览器窗口太小时关闭元素或重叠元素。在某些时候最好有一个滚动条。网页应该获得的最小宽度约为600像素(包括任何固定宽度的列),因为除非您正在处理适合手机的网站,否则屏幕分辨率不会变小。 !!!

我使用了一个完全透明的png,但如果你做得对,我真的不认为它最终会引起关注。像这样:

<div class="video">
     <img class="maintainaspectratio" src="maintainaspectratio.png" />
     <object>
          <param ... /><param ... />...
          <embed src="..." ...</embed>
     </object>
</div>

现在您应该可以添加类似于以下内容的CSS:

div.video { ...; position: relative; }
div.video img.maintainaspectratio { width: 100%; }
div.video object { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; }
div.video embed {width: 100%; height: 100%; }

确保您还删除了通常附带复制/粘贴嵌入代码的object和embed标记中的任何显式高度或宽度声明。

它的工作方式取决于视频类元素的位置属性以及您想要保持特定宽高比的项目。它利用了在元素中调整大小时图像保持其正确宽高比的方式。它告诉视频类元素中的任何其他内容,通过强制其宽度/高度为图像调整的视频类元素的100%,充分利用动态图像提供的不动产。

非常酷,嗯?

您可能需要稍微使用它来使其与您自己的设计一起使用,但这实际上对我来说效果非常好。一般概念就在那里。

答案 3 :(得分:13)

要添加到Web_Designer的答案,<div>的高度(完全由底部填充组成)将为其包含元素宽度的75%。这是一个很好的总结:http://mattsnider.com/css-using-percent-for-margin-and-padding/。我不确定为什么会这样,但事实就是如此。

如果您希望div的宽度不是100%,则需要另一个包装div来设置宽度:

div.ar-outer{
    width: 60%; /* container; whatever width you want */
    margin: 0 auto; /* centered if you like */
}
div.ar {
    width:100%; /* 100% of width of container */
    padding-bottom: 75%; /* 75% of width of container */
    position:relative;
}
div.ar-inner {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
}

我最近使用类似于Elliot的图像技巧,允许我使用CSS媒体查询根据设备分辨率提供不同的徽标文件,但仍按比例缩放<img>自然会做(我设置徽标作为具有正确宽高比的透明.png的背景图像)。但是Web_Designer的解决方案会为我节省一个http请求。

答案 4 :(得分:13)

Elliot鼓励我使用这个解决方案 - 谢谢:

aspectratio.png是一个完全透明的PNG文件,其大小与首选宽高比相同,在我的情况下为30x10像素。

HTML

<div class="eyecatcher">
  <img src="/img/aspectratio.png"/>
</div>

CSS3

.eyecatcher img {
  width: 100%;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-image: url(../img/autoresized-picture.jpg);
}

请注意: background-size是一项css3功能,可能无法与您的目标浏览器配合使用。您可以检查互操作性(例如caniuse.com)。

答案 5 :(得分:11)

正如here on w3schools.com中所述并在此accepted answer中有所重申,填充值为百分比(强调我的):

  

包含元素

的宽度的百分比指定填充

Ergo,保持16:9宽高比的响应式DIV的正确示例如下:

CSS

.parent {
    position: relative;
    width: 100%;
}
.child {
    position: relative;
    padding-bottom: calc(100% * 9 / 16);
}
.child > div {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

HTML

<div class="parent">
    <div class="child">
        <div>Aspect is kept when resizing</div>
    </div>
</div>

Demo on JSFiddle

答案 6 :(得分:8)

基于你的解决方案,我做了一些技巧:

当您使用它时,您的HTML将只是

<div data-keep-ratio="75%">
    <div>Main content</div>
</div>

以这种方式使用它: CSS:

*[data-keep-ratio] {
    display: block;
    width: 100%;
    position: relative;
}
*[data-keep-ratio] > * {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
}

和js(jQuery)

$('*[data-keep-ratio]').each(function(){ 
    var ratio = $(this).data('keep-ratio');
    $(this).css('padding-bottom', ratio);
});

有了这个,你只需将at data-keep-ratio设置为高度/宽度即可。

答案 7 :(得分:7)

这是对已接受答案的改进:

  • 使用伪元素代替包装div
  • 纵横比是基于框的宽度而不是其父级
  • 当内容变高时,该框将垂直拉伸

.box {
  margin-top: 1em;
  margin-bottom: 1em;
  background-color: #CCC;
}

.fixed-ar::before {
  content: "";
  float: left;
  width: 1px;
  margin-left: -1px;
}
.fixed-ar::after {
  content: "";
  display: table;
  clear: both;
}

.fixed-ar-16-9::before {
  padding-top: 56.25%;
}
.fixed-ar-3-2::before {
  padding-top: 66.66%;
}
.fixed-ar-4-3::before {
  padding-top: 75%;
}
.fixed-ar-1-1::before {
  padding-top: 100%;
}

.width-50 {
  display: inline-block;
  width: 50%;
}
.width-20 {
  display: inline-block;
  width: 20%;
}
<div class="box fixed-ar fixed-ar-16-9">16:9 full width</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-50">16:9</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-20">16:9</div>
<div class="box fixed-ar fixed-ar-3-2 width-20">3:2</div>
<div class="box fixed-ar fixed-ar-4-3 width-20">4:3</div>
<div class="box fixed-ar fixed-ar-1-1 width-20">1:1</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-20">16:9</div>
<div class="box fixed-ar fixed-ar-16-9 width-50">16:9</div>

答案 8 :(得分:7)

由于@ web-tiki已经显示了使用vh / vw的方法,我还需要一种在屏幕中居中的方法,这里是 9:16 <的代码段< / strong>肖像。

.container {
  width: 100vw;
  height: calc(100vw * 16 / 9);
  transform: translateY(calc((100vw * 16 / 9 - 100vh) / -2));
}

translateY会将此中心保留在屏幕上。 calc(100vw * 16 / 9)预计9月16日的高度。(100vw * 16 / 9 - 100vh)是溢出高度,因此,上拉overflow height/2会使其保持在屏幕中心。

对于风景,并保持 16:9 ,您显示使用

.container {
  width: 100vw;
  height: calc(100vw * 9 / 16);
  transform: translateY(calc((100vw * 9 / 16 - 100vh) / -2));
}

比率9/16易于更改,无需预定义100:56.25100:75。如果您想先确保身高,则应切换宽度和高度,例如: height:100vh;width: calc(100vh * 9 / 16) 9:16肖像。

如果您想要适应不同的屏幕尺寸,您可能也会感兴趣

  • background-size涵盖/包含
    • 以上样式类似于包含,取决于宽度:高度比。
  • object-fit
    • 封面/包含img / video标签
  • @media (orientation: portrait) / @media (orientation: landscape)
    • 媒体查询portrait / landscape以更改比率。

答案 9 :(得分:7)

你可以使用svg。使容器/包装器位置相对,将svg放在静止位置,然后放置绝对定位的内容(顶部:0;左:0;右:0;底部:0;)

比例为16:9的例子:

image.svg :(可以在src中内联)

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 9" width="16" height="9"/>

CSS:

.container {
  position: relative;
}
.content {
  position: absolute;
  top:0; left:0; right:0; bottom:0;
}

HTML:

<div class="container">
  <img style="width: 100%" src="image.svg" />
  <div class="content"></div>
</div>

请注意,内联svg似乎不起作用,但您可以对svg进行urlencode并将其嵌入img src属性中,如下所示:

<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%209%22%20width%3D%2216%22%20height%3D%229%22%2F%3E" style="width: 100%;" />

答案 10 :(得分:5)

2021 解决方案 - 使用 aspect-ratio CSS 属性

(目前支持 Chromium、Safari Technology Preview 和 Firefox Nightly)

<div class='demo'></div>
.demo {
  background: black;
  width: 500px;
  aspect-ratio: 4/3;
}

答案 11 :(得分:5)

SCSS是我案例中最好的解决方案;使用数据属性:

<div data-aspect-ratio="16:9"><iframe ...></iframe></div>

例如:

=INDEX($A$13:$A$5000,MATCH("start*",$A$13:$A$5000,0))

source

答案 12 :(得分:4)

2020解决方案-使用网格和伪元素填充

我找到了解决此问题的一些更新颖的方法。此解决方案是任何padding-bottom方法的后代,但没有任何position: absolute子级,仅使用display: grid;和伪元素。

在这里,我们有.ratio::before和旧的padding-bottom: XX%grid-area: 1 / 1 / 1 / 1;,它们迫使伪元素将位置保持在网格中。尽管在这里我们有width: 0;来防止这个元素溢出主元素(我们在这里冷使用z-index,但是这个元素较短)。

我们的主要元素.ratio > *:first-child.ratio::before的位置相同,即grid-area: 1 / 1 / 1 / 1;,因此它们都共享相同的网格单元位置。现在我们可以在div中放入任何内容,而伪元素是确定宽高比的元素。有关grid-area的更多信息。

.ratio {
  display: grid;
  grid-template-columns: 1fr;
  max-width: 200px; /* just for instance, can be 100% and depends on parent */  
}

.ratio::before {
  content: '';
  width: 0;
  padding-bottom: calc(100% / (16/9)); /* here you can place any ratio */
  grid-area: 1 / 1 / 1 / 1;
}

.ratio>*:first-child {
  grid-area: 1 / 1 / 1 / 1; /* the same as ::before */
  background: rgba(0, 0, 0, 0.1); /* just for instance */
}
<div class="ratio">
  <div>16/9</div>
</div>


尽管您可以使用CSS val并使用style属性将其放置在HTML中。也可以与display: inline-grid一起使用。

.ratio {
  display: inline-grid;
  grid-template-columns: 1fr;
  width: 200px; /* just for instance, can be 100% and depends on parent */ 
  margin-right: 10px; /* just for instance */
}

.ratio::before {
  content: '';
  width: 0;
  padding-bottom: calc(100% / (var(--r))); /* here you can place any ratio */
  grid-area: 1 / 1 / 1 / 1;
}

.ratio>*:first-child {
  grid-area: 1 / 1 / 1 / 1; /* the same as ::before */
  background: rgba(0, 0, 0, 0.1); /* just for instance */
}
<div class="ratio" style="--r: 4/3;">
  <div>4/3</div>
</div>

<div class="ratio" style="--r: 16/9;">
  <div>16/9</div>
</div>

答案 13 :(得分:4)

好吧,我们最近获得了在CSS中使用aspect-ratio属性的功能。

https://twitter.com/Una/status/1260980901934137345/photo/1

注意:支持还不是最好的...

https://caniuse.com/#search=aspect-ratio

答案 14 :(得分:4)

使用canvas元素维护长宽比的简单方法。

尝试调整以下div的大小以查看其作用。

对于我来说,这种方法效果最好,所以我与其他人共享它,以便他们也可以从中受益。

.cont {
  border: 5px solid blue;
  position: relative;
  width: 300px;
  padding: 0;
  margin: 5px;
  resize: horizontal;
  overflow: hidden;
}

.ratio {
  width: 100%;
  margin: 0;
  display: block;
}

.content {
  background-color: rgba(255, 0, 0, 0.5);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  margin: 0;
}
<div class="cont">
  <canvas class="ratio" width="16" height="9"></canvas>
  <div class="content">I am 16:9</div>
</div>

也可以使用动态高度!

.cont {
  border: 5px solid blue;
  position: relative;
  height: 170px;
  padding: 0;
  margin: 5px;
  resize: vertical;
  overflow: hidden;
  display: inline-block; /* so the div doesn't automatically expand to max width */
}

.ratio {
  height: 100%;
  margin: 0;
  display: block;
}

.content {
  background-color: rgba(255, 0, 0, 0.5);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  margin: 0;
}
<div class="cont">
  <canvas class="ratio" width="16" height="9"></canvas>
  <div class="content">I am 16:9</div>
</div>

答案 15 :(得分:3)

假设你有2个div,其他div是一个容器,内部可以是你需要保持其比例的任何元素(img或youtube iframe或其他)

html看起来像这样:

<div class='container'>
  <div class='element'>
  </div><!-- end of element -->

假设你需要保持“元素”的比例

ratio =&gt; 4比1或2比1 ......

css看起来像这样

.container{
  position: relative;
  height: 0
  padding-bottom : 75% /* for 4 to 3 ratio */ 25% /* for 4 to 1 ratio ..*/

}

.element{
  width : 100%;
  height: 100%;
  position: absolute; 
  top : 0 ;
  bottom : 0 ;
  background : red; /* just for illustration */
}

以%指定时填充,它是根据宽度而不是高度计算的。 .. 所以基本上你无论你的宽度是多少,它总是根据它来计算高度。这将保持比例。

答案 16 :(得分:2)

只是一个想法或一个黑客。

&#13;
&#13;
div {
  background-color: blue;
  width: 10%;
  transition: background-color 0.5s, width 0.5s;
  font-size: 0;
}

div:hover {
  width: 20%;
  background-color: red;
}
  
img {
  width: 100%;
  height: auto;
  visibility: hidden;
}
&#13;
<div>
  <!-- use an image with target aspect ratio. sample is a square -->
  <img src="http://i.imgur.com/9OPnZNk.png" />
</div>
&#13;
&#13;
&#13;

答案 17 :(得分:2)

实际上,高票数的答案是一个非常好的解决方案,但有一个新的 CSS 功能,名称为 aspect-ratio

可以这样使用:

.someClass {
  width: 100%;
  aspect-ratio: 4/3;
}

它会自动确定其高度,但请参阅兼容性表:

enter image description here

如果浏览器支持对您的项目很重要,请不要使用它。使用 padding-bottom 技术。

答案 18 :(得分:2)

我偶然发现a smart solution使用<svg>display:grid

Grid元素允许您使用两个(或更多)元素占据相同的空间,而无需指定哪个元素来设置高度。也就是说,更高的那个设置比率

这意味着您可以按原样使用它,当您知道内容永远不会高到无法填充整个“比率”,而您只是在寻找一种将内容放置在此空间中的方法(即将其居中放置)双向使用  display:flex; align-items:center; justify-content:center
它与使用具有<img>和预定比率的透明display:block几乎相同,除了<svg>较轻且易于修改(根据需要更改比率以响应方式)

<div class="ratio">
  <svg viewBox="0 0 1 1"></svg>
  <div>
    I'm square
  </div>
</div>
.ratio {
  display: grid;
}
.ratio > * {
  grid-area: 1/1/1/1;
}

您需要做的就是更改<svg>的比率:

  • <svg viewBox="0 0 4 3"></svg>
  • <svg viewBox="0 0 16 9"></svg>

看到它正常工作:

.ratio {
  display: grid;
}
.ratio > * {
  grid-area: 1/1/1/1;
}

/* below code NOT needed for setting the ratio 
 * I just wanted to mark it visually
 * and center contents
 */
.ratio div {
  border: 1px solid red;
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="ratio">
  <svg viewBox="0 0 7 1"></svg>
  <div>
    Fixed ratio 7:1
  </div>
</div>


如果您需要一种解决方案,其中不允许content元素设置更高的比例(隐藏或自动溢出),则需要在网格上设置position:relative,在网格上设置position:absolute; height:100%; overflow-y: auto;内容。示例:

.ratio {
  display: grid;
  position: relative;
}
.ratio > * {
  grid-area: 1/1/1/1;
}


.ratio > div {
  height: 100%;
  overflow-y: auto;
  position: absolute;
  
  /* the rest is not needed */
  border: 1px solid red;
  padding: 0 1rem;
}
<div class="ratio">
  <svg viewBox="0 0 7 1"></svg>
  <div>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. A scelerisque purus semper eget. Sem nulla pharetra diam sit amet nisl suscipit adipiscing bibendum. A cras semper auctor neque vitae tempus quam pellentesque nec. Morbi enim nunc faucibus a pellentesque sit amet porttitor. Arcu odio ut sem nulla. Sed viverra ipsum nunc aliquet bibendum enim facilisis gravida neque. Cras tincidunt lobortis feugiat vivamus at augue eget. Laoreet sit amet cursus sit amet. Amet nulla facilisi morbi tempus iaculis urna id volutpat. Leo in vitae turpis massa sed elementum tempus egestas sed. Egestas integer eget aliquet nibh. Dolor sit amet consectetur adipiscing elit.

<p>Ut aliquam purus sit amet. Eget magna fermentum iaculis eu non diam phasellus vestibulum. Diam in arcu cursus euismod quis viverra nibh. Nullam vehicula ipsum a arcu cursus vitae congue. Vel orci porta non pulvinar neque laoreet suspendisse. At tellus at urna condimentum mattis pellentesque. Tristique senectus et netus et malesuada. Vel pretium lectus quam id leo in. Interdum velit euismod in pellentesque. Velit euismod in pellentesque massa placerat duis. Vitae suscipit tellus mauris a diam maecenas sed enim.

<p>Mauris a diam maecenas sed enim ut sem. In hendrerit gravida rutrum quisque. Amet dictum sit amet justo donec enim diam. Diam vulputate ut pharetra sit amet aliquam id. Urna porttitor rhoncus dolor purus non enim praesent. Purus in massa tempor nec feugiat nisl pretium. Sagittis vitae et leo duis ut. Facilisi nullam vehicula ipsum a arcu cursus vitae congue mauris. Volutpat odio facilisis mauris sit amet massa vitae tortor condimentum. Aliquam purus sit amet luctus venenatis lectus magna. Sit amet purus gravida quis blandit turpis. Enim eu turpis egestas pretium aenean. Consequat mauris nunc congue nisi. Nunc sed id semper risus in hendrerit gravida rutrum. Ante metus dictum at tempor. Blandit massa enim nec dui nunc mattis enim ut.
  </div>
</div>

答案 19 :(得分:2)

虽然大多数答案非常酷,但大多数答案都要求图像已经正确尺寸...其他解决方案仅适用于宽度而不关心可用的高度,但有时您希望将内容放入一定的高度。

我试图将它们结合在一起以带来一个完全可移植且可重新调整大小的解决方案......诀窍是使用自动缩放图像但使用内联svg元素而不是使用预渲染图像或任何形式的第二个HTTP请求......

div.holder{
  background-color:red;
  display:inline-block;
  height:100px;
  width:400px;
}
svg, img{
  background-color:blue;
  display:block;
  height:auto;
  width:auto;
  max-width:100%;
  max-height:100%;
}
.content_sizer{
  position:relative;
  display:inline-block;
  height:100%;
}
.content{
  position:absolute;
  top:0;
  bottom:0;
  left:0;
  right:0;
  background-color:rgba(155,255,0,0.5);
}
<div class="holder">
  <div class="content_sizer">
    <svg width=10000 height=5000 />
    <div class="content">
    </div>
  </div>
</div>

请注意,我在SVG的宽度和高度属性中使用了较大的值,因为它需要大于最大预期大小,因为它只能缩小。该示例使div的比率为10:5

答案 20 :(得分:1)

我想分享我的解决方案,其中我有一个img标签来填充特定的长宽比。由于缺乏CMS的支持,我无法使用background,并且我不喜欢使用像<img style="background:url(...)" />这样的样式标签。另外,宽度为100%,因此不需要像某些解决方案一样将其设置为固定大小。它将迅速响应!

.wrapper {
  width: 50%;
}

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

.image-container::before {
  content: "";
  display: block;
}

.image-container img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ratio-4-3::before {
  padding-top: 75%;
}

.ratio-3-1::before {
  padding-top: calc(100% / 3);
}

.ratio-2-1::before {
  padding-top: 50%;
}
<div class="wrapper"> <!-- Just to make things a bit smaller -->
  <p>
  Example of an 4:3 aspect ratio, filled by an image with an 1:1 ratio.
  </p>
  <div class="image-container ratio-4-3"> <!-- Lets go for a 4:3 aspect ratio -->
    <img src="https://placekitten.com/1000/1000/" alt="Kittens!" />
  </div>
  <p>
  Just place other block elements around it; it will work just fine.
  </p>
</div>

答案 21 :(得分:1)

如果您想在纵向视图中放置一个正方形在纵向或横向视图中(尽可能大,但没有任何东西粘在外面),请在方向{{1}上使用vw / vh之间切换}} / portrait

landscape

答案 22 :(得分:1)

我已经遇到过这个问题很多次了,所以我为它制作了一个JS解决方案。这基本上根据元素的宽度按您指定的比例调整domElement的高度。您可以按照以下方式使用它:

<div ratio="4x3"></div>

请注意,由于设置元素的高度,因此该元素应为display:blockdisplay:inline-block

https://github.com/JeffreyArts/html-ratio-component

答案 23 :(得分:1)

我刚刚创建了一个2:1的div,该div的大小可以调整为占据整个宽度,但是如果会导致顶部或底部超出范围,则可以缩小宽度。但是请注意,这仅适用于窗口的大小,而不适用于父窗口的大小。

#scene {
    position: relative;
    top: 50vh;
    left: 50vw;
    width: 100vw;
    height: 50vw;
    max-height: 100vh;
    max-width: calc(100vh * 2);
    transform: translate(-50%, -50%);
}

我确定您可以算出4:3而不是2:1使用的正确百分比。

答案 24 :(得分:0)

新的宽高比标签会很棒,但它弄乱了我的 div 的定位。 填充包装器 div 的传统解决方案有效,但仅根据父级或视口的宽度调整大小,这使得 当高度是限制因素时会出现问题

我发现 min() 函数非常有用,并像这样调整了传统方法:

body{
    background-image: linear-gradient(to top right, #FFE6B5, #B3CEBF);
    padding: 0;
    margin: 0 auto;
    overflow-y: hidden; /* this is to avoid scrolling when the height of the viewport is less than what the aspect ratio requires */
}

.wrapper {
    position: relative;
    width: 100vw;
    max-height: 100vh;
}
.sixteen-by-nine.aspect-ratio { 
    padding-bottom: 56.25% /* 9:16 ratio */
}
.content {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
    background-color: green
}

.centered {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    height: 100%;
    width: min(177.8vh, 100%); /* this always keeps a 16:9 ratio within the viewport */
    font-size: min(3vh,1.7vw); /* if you are also interested in scaling the font size */
    background-color: blue
}
<body>
  <div class="wrapper">
    <div class="sixteen-by-nine aspect-ratio"></div>
    <div class="content" >
      <div class="centered">
        <!-- stuff goes here -->
      </div>
    </div>
  </div>
</body>

答案 25 :(得分:0)

CSS 有一个新属性:aspect-ratio

<块引用>

https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio

@supports (aspect-ratio: 1 / 1) {
  div {
    aspect-ratio: 16 / 9;
    background-color: orange;
  }  
}
<div style="width: 200px"></div>
<hr />
<div style="width: 400px"></div>
<hr />
<div style="height: 50px"></div>
<hr />
<div style="height: 10px"></div>

Chrome 和 Edge 自 V88 以来一直完全支持此功能,而 Firefox 自 V81 以来一直在背后支持它(在 {{3} 中将 layout.css.aspect-ratio.enabled 设置为 true }).

有关兼容性信息,请检查 about:config

答案 26 :(得分:0)

我想只使用 rem 或 em 应该可以解决固定比例的问题,但不会像 vwvh 那样硬绑定到屏幕上,也不会像 % 那样与 flexbox 一起使用很痛苦是。好吧,没有一个答案适合我,就我而言,这对我有用:

<div class="container">
   <div>
   </div>
</div>
.container {
   height: 100vh;
   width: 100vw;
}
.container div {
   height: 4em;
   width: 3em;
}

或者使用 rem。但无论如何,他们中的任何一个都应该成功。
rem 使用默认字体大小值作为 em 使用最接近的字体大小。

答案 27 :(得分:0)

我想分享这个,因为我经历了几天令人沮丧的旅程,才找到对我有用的解决方案。我正在使用这些填充技术(上面提到了使用一些填充和绝对定位的变化)来实现 1:1 纵横比,用于网格/flex 布局内部的类似按钮的元素。布局设置为 100vh 高,以便它始终显示为单个非滚动页面。

填充技术确实工作得很好,但它很容易破坏您的网格布局并导致井喷/讨厌的滚动条。在这种情况下,那些说绝对 div 不能影响布局的人是错误的,因为父级的高度和/或宽度都在增长,即使子级不直接,父级也会干扰您的布局。

通常这不是问题,但使用网格时需要注意。网格是一种 2D 布局,它可以考虑在两个轴上调整大小和布局。我仍在尝试了解其确切性质,但到目前为止,似乎至少如果您在两个轴上均受 fr 单位约束的网格区域内使用此技术,您几乎肯定会在方面时遇到井喷- ratio 项目增长或以其他方式更改布局(display:none 切换和用 css 交换网格区域也是布局更改问题,导致了我的井喷)。

就我而言,我限制了不需要的列的高度。将其更改为“自动”而不是“1fr”可以保持我所有其他布局相同并防止井喷,同时仍然让我保留漂亮的方形按钮!

我不知道这是否是这里每个人沮丧的根源,但这是一个很容易犯的错误,即使使用开发工具也不会让您准确了解井喷的来源情况,因为它实际上并不是单个元素将其炸毁的情况,而是网格布局扩大自身以保持这些 fr 单位在垂直和水平方向上准确。

答案 28 :(得分:0)

新的 CSS aspect-ratio 属性是 Chrome 88 中的新属性,并且很快会在其他浏览器中使用。

<块引用>

aspect-ratio CSS 属性设置框的首选纵横比,将用于计算自动大小和一些其他布局功能。

CSS Tricks Article

More Information

div {
  background: rebeccapurple;
  height:100px;
  margin:1em auto;
}

.square {
  aspect-ratio: 1 / 1;
  }
<div class="square">
  
</div>

答案 29 :(得分:0)

这是我的解决方案,用于在具有可选固定边距的div上以纵向或横向保持16:9的长宽比。

这是宽度/高度和最大宽度/最大高度属性与大众单位的组合。

在此示例中,悬停时添加了50px的顶部和底部边距。

html {
  height: 100%;
}

body {
  margin: 0;
  height: 100%;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}

.fixedRatio {
  max-width: 100vw;
  max-height: calc(9 / 16 * 100vw);
  width: calc(16 / 9 * 100vh);
  height: 100vh;
  
  /* DEBUG */
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: blue;
  font-size: 2rem;
  font-family: 'Arial';
  color: white;
  transition: width 0.5s ease-in-out, height 0.5s ease-in-out; 
}

.fixedRatio:hover {
  width: calc(16 / 9 * (100vh - 100px));
  height: calc(100vh - 100px);
}
<div class='container'>
  <div class='fixedRatio'>
    16:9
  </div>
</div>

Demo on JSFiddle

答案 30 :(得分:0)

您可以通过使用SVG来实现。

这取决于情况,但在某些情况下确实有用。例如,您可以设置background-image而不设置固定高度,也可以使用它以<iframe>16:9等比率嵌入youtube position:absolute

对于3:2比率,设置viewBox="0 0 3 2",依此类推。

示例:

div{
    background-color:red
}
svg{
    width:100%;
    display:block;
    visibility:hidden
}

.demo-1{width:35%}
.demo-2{width:20%}
<div class="demo-1">
  <svg viewBox="0 0 3 2"></svg>
</div>

<hr>

<div class="demo-2">
  <svg viewBox="0 0 3 2"></svg>
</div>

答案 31 :(得分:0)

说您要保持Width:100px和Height:50px(即2:1) 只需执行以下数学操作即可:

.pb-2to1 {
  padding-bottom: calc(50 / 100 * 100%); // i.e., 2:1
}

答案 32 :(得分:0)

您可以使用焊剂布局(FWD)。

https://en.wikipedia.org/wiki/Adaptive_web_design

它将扩展和维护布局,它有点复杂但允许页面调整大小而不像(RWD)那样推送内容。

它看起来像响应但它正在缩放。 https://www.youtube.com/watch?v=xRcBMLI4jbg

您可以在此处找到CSS缩放公式:

http://plugnedit.com/pnew/928-2/

答案 33 :(得分:-1)

我使用了新的解决方案。

.squares{
  width: 30vw
  height: 30vw

达到主要宽高比

.aspect-ratio
  width: 10vw
  height: 10vh

但是,这与整个视口相关。因此,如果你需要一个占视口宽度30%的div,你可以使用30vw,因为你知道宽度,你可以使用calc和vw单位在高度重复使用它们。

答案 34 :(得分:-1)

container {
   height: 100vh;
   width: 100vw;
}
.container div {
   height: 4em;
   width: 3em;
}

答案 35 :(得分:-2)

如果整个容器结构是基于百分比的,这将是默认行为,您能提供更具体的示例吗?

下面是我的意思的一个例子,如果您的整个父级层次结构是基于%的,任何浏览器窗口调整都可以在没有任何额外的js / css的情况下工作,这是不是您的布局可能吗?

<div style="width: 100%;">
   <div style="width: 50%; margin: 0 auto;">Content</div>
</div>