使用CSS保持div的长宽比

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

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

我知道我可以通过JavaScript来做到这一点,但我宁愿只使用CSS。

div根据窗口宽度保持宽高比

番长神无2020/03/15 18:36:57

您可以使用SVG来实现。

这取决于情况,但在某些情况下确实有用。作为一个例子-可以设置background-image不设置固定高度或者用它来嵌入YouTube <iframe>与比16:9position: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>

AStafan2020/03/15 18:36:57

我使用了新的解决方案。

.squares{
  width: 30vw
  height: 30vw

与主要纵横比

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

但是,这是相对于整个视口而言的。因此,如果需要的div是视口宽度的30%,则可以改用30vw,由于知道了宽度,因此可以使用calc和vw单位在高度上重复使用它们。

Near小哥神奇2020/03/15 18:36:57

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

以下是我的意思的示例,如果您整个父级层次结构均基于%,则无需任何其他js / css即可进行任何浏览器窗口调整,这是否可能与您的布局无关?

<div style="width: 100%;">
   <div style="width: 50%; margin: 0 auto;">Content</div>
</div>
乐米亚2020/03/15 18:36:57

您可以使用磁通布局(FWD)。

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

它将缩放和维护布局,这有点复杂,但允许页面大小调整而无需推送(RWD)之类的内容。

看起来像是响应式的,但它正在扩展。https://www.youtube.com/watch?v=xRcBMLI4jbg

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

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

十三前端Harry2020/03/15 18:36:57

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

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

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

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

2020/03/15 18:36:57

我想分享我的解决方案,其中有一个img-tag可以填充一定的宽高比。background由于缺乏CMS的支持,我无法使用,并且我不喜欢使用如下样式标签:<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>

十三古一2020/03/15 18:36:57

假设您希望维持Width:100px和Height:50px(即2:1),只需执行以下数学操作:

.pb-2to1 {
  padding-bottom: calc(50 / 100 * 100%); // i.e., 2:1
}
纳兰长歌2020/03/15 18:36:56

只是一个主意或破解。

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;
}
<div>
  <!-- use an image with target aspect ratio. sample is a square -->
  <img src="http://i.imgur.com/9OPnZNk.png" />
</div>

猿神奇2020/03/15 18:36:56

如果要在纵向或横向视图上使视口内适合一个正方形(尽可能大,但外面没有东西粘住),请在vw/ vh方向portrait/ 切换landscape

@media (orientation:portrait ) {
  .square {
    width :100vw;
    height:100vw;
  }
} 
@media (orientation:landscape) {
  .square {
    width :100vh;
    height:100vh;
  }
} 
GO路易西门2020/03/15 18:36:56

就我而言,SCSS是最好的解决方案。使用数据属性:

[data-aspect-ratio] {
    display: block;
    max-width: 100%;
    position: relative;

    &:before {
        content: '';
        display: block;
    }

    > * {
        display: block;
        height: 100%;
        left: 0;
        position: absolute;
        top: 0;
        width: 100%;
    }
}
[data-aspect-ratio="3:1"]:before {
    padding-top: 33.33%;
}
[data-aspect-ratio="2:1"]:before {
    padding-top: 50%;
}
[data-aspect-ratio="16:9"]:before {
    padding-top: 56.25%;
}
[data-aspect-ratio="3:2"]:before {
    padding-top: 66.66%;
}
[data-aspect-ratio="4:3"]:before {
    padding-top: 75%;
}
[data-aspect-ratio="1:1"]:before {
    padding-top: 100%;
}
[data-aspect-ratio="3:4"]:before {
    padding-top: 133.33%;
}
[data-aspect-ratio="2:3"]:before {
    padding-top: 150%;
}
[data-aspect-ratio="9:16"]:before {
    padding-top: 177.77%;
}
[data-aspect-ratio="1:2"]:before {
    padding-top: 200%;
}
[data-aspect-ratio="1:3"]:before {
    padding-top: 300%;
}

例如 :

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

资源

古一古一2020/03/15 18:36:56

虽然大多数答案都很酷,但是大多数答案都需要正确调整图像大小……其他解决方案仅适用于宽度,并不关心可用的高度,但有时您也希望将内容调整为一定的高度。

