Answers:
使用新的CSS视口单位 vw
和vh
(视口宽度/视口高度)
在垂直和水平方向上调整大小,您将看到该元素将始终填充最大视口大小,而不会破坏比例和没有滚动条!
div
{
width: 100vw;
height: 56.25vw; /* height:width ratio = 9/16 = .5625 */
background: pink;
max-height: 100vh;
max-width: 177.78vh; /* 16/9 = 1.778 */
margin: auto;
position: absolute;
top:0;bottom:0; /* vertical center */
left:0;right:0; /* horizontal center */
}
如果要使用最大90%的视口宽度和高度,请执行以下操作:FIDDLE
另外,浏览器支持也相当不错:IE9 +,FF,Chrome,Safari- caniuse
只需Danield
在LESS mixin中重新编写答案即可,以供进一步使用:
// Mixin for ratio dimensions
.viewportRatio(@x, @y) {
width: 100vw;
height: @y * 100vw / @x;
max-width: @x / @y * 100vh;
max-height: 100vh;
}
div {
// Force a ratio of 5:1 for all <div>
.viewportRatio(5, 1);
background-color: blue;
margin: 0;
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
}
将CSS媒体查询 @media
与CSS视口单位 一起使用,vw
并vh
适应视口的宽高比。这具有更新其他属性(例如)的好处font-size
。
该小提琴演示了div的固定长宽比,以及与它的比例完全匹配的文本。
初始尺寸基于全宽:
div {
width: 100vw;
height: calc(100vw * 9 / 16);
font-size: 10vw;
/* align center */
margin: auto;
position: absolute;
top: 0px; right: 0px; bottom: 0px; left: 0px;
/* visual indicators */
background:
url(data:image/gif;base64,R0lGODlhAgAUAIABAB1ziv///yH5BAEAAAEALAAAAAACABQAAAIHhI+pa+EPCwA7) repeat-y center top,
url(data:image/gif;base64,R0lGODlhFAACAIABAIodZP///yH5BAEAAAEALAAAAAAUAAIAAAIIhI8Zu+nIVgEAOw==) repeat-x left center,
silver;
}
然后,当视口宽于所需的宽高比时,切换到高度作为基本度量:
/* 100 * 16/9 = 177.778 */
@media (min-width: 177.778vh) {
div {
height: 100vh;
width: calc(100vh * 16 / 9);
font-size: calc(10vh * 16 / 9);
}
}
这与@Danield 的max-width
and max-height
方法非常相似,只是更加灵活。
我最初的问题是如何同时拥有一个固定方面的元素,但又如何将该元素准确地放入指定的容器中,这使它显得有些笨拙。如果您只希望单个元素保持其长宽比,则容易得多。
我遇到的最好的方法是将元素的高度设置为零,然后使用百分比填充底部将其设置为高度。填充百分比始终与元素的宽度成比例,而不与元素的高度成比例,即使元素的顶部或底部填充也是如此。
因此,您可以利用该元素为元素提供一定百分比的宽度以使其位于容器中,然后填充以指定纵横比,或者换句话说,指定其宽度和高度之间的关系。
.object {
width: 80%; /* whatever width here, can be fixed no of pixels etc. */
height: 0px;
padding-bottom: 56.25%;
}
.object .content {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
box-sizing: border-box;
-moz-box-sizing: border-box;
padding: 40px;
}
因此,在上面的示例中,对象占容器宽度的80%,然后其高度为该值的56.25%。如果宽度为160像素,则底部填充,因此高度将为90像素-16:9宽高比。
这里的一个小问题对您来说可能不是问题,那就是新对象内部没有自然空间。例如,如果您需要添加一些文本,并且该文本需要采用自己的填充值,则需要在其中添加一个容器并在其中指定属性。
此外,在某些较旧的浏览器中也不支持vw和vh单位,因此您可能无法接受我的问题的答案,并且您可能必须使用更多lo-fi。
据了解,您要求提供CSS
特定的解决方案。要保持长宽比,您需要将高度除以所需的长宽比。16:9 = 1.777777777778。
为了获得正确的容器高度,您需要将当前宽度除以1.777777777778。由于您无法使用来检查width
容器的正好CSS
或除以is CSS
,因此JavaScript
(据我所知)这是不可能的。
我编写了一个工作脚本,该脚本将保持所需的宽高比。
的HTML
<div id="aspectRatio"></div>
的CSS
body { width: 100%; height: 100%; padding: 0; margin: 0; }
#aspectRatio { background: #ff6a00; }
的JavaScript
window.onload = function () {
//Let's create a function that will scale an element with the desired ratio
//Specify the element id, desired width, and height
function keepAspectRatio(id, width, height) {
var aspectRatioDiv = document.getElementById(id);
aspectRatioDiv.style.width = window.innerWidth;
aspectRatioDiv.style.height = (window.innerWidth / (width / height)) + "px";
}
//run the function when the window loads
keepAspectRatio("aspectRatio", 16, 9);
//run the function every time the window is resized
window.onresize = function (event) {
keepAspectRatio("aspectRatio", 16, 9);
}
}
function
如果您想通过使用来显示其他具有不同比率的内容,可以再次使用
keepAspectRatio(id, width, height);
window.onresize
浏览器更改大小后立即触发。
现在指定了一个新的CSS属性来解决此问题:object-fit
。
http://docs.webplatform.org/wiki/css/properties/object-fit
仍然缺少浏览器支持(http://caniuse.com/#feat=object-fit)-当前,除了Microsoft以外,大多数浏览器在某种程度上都可以工作-但是给定的时间正是这个问题所需要的。
Danield的回答很好,但是只有在div填充整个视口时才可以使用它,或者calc
如果知道视口中其他内容的宽度和高度,可以使用一点点的来使用。
但是,通过将margin-bottom
技巧与上述答案中的方法相结合,可以将问题减少到只需要知道其他内容的高度即可。如果您具有固定的高度标题,但是例如侧边栏的宽度未知,这将很有用。
body {
margin: 0;
margin-top: 100px; /* simulating a header */
}
main {
margin: 0 auto;
max-width: calc(200vh - 200px);
}
section {
padding-bottom: 50%;
position: relative;
}
div {
position:absolute;
background-color: red;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
<main>
<section>
<div></div>
</section>
</main>
这是在使用scss的jsfiddle中,这使得值的来源更加明显。
根据Daniel的回答,我#{}
为Bootstrap模态对话框内的youtube视频的iframe 编写了带插值()的SASS mixin :
@mixin responsive-modal-wiframe($height: 9, $width: 16.5,
$max-w-allowed: 90, $max-h-allowed: 60) {
$sides-adjustment: 1.7;
iframe {
width: #{$width / $height * ($max-h-allowed - $sides-adjustment)}vh;
height: #{$height / $width * $max-w-allowed}vw;
max-width: #{$max-w-allowed - $sides-adjustment}vw;
max-height: #{$max-h-allowed}vh;
}
@media only screen and (max-height: 480px) {
margin-top: 5px;
.modal-header {
padding: 5px;
.modal-title {font-size: 16px}
}
.modal-footer {display: none}
}
}
用法:
.modal-dialog {
width: 95vw; // the modal should occupy most of the screen's available space
text-align: center; // this will center the titles and the iframe
@include responsive-modal-wiframe();
}
HTML:
<div class="modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Video</h4>
</div>
<div class="modal-body">
<iframe src="https://www.youtube-nocookie.com/embed/<?= $video_id ?>?rel=0" frameborder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
</div>
<div class="modal-footer">
<button class="btn btn-danger waves-effect waves-light"
data-dismiss="modal" type="button">Close</button>
</div>
</div>
</div>
</div>
当宽度或高度与视频不成比例时,这将始终显示视频,而没有 youtube添加到iframe的黑色部分。笔记:
$sides-adjustment
稍作调整,以补偿侧面出现的黑色部分中的一小部分;.modal-footer
;.modal-dialog
;.modal-header
。经过大量测试,现在这对我来说是完美无缺的。
这里是基于@Danield解决方案的解决方案,即使在div中也可以使用。
在该示例中,我使用的是Angular,但是它可以快速迁移到Vanilla JS或其他框架。
主要思想是将@Danield解决方案移到空的iframe中,并在iframe窗口大小更改后复制尺寸。
该iframe必须与其父元素相适应。
https://stackblitz.com/edit/angular-aspect-ratio-by-iframe?file=src%2Findex.html
这里有一些截图:
position: relative (default) height: 0 padding-<top/bottom>: H/W*100%