CSS:使div的宽度与高度成比例

41zrol4v  于 2023-04-08  发布在  其他
关注(0)|答案(8)|浏览(223)

这有点难以解释,但是:我想要一个响应高度的div(height: 100%),它将宽度按比例缩放到高度(反之亦然)。
我知道this method使用了padding-top的技巧来使高度与宽度成比例,但我需要它反过来工作。话虽如此,我并不非常热衷于在该方法中对内容的绝对定位元素的额外要求,所以我意识到我很可能在这里要求月亮。
为了帮助可视化,这里有一张图片:

这是一个jsFiddle,说明了几乎相同的事情。
值得注意的是,我已经使用:before:after伪元素来垂直对齐我想要按比例缩放的框的内容。
我真的很喜欢不必恢复到jQuery,只是因为这将是一个对调整大小处理程序的内在要求,并且通常需要更多的调试......但如果这是我唯一的选择,那么 fiat

xmakbtuz

xmakbtuz1#

我一直在想用纯css解决这个问题,最后我想到了一个使用ems的解决方案,它可以使用vws来逐步增强:
有关完整的工作演示和解释,请参见codepen链接:
http://codepen.io/patrickkunka/pen/yxugb
简化版:

.parent {
  font-size: 250px; // height of container
  height: 1em;
}

.child {
  height: 100%;
  width: 1em; // 100% of height
}
camsedfj

camsedfj2#

你可以用那个“垫顶”的把戏

width: 50%;
height: 0;
padding-bottom: 50%;

http://absolide.tumblr.com/post/7317210512/full-css-fluid-squares
或者:

.square-box{
    position: relative;
    width: 50%;
    overflow: hidden;
    background: #4679BD;
}
.square-box:before{
    content: "";
    display: block;
    padding-top: 100%;
}

http://codeitdown.com/css-square-rectangle/
CSS中的垂直填充与元素的宽度有关,而不是高度。

ddrv8njm

ddrv8njm3#

字体解决方案要求高度是已知的。我已经找到了一个解决方案,可以在宽度和高度未知的父div中使元素成比例。Here is a demo
我使用的技巧是将图像用作间隔符。代码解释如下:

<div class="heightLimit">
 <img width="2048" height="2048" class="spacer"
  src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAA
       P///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
 <div class="filler">
  <div class="proportional">
  </div>
 </div>
</div>

因此,它不是最漂亮的两个额外的div和一个无用的图像。但它可能会更糟。图像元素需要具有所需尺寸的宽度和高度。宽度和高度需要与允许的最大尺寸一样大(一个功能!)。
CSS:

.heightLimit {
 position: absolute;
 top: 0;
 left: 0;
 height: 100%;
 width: auto;
 max-width: 100%;
 overflow: hidden;
}

这个元素是用来限制高度的,但是水平扩展(width: auto),虽然永远不会超过父元素(max-width)。溢出需要隐藏,因为一些子元素会突出到div之外。

.spacer {
 width: auto;
 max-height: 100%;
 visibility: hidden;
}

此图像不可见并与高度成比例缩放,而宽度将被调整并强制父对象的宽度也被调整。

.filler {
 position: absolute;
 top: 0;
 left: 0;
 bottom: 0;
 right: 0;
}

这个元素是用一个绝对定位的容器填充空间所必需的。

.proportional {
 position: relative;
 width: 100%;
 height: 0;
 padding-bottom: 100%;
}

在这里,我们的比例元素使用熟悉的padding-bottom技巧获得与宽度成比例的高度。
不幸的是,在Chrome和IE中有一个错误,所以如果你使用Javascript修改父元素,例如在我的演示中,尺寸将不会更新。有一个黑客可以应用于解决这个问题,如我的演示所示。

q0qdq0h2

q0qdq0h24#

您可以使用view height(vh)作为width的单位。
这里是一个例子与20px保证金您要求的。

.parent {
   margin : 20px;
}
.child {
   width: calc(100vh - 40px);
   height : calc(100vh - 40px);
   margin:0 auto;
   background: red;
   box-sizing:border-box;
   padding:10px;
}

看小提琴:https://jsfiddle.net/svobczp4/

bqucvtff

bqucvtff5#

基于@kunkalabs的回答(这真的很聪明),我提出了一个解决方案,可以让您保留继承的font-size。
HTML:

<div id='rect'>
    <div id='content'>Text</div>
</div>

CSS:

#rect {
    font-size: 1000%;
    height: 1em;
    width: 1em;
    position: relative;
}

#content {
    font-size: 10%;
}

所以基本上#content的字体大小是(100 / $rectFontSize)* 矩形的100%。如果你需要一个确定的矩形像素大小,你可以设置#rect的父级的字体大小......否则只是调整字体大小,直到它在你想要的地方(在这个过程中激怒你的设计师)。