我试图将它们结合在一起以提供一个完全可移植且可调整大小的解决方案...诀窍是用于自动缩放图像,但使用内嵌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的width和height属性中使用了较大的值,因为它必须大于最大预期大小,因为它只能收缩。该示例使div的比例为10:5

西门Sam2020/03/15 18:36:56

您可以使用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%;" />
布雷西2020/03/15 18:36:56

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

  • 使用伪元素而不是包装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>

鸣人2020/03/15 18:36:56

由于@ web-tiki已经显示了使用vh/ 的方式vw,因此我也需要一种在屏幕上居中的方式,这是9:16人像的代码段

.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.25或设置100:75。如果要首先确保高度,则应切换宽度和高度,例如height:100vh;width: calc(100vh * 9 / 16)9:16纵向。

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

  • 背景尺寸封面/包含
    • 上面的样式类似于包含,取决于宽度:高度比率。
  • 对象拟合
    • 封面/包含img /视频标签
  • @media (orientation: portrait)/@media (orientation: landscape)
    • 媒体查询portrait/ landscape更改比率。
神乐蛋蛋2020/03/15 18:36:56

我找到了一种使用CSS进行此操作的方法,但是您必须小心,因为它可能会根据您自己的网站的流量而变化。我这样做是为了将具有恒定纵横比的视频嵌入到我的网站的宽度部分中。

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

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

然后,您可以将这些全部放入带有“视频”类的div中。该视频类可能是您网站中的不稳定元素,因此,它本身没有直接的高度限制,但是当您调整浏览器的大小时,它的宽度将根据网站的流量而变化。这可能是您在保持视频的特定纵横比的同时尝试获取嵌入式视频的元素。

为此,我将图像放置在“视频”类div中的嵌入式对象之前。

!!! 重要的是,图像具有您希望保持的正确的宽高比。另外,请确保图像的大小至少与您希望视频(或您要维护其AR)所依据的最小尺寸一样大。当按百分比调整大小时,这将避免图像分辨率中的任何潜在问题。例如,如果您想保持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%; }

确保您还删除了对象内的任何明确的高度或宽度声明,并嵌入了通常复制/粘贴嵌入代码随附的标签。

它的工作方式取决于视频类元素的位置属性,并且您想要的项目保持一定的宽高比。它利用了在元素中调整大小时图像将保持其适当纵横比的方式。它通过将动态图像的宽度/高度强制为要由图像调整的视频类别元素的100%,告诉视频类元素中的所有其他内容都可以充分利用动态图像提供的不动产。

很酷吧?

您可能需要花一点时间才能使其与您自己的设计一起使用,但这实际上对我来说效果很好。这里有一般概念。

小小2020/03/15 18:36:56

vw 单位:

您可以将vw单位用于元素宽度和高度这样可以根据视口宽度保留元素的宽高比。

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

另外,您也可以使用vh视口高度,甚至使用vmin/ vmax来使用视口尺寸的小/大(此处讨论)。

示例:1:1长宽比

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

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

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

示例:4x4格的div网格

body {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}
div {
  width: 23vw;
  height: 23vw;
  margin: 0.5vw auto;
  background: gold;
}
<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>

这是该演示小提琴,这是一种使响应的正方形网格具有垂直和水平居中内容的解决方案


IE9 +支持vh / vw单位的浏览器,请参见canIuse了解更多信息

猿阿飞Tom2020/03/15 18:36:56

为了增加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请求。

凯阿飞卡卡西2020/03/15 18:36:56

在w3schools.com上的此处所述,并在此公认的答案中有所重申,填充值以百分比表示(强调我的意思):

指定包含元素宽度的百分比的填充

因此,保持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>

JSFiddle上的演示

Jim前端Near2020/03/15 18:36:56

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上)。

西门神奇2020/03/15 18:36:56

只需创建一个<div>具有百分比值的包装器padding-bottom,如下所示:

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

/* demonstration purposed only : non-essential */
.demoWrapper {
  padding: 10px;
  background: white;
  box-sizing: border-box;
  resize: horizontal;
  border: 1px dashed;
  overflow: auto;
  max-width: 100%;
  height: calc(100vh - 16px);
}
<div class="demoWrapper">
  <div></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;
}

这是一个演示,还有另一个更深入的演示