根据纵横比响应性地改变div大小

226

当我给一张图片设置百分比宽度或高度时,它会保持纵横比而增加或缩小大小。但是如果我希望另一个元素也具有相同的效果,是否有可能使用百分比将宽度和高度绑定在一起呢?

5个回答

544
你可以使用纯CSS来实现此操作,不需要JavaScript。这利用了一个有点反直觉的事实,即 padding-top 百分比是相对于包含块的 宽度 的。以下是一个例子:

.wrapper {
  width: 50%;
  /* whatever width you want */
  display: inline-block;
  position: relative;
}
.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;
}
<div class="wrapper">
  <div class="main">
    This is your div with the specified aspect ratio.
  </div>
</div>


28
我必须说这太棒了,它甚至可以在IE上运行。大加赞赏。 - Peter
2
@IlyaD 请看一下CSS2规范中的这个链接:小链接 - Chris
8
先生,您赢得了互联网。这是一件大事,特别是对于响应式设计中的背景图像。谢谢! - Vidal Quevedo
50
对于像我这样的数学笨蛋,如果要计算非16:9比例元素的padding-top百分比,请使用以下公式(例如使用22:5比例,其中22是A,5是B):B /(A / 100)= C%。因此,22:5是5 / .22 = 22.72%。 - Dreamdealer
1
如何将 <div class="main"> 垂直居中于 body 中? - Krunal Mevada
显示剩余13条评论

46

基于 Chris 的想法,另一个选项是使用伪元素,这样就不需要使用绝对定位的内部元素了。

<style>
.square {
    /* width within the parent.
       can be any percentage. */
    width: 100%;
}
.square:before {
    content: "";
    float: left;

    /* essentially the aspect ratio. 100% means the
       div will remain 100% as tall as it is wide, or
       square in other words.  */
    padding-bottom: 100%;
}
/* this is a clearfix. you can use whatever
   clearfix you usually use, add
   overflow:hidden to the parent element,
   or simply float the parent container. */
.square:after {
    content: "";
    display: table;
    clear: both;
}
</style>
<div class="square">
  <h1>Square</h1>
  <p>This div will maintain its aspect ratio.</p>
</div>

我已经在这里制作了一个演示:http://codepen.io/tcmulder/pen/iqnDr


编辑:

现在,借鉴Isaac的想法,在现代浏览器中使用vw单位来强制宽高比更加容易(尽管我不建议也使用vh,因为这样宽高比将基于窗口高度而改变)。

所以,这简化了事情:

<style>
.square {
    /* width within the parent (could use vw instead of course) */
    width: 50%;
    /* set aspect ratio */
    height: 50vw;
}
</style>
<div class="square">
  <h1>Square</h1>
  <p>This div will maintain its aspect ratio.</p>
</div>

我在这里提供了一个修改过的演示: https://codepen.io/tcmulder/pen/MdojRG?editors=1100

此外,如果您不想让它变得非常大或非常小,您还可以设置最大高度、最大宽度和/或最小高度、最小宽度,因为现在它是基于浏览器的宽度而不是容器的宽度,并且会无限制地增长 / 缩小。

请注意,如果您将字体大小设置为vw测量单位并将所有内容设置为em测量单位,则还可以缩放元素内部的内容。这是一个演示:https://codepen.io/tcmulder/pen/VBJqLV?editors=1100


3
太棒了,因为你不需要一个包装元素。做得好! - Jim Buck
3
如何防止子元素的内容扩展父元素的高度? - Jacob Raccuia
我无法让这种更短的方法在IE10中运行。 - cyberwombat
是的,如果子级可以展开父级,则此方法无效。 - user541686
你可以在 .square 元素上使用 display: flow-root 或 contain: content,而不是使用 clearfix hack:https://codepen.io/fcalderan/pen/xxRPwgL - Fabrizio Calderan

31
<style>
#aspectRatio
{
  position:fixed;
  left:0px;
  top:0px;
  width:60vw;
  height:40vw;
  border:1px solid;
  font-size:10vw;
}
</style>
<body>
<div id="aspectRatio">Aspect Ratio?</div>
</body>

需要注意的关键是 vw 表示视口宽度,vh 表示视口高度


2
请注意,如果屏幕的比例不同,则元素的比例也会不同,从而失去了纵横比。 - Ryan Killeen
9
除了他在使用“vw”来表示宽度和高度,其他看起来都没问题。因此百分比仍然具有相同的长宽比。 - christophercotton
1
@christophercotton... 这就是我匆忙阅读的结果。你是正确的。 - Ryan Killeen

3
那是我的解决方案
<div class="main" style="width: 100%;">
    <div class="container">
        <div class="sizing"></div>
        <div class="content"></div>
    </div>
</div>

.main {
    width: 100%;
}
.container {
    width: 30%;
    float: right;
    position: relative;
}
.sizing {
    width: 100%;
    padding-bottom: 50%;
    visibility: hidden;
}
.content {
    width: 100%;
    height: 100%;
    background-color: red;
    position: absolute;
    margin-top: -50%;
}

http://jsfiddle.net/aG4Fs/3/


2
(function( $ ) {
  $.fn.keepRatio = function(which) {
      var $this = $(this);
      var w = $this.width();
      var h = $this.height();
      var ratio = w/h;
      $(window).resize(function() {
          switch(which) {
              case 'width':
                  var nh = $this.width() / ratio;
                  $this.css('height', nh + 'px');
                  break;
              case 'height':
                  var nw = $this.height() * ratio;
                  $this.css('width', nw + 'px');
                  break;
          }
      });

  }
})( jQuery );      

$(document).ready(function(){
    $('#foo').keepRatio('width');
});

Working example: http://jsfiddle.net/QtftX/1/


太好了!我正在使用这个脚本,但是如果我在多个DIV上使用它,并且它们每个都有不同的高度...一旦脚本启动,它会调整所有高度为相同的高度...我无法弄清楚为什么!有什么想法吗?我想像这个脚本一样保持纵横比,但是保持每个DIV的不同高度。 - Michael Giovanni Pumo
2
因为该函数应用于一组元素。 脚本应单独处理每个元素。 这是更新后的代码:http://jsfiddle.net/QtftX/100/ - onetdev
如果您刷新页面,宽度和高度将再次重置。如何阻止这种情况发生? - Gilko
这在iOS上不起作用。 - bryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接