u0sqgete

u0sqgete6#

你可以通过使用SVG来实现这一点。
这取决于具体情况,但在某些情况下它确实很有用。举个例子-您可以设置background-image而不设置固定高度,或者使用它以16:9position:absolute的比例嵌入<iframe>
对于3:2比率设置viewBox="0 0 3 2"等等。
示例:

div{width:35%;background-color:red}
svg{width:100%;display:block;visibility:hidden}
<div>
  <svg viewBox="0 0 3 2"></svg>
</div>
dhxwm5r4

dhxwm5r47#

在较新的浏览器上,我们可以使用具有固定高度的aspect-ratio,并相应地计算宽度。

img {
    aspect-ratio: 1.2;
    height: 250px;
    max-width: 500px;
}

但是浏览器对aspect-ratio的支持还不够好。我喜欢@Jakub Muda提出的SVG解决方案,除了它需要修改标记的事实。我已经通过使用content属性将SVG移动到CSS中。在较新的浏览器上,它禁用SVG hack并切换到aspect-ratio属性。

document.querySelector('.nav').addEventListener('click', function(e) {
  var index = parseInt(e.target.dataset.index);
  if (!index) {
    return;
  }

  var elements = document.querySelectorAll('.box');
  for (var i = elements.length; i > 0; i--) {
    elements[i - 1].classList.toggle('hide', i !== index);
  }

});
.wrapper {
  max-width: 500px;
  margin: 0 auto;
  width: 100%;
  height: 250px;
  text-align: center;
  background: green;
}

.box {
  display: inline-flex;
  position: relative;
  max-width: 100%;
}

/* SVG Hack */

.box::before {
  display: block;
  line-height: 0;
  max-width: 100%;
  content: 'test';
}

[data-aspect-ratio="1"]::before {
  content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1' height='250'></svg>");
}

[data-aspect-ratio="2"]::before {
  content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2 1' height='250'></svg>");
}

[data-aspect-ratio="3"]::before {
  content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 3 1' height='250'></svg>");
}

@supports (aspect-ratio: 1) {
  /* Modern browsers */
  .box {
    height: 100%;
    background: green;
  }
  .box::before {
    display: none;
  }
  [data-aspect-ratio="1"] {
    aspect-ratio: 1;
  }
  [data-aspect-ratio="2"] {
    aspect-ratio: 2;
  }
  [data-aspect-ratio="3"] {
    aspect-ratio: 2;
  }
}

.content {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

.content>svg {
  display: block;
  width: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  height: auto;
  transform: translate(-50%, -50%);
}

.nav {
  text-align: center;
}

.hide {
  display: none;
}
<!doctype html>
<html lang="en">

<head>
  <title>Width proportional to height in CSS</title>
</head>

<body>
  <div class="wrapper">
    <div class="box" data-aspect-ratio="1">
      <div class="content">
        <svg viewBox="0 0 100 100" width="100" height="100" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="96" height="96" style="fill:#DEDEDE;stroke:#555555;stroke-width:2"/><text x="50%" y="50%" font-size="18" text-anchor="middle" alignment-baseline="middle" font-family="monospace, sans-serif" fill="#555555">100&#215;100</text></svg>
      </div>
    </div>
    <div class="box hide" data-aspect-ratio="2">
      <div class="content">
        <svg viewBox="0 0 200 100" width="200" height="100" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="196" height="96" style="fill:#DEDEDE;stroke:#555555;stroke-width:2"/><text x="50%" y="50%" font-size="18" text-anchor="middle" alignment-baseline="middle" font-family="monospace, sans-serif" fill="#555555">200&#215;100</text></svg>
      </div>
    </div>
    <div class="box hide" data-aspect-ratio="3">
      <div class="content">
        <svg viewBox="0 0 300 100" width="300" height="100" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="296" height="96" style="fill:#DEDEDE;stroke:#555555;stroke-width:2"/><text x="50%" y="50%" font-size="18" text-anchor="middle" alignment-baseline="middle" font-family="monospace, sans-serif" fill="#555555">300&#215;100</text></svg>
      </div>
    </div>
  </div>

  <div class="nav">
    <button data-index="1">1</button>
    <button data-index="2">2</button>
    <button data-index="3">3</button>
  </div>
</body>

</html>
kuhbmx9i

kuhbmx9i8#

使父DIV表现得像一个表格单元格,并垂直对齐子元素。不需要做任何填充技巧。
HTML

<div class="parent">
<img src="foo.jpg" />
</div>

CSS

.parent { width:300px; height:300px; display:table-cell; vertical-align:middle; }

相关问题