解释起来有点棘手,但是:我想要一个响应式高度 div (
height: 100%
),它将按比例缩放 width 与 height(反之亦然)。
我知道 this method 利用
padding-top
hack 使高度与宽度成正比,但我需要它以相反的方式工作。话虽如此,我并不是非常热衷于对该方法中的内容的绝对定位元素的额外要求,所以我意识到我很可能在这里要求月亮在棍子上。
为了帮助形象化,这里有一张图片:
...这是一个 jsFiddle,说明了几乎相同的事情。
值得注意的是,我已经在使用
:before
和 :after
伪元素来垂直对齐我想要按比例缩放的框的内容。
我真的很享受不必恢复到 jQuery,只是因为对调整大小处理程序有一个内在的要求,并且通常会有更多的全面调试......但如果这是我唯一的选择,那么 fiat.
一段时间以来,我一直在想关于这个问题的纯 css 解决方案。我终于想出了一个使用 ems 的解决方案,可以使用 vws 逐步增强它:
有关完整的工作演示和说明,请参阅代码笔链接:
http://codepen.io/patrickkunka/pen/yxugb
简化版:
.parent {
font-size: 250px; // height of container
height: 1em;
}
.child {
height: 100%;
width: 1em; // 100% of height
}
哦,你可能会使用那个“padding-top”技巧。
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 中的垂直内边距与元素的宽度有关,而不是高度。
字体方案要求已知高度。我找到了一种解决方案,可以使元素在宽度和高度未知的父 div 内成比例。 这是一个演示.
我使用的技巧是将图像用作间隔物。代码解释:
<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%;
}
在这里,我们的比例元素使用熟悉的填充底部技巧获得与宽度成比例的高度。
不幸的是,Chrome 和 IE 中存在一个错误,因此如果您使用 Javascript 修改父元素,例如在我的演示中,尺寸将不会更新。有一个 hack 可以用来解决这个问题,如我的演示所示。
您可以使用视图高度 (vh) 作为 width 的单位。
这是您要求的 20 像素边距的示例。
.parent {
margin : 20px;
}
.child {
width: calc(100vh - 40px);
height : calc(100vh - 40px);
margin:0 auto;
background: red;
box-sizing:border-box;
padding:10px;
}
基于@kunkalabs 的回答(这真的很聪明),我想出了一个解决方案,可以让您保留继承的字体大小。
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
的父级字体大小......否则只需调整字体大小直到它大约在你想要的位置(并在此过程中激怒你的设计师) .
您可以通过使用 SVG 来实现。
视情况而定,但在某些情况下它确实很有用。例如 - 您可以设置
background-image
而不设置固定高度或使用它来嵌入 <iframe>
与比率 16:9
和 position:absolute
.
为
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>
在较新的浏览器上,我们可以使用固定高度的
aspect-ratio
,宽度将相应地计算。
img {
aspect-ratio: 1.2;
height: 250px;
max-width: 500px;
}
但是浏览器对
aspect-ratio
的支持还不够好。我喜欢@Jakub Muda 提出的SVG
解决方案,除了它需要修改标记这一事实。我通过使用 SVG
属性将 content
移动到 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×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×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×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>
使父 DIV 表现得像一个表格单元格,并垂直对齐子元素。无需做任何填充技巧。
HTML
<div class="parent">
<img src="foo.jpg" />
</div>
CSS
.parent { width:300px; height:300px; display:table-cell; vertical-align:middle; }