css实现宽度与高度成比例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了css实现宽度与高度成比例相关的知识,希望对你有一定的参考价值。
参考技术A 当你使用绝对的值设置了一个框的大小(如,固定像素的宽/高),允许的大小可能不适合放置内容,这种情况下内容会从盒子溢流。我们使用 overflow 属性来控制这种情况的发生。它有一些可能的值,但是最常用的是:框模型的 width 和 height (不是content设置的width,height),框模型 content 不足以放下内部元素时可以延伸到框的外部,即使 content 设置的height为0,然而默认溢出是当内容过多时溢流的内容被显示在框外边。
示例1:先看溢出框的情况
结果1:
发现img溢出到父容器之外
示例2:溢出框被删减的情况
发现设置完overflow之后img超出父容器的部分被删减了。
为什么height设置为0?
因为容器如果去掉这一行的话,img下面会出现一个img大小的空白区域,这个区域是设置 padding-bottom 导致的,所以设置height=0是为了让父元素没有高度。
CSS:使div宽度与高度成正比
【中文标题】CSS:使div宽度与高度成正比【英文标题】:CSS: make div width proportional to height 【发布时间】:2014-05-05 13:32:29 【问题描述】:这有点难以解释,但是:我想要一个响应高度的 div (height: 100%
),它会按比例缩放 width 与 height(不是反之亦然)。
我知道this method 使用padding-top
hack 使高度与宽度成正比,但我需要它以相反的方式工作。话虽如此,我并不非常热衷于该方法中内容的绝对定位元素的额外要求,所以我意识到我很可能在这里要求月亮在棍子上。
为了帮助形象化,这里有一张图片:
...这里是jsFiddle,说明几乎相同的东西。
值得注意的是,我已经在使用:before
和:after
伪元素来垂直对齐要按比例缩放的框的内容。
我真的,真的很喜欢不必恢复到 jQuery,只是因为对调整大小处理程序和通常更多的调试有内在的要求......但如果这是我唯一的选择,那么 fiat。
【问题讨论】:
恐怕你必须使用 javascript... 除了使用padding
或 margin
jsfiddle.net/V2dyZ/3 的技巧之外别无他法。不知何故,我们必须找到宽度和高度之间的某种关系,以便我们可以相应地设置高度,但是通常width
仅相对于父级的width
,height
仅相对于父级的@987654335 @,margin
和 padding
只有 1 个特别之处,即它们的 百分比(相对值)值基于父级的 width
,无论您设置 padding-top
,@ 987654340@ or margin-top
, margin-bottom
,所以我们有一个解决方案(只有?)
related
【参考方案1】:
哦,您可能可以使用“填充顶部”技巧。
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就可以了.
是的,我知道那个;不幸的是,这种设计的规范是宽度必须与高度成比例地设置,而不是相反。看起来我很可能会为此转向 jQuery。【参考方案2】:
一段时间以来,我一直在想有一个纯 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
【讨论】:
在这里使用font-size
看起来真的很丑陋并且可能不方便。
超迟收!我完全忘记了我问过这个问题,然后我在谷歌上搜索完全相同的东西,我的问题是第一个。事实证明,这正是我所追求的(对内联比例进行了一点调整——根据图像大小比计算)。感谢您的提示!
我们不能有固定高度的情况怎么办... :(
您需要知道高度。它不需要以 px 为单位设置,但是您可以使用任何大小单位(rem
、vh
、vw
等)。如果高度根据视口大小而变化,您还可以通过断点更改 height
值。【参考方案3】:
字体解决方案要求知道高度。我找到了一种解决方案,可以在宽度和高度未知的父 div 内使元素成比例。 Here is a demo.
我使用的技巧是将图像用作分隔符。代码解释:
<div class="heightLimit">
<img 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 修改父元素,例如在我的演示中,尺寸将不会更新。如我的演示所示,有一个 hack 可以用来解决这个问题。
【讨论】:
data:image/gif;base64,R0lGODlhAQABAIAAAAAAA P///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
的意义是什么?可以改用常规网址吗?具体来说,我不明白所有看起来毫无意义的随机字符的用途。【参考方案4】:
您可以使用视图高度 (vh) 作为 宽度 的单位。
这是您要求的 20 像素边距的示例。
.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/
【讨论】:
【参考方案5】:根据@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
的父级字体大小……否则只需调整字体大小,直到它达到您想要的位置(并在此过程中激怒您的设计师) .
【讨论】:
有没有办法让这个比例响应视口宽度? 好问题,肯定有(尽管您失去了继承的字体宽度),只需更改“#rect font-width 以使用视口相对 CSS 单位作为字体大小。所以像 @ 987654325@ 表示在上述情况下,您的矩形将始终是视口宽度和高度的 10%。如果您希望内容的字体缩放到(这不是一个坏主意),请将其保留为百分比,否则您将拥有设置像素值。 您的意思是“更改#rect
的字体-大小”,否则,谢谢。【参考方案6】:
您可以通过使用 SVG 来实现。
视情况而定,但在某些情况下它确实很有用。举个例子——你可以设置background-image
而不设置固定高度,或者使用它来嵌入<iframe>
,比例为16:9
和position:absolute
。
对于3:2
比率设置viewBox="0 0 3 2"
等等。
例子:
divwidth:35%;background-color:red
svgwidth:100%;display:block;visibility:hidden
<div>
<svg viewBox="0 0 3 2"></svg>
</div>
【讨论】:
【参考方案7】:在较新的浏览器上,我们可以使用固定高度的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-ratio1: 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" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" 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" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" 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" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" 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>
【讨论】:
【参考方案8】:使父 DIV 表现得像一个表格单元格并垂直对齐子元素。不需要做任何填充技巧。
HTML
<div class="parent">
<img src="foo.jpg" />
</div>
CSS
.parent width:300px; height:300px; display:table-cell; vertical-align:middle;
【讨论】:
垂直居中的内容不是问题 - 它使包含元素的高度与其宽度成比例地响应。在您的示例中,您对两者都使用硬编码值。以上是关于css实现宽度与高度成比例的主要内容,如果未能解决你的问题,请参考以下文章