根据高度设置宽度

19
我看到了一个关于高度根据宽度而定的解决方案:css height same as width。或者在这里查看:https://dev59.com/t2035IYBdhLWcg3wZvFg#6615994。 但我的问题是相反的。
我的元素:
<body>
    <div id="square"></div>
</body>

样式如下:

body, html {
    margin: 0;
    height: 100%;
    min-height: 300px;
    position: relative;
}
div#square { /* My square. */
    height: 75%; /* It's height depends on ancestor's height. */
    width: 75vh; /* If supported, preliminarily sets it's width. */
    position: absolute; /* Centers it. */
    left: 50%; top: 50%; transform: translate(-50%, -50%);
    background-color: darkorange; /* Makes it visible. */
}

保持一致的脚本:

window.onload = window.onresize = function (event) {
    var mySquare = document.getElementById("square");
    mySquare.style.width = mySquare.offsetHeight + 'px';
};

完整的代码在这里:http://jsfiddle.net/je1h/hxkgfr9g/

问题是使用纯CSS实现相同的效果,不使用脚本。


1
我不知道你是否可以在CSS中实现这个。你可以尝试https://css-tricks.com/snippets/css/a-guide-to-flexbox/,但我不确定那是否能帮到你。 - xdhmoore
这个能满足你的需求吗?http://stackoverflow.com/questions/12899031/css-squares-on-resize - xdhmoore
我也认为在纯CSS中不可能实现,尝试了很多次... 在样式化动态完美正方形之前,我们必须等待! 我唯一看到的选择是像你所写的那样使用Javascript。 - Sebastien
2个回答

16

我知道有两种技术可以根据元素的高度保持其纵横比:

高度相对于视口时:

您可以使用vh单位:

div {
  width: 75vh;
  height: 75vh;
  background:darkorange;
}
<div></div>


要根据父元素的高度来设置高度:

您可以使用具有所需宽高比的虚拟图像。例如,对于1:1的宽高比,您可以使用一个1*1透明的.png图像或如 @vlgalik 所述的一个1*1的Base64编码的gif文件。

html,body{
    height:100%;
    margin:0;
    padding:0;
}
#wrap{
    height:75%;
}
#el{
    display:inline-block;
    height:100%;
    background:darkorange;
}
#el img{
    display:block;
    height:100%;
    width:auto;
}
<div id="wrap">
    <div id="el">
        <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
    </div>
</div>

请注意,这个最后的示例在窗口调整大小时不会更新。但是宽高比在页面加载时保持不变。

更新:
评论中所述,对#el应用display:inline-flex;似乎可以解决窗口调整大小时的更新问题。


1
或者您可以使用Base64编码的1x1像素透明GIF <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">,或内联SVG(但在Firefox和旧版浏览器中存在一些SVG问题)。 - vlgalik
@vlgalik 不错,我更新了答案。 - web-tiki
谢谢你的回答。这是一个有趣的技巧,老实说,我并没有完全弄清楚它是如何工作的 :) 我们为什么需要“#wrap”,确切地说。正如你所提到的,不幸的是它不能在窗口调整大小时更新“#el”的宽度。 - jevgenij
@jevgenij #wrap 不是必需的,它只是为了演示,以显示您可以根据父元素(#wrap)的高度来保持纵横比。 - web-tiki
1
好的,我明白了,刚刚有点纠结 :) 还发现对于 #el,使用display:inline-flex; 解决了更新问题,但是当然也会带来兼容性问题。 - jevgenij
不错 @jevgenij 我之前不知道。我已经更新了答案。 - web-tiki

-1

编辑:没看到您想根据高度设置宽度,这个实现恰好相反了 :(


为了支持所有的比例,您可以使用padding-bottom。在padding-bottom中的百分比始终是相对于元素的宽度:

/* the wrapper has a width */
.wrapper {
  position: relative;
  width: 25%;
  margin-bottom: 10px;
}
/* these elements set the height (using padding-bottom) */
.square {
  padding-bottom: 100%;
  position: relative;
}
.widescreen {
  padding-bottom: 56.25%; /* 9/16 = 0.5625 */
}

/* 
 * This is the content. 
 * Needs position:absolute to not add to the width of the parent 
 */
.content {
  /* fill parent */
  position: absolute;  
  top: 0; bottom: 0;
  left: 0; right: 0;
  
  /* visual */
  padding: 10px;
  background: orange;
  color: white;
}
<div class="wrapper">
  <div class="square">
    <div class="content">square</div>
  </div>
</div>

<div class="wrapper">
  <div class="widescreen">
    <div class="content">16:9 ratio</div>
  </div>
</div>

唯一的缺点是,你需要一堆包装元素。

2
我们根据高度寻找宽度,而不是根据宽度寻找高度。 - JulianSoto

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