提问



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


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


我知道我可以通过JavaScript实现这一点,但我更喜欢只使用CSS。


[68]

最佳参考


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




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

<div></div>



vw单位:



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



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



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


示例:1:1宽高比





div {
  width: 20vw;
  height: 20vw;
  background: gold;
}

<div></div>



我已经找到了使用CSS做到这一点的方法,但你必须要小心,因为它可能会根据你自己网站的流量而改变。我已经完成了它,以便在流体中嵌入具有恒定宽高比的视频我网站的宽度部分。


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


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


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


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


!重要的是,图像具有您希望保持的正确宽高比。此外,请确保图像的大小至少与您期望的视频(或者您维护A.R.的任何内容)一样大,以便根据您的布局获得。这将避免在调整百分比时图像分辨率中的任何潜在问题。例如,如果你想保持3:2的宽高比,不要只使用3px乘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%,充分利用动态图像提供的不动产。


很酷,嗯?


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

其它参考1


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


如果您希望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请求。

其它参考2


艾略特激励我使用这个解决方案 - 谢谢:


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上)。[72]

其它参考3


正如在w3schools.com上所述并在这个已接受的答案中有所重申,填充值为百分比(强调我的):[73]



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



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>


关于JSFiddle的演示[75]

其它参考4


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


当您使用它时,您的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);
});


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

其它参考5


你可以使用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%;" />

其它参考6


由于@ 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.25100:75。如果要首先确保高度,则应切换宽度和高度,例如: height:100vh;width: calc(100vh * 9 / 16)为9:16画像。


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



  • 背景大小封面/包含


    • 以上样式类似于包含,取决于宽度:高度比。


  • 对象配合


    • 封面/包含img/video标签


  • @media (orientation: portrait)/@media (orientation: landscape)


    • 媒体查询portrait/landscape以更改比率。



其它参考7


在我的案例中,SCSS是最好的解决方案;使用数据属性:[76] [77]


[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>


[78]

其它参考8


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




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>



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



HTML看起来像这样:


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




让我们说你需要保持元素的比例


ratio => 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 */
}


以%指定时填充,它是根据宽度而不是高度计算的。
..
所以基本上你不重要的是它的宽度总是根据它计算高度。这将保持比率。

其它参考9


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


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


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


https://github.com/JeffreyArts/html-ratio-component[79]

其它参考10


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


我已经尝试将它们结合在一起以带来一个完全可移植且可重新调整大小的解决方案......诀窍是使用自动缩放图像但使用内联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>



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


@media (orientation:portrait ) {
  .square {
    width :100vw;
    height:100vw;
  }
} 
@media (orientation:landscape) {
  .square {
    width :100vh;
    height:100vh;
  }
} 

其它参考11


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


https://en.wikipedia.org/wiki/Adaptive_web_design[80]


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


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


你可以在这里找到CSS缩放公式:


http://plugnedit.com/pnew/928-2/[82]

其它参考12


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



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



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


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


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

其它参考13


我用了一个新的解决方案。


.squares{
  width: 30vw
  height: 30vw


主要宽高比


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


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