问题描述
我有一个网站放在一起,具有大约 16:9
景观的固定长宽比,就像一个视频。
我想让它居中和扩展,以填补可用的宽度和可用的高度,但不要在任一侧增长更大。
例如:
-
高而薄的页面将使内容在保持比例高度的同时伸展全宽。
-
一个宽阔的页面将使内容拉伸整个高度,具有比例宽度。
有两种方法我一直在看:
-
使用具有正确宽高比的图像扩展容器
div
,但是我无法让它在主流浏览器上的行为方式相同。 -
设置一个比例的底部填充,但它只对宽度起作用,忽略高度。它的宽度越来越大,显示垂直滚动条。
我知道你可以很容易地使用 JS,但我想要一个纯 CSS 的解决方案。
有任何想法吗?
最佳解决方案
使用新的 CSS viewport units vw
和 vh
(视口宽度/视口高度)
调整垂直和水平的大小,您会看到元素将始终填充最大视口大小,而不会破坏比例,不使用滚动条!
(PURE)CSS
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 */
}
* {
margin: 0;
padding: 0;
}
div {
width: 100vw;
height: 56.25vw;
/* 100/56.25 = 1.778 */
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 */
}
<div></div>
如果你想使用最大的 90%宽度和高度的视口:FIDDLE
* {
margin: 0;
padding: 0;
}
div {
width: 90vw;
/* 90% of viewport vidth */
height: 50.625vw;
/* ratio = 9/16 * 90 = 50.625 */
background: pink;
max-height: 90vh;
max-width: 160vh;
/* 16/9 * 90 = 160 */
margin: auto;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<div></div>
此外,浏览器支持也不错: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;
}
第三种解决方案
我的原始问题是如何既具有固定方面的元素,也可以恰好适应指定容器内的元素,这使得它有点小巧。如果你只想要一个单独的元素来保持它的宽高比,这很容易。
我遇到的最好的方法是提供零高度,然后使用百分比 padding-bottom 来给它高度。百分比填充总是与元素的宽度成比例,而不是其高度,即使其顶部或底部填充。
所以利用它可以给一个元素一个百分比的宽度,以便坐在一个容器中,然后填充以指定宽高比,或以其他方式指定其宽度和高度之间的关系。
.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%。如果宽度为 160px,则底部填充,因此高度将为 90 像素 – 16:9 方面。
这里的轻微问题可能不是您的一个问题,是您的新对象内没有自然空间。如果您需要将一些文本放在一起,并且文本需要使用自己的填充值,则需要在其中添加一个容器并指定其中的属性。
在某些旧的浏览器上也不支持 vw 和 vh 单元,所以对我的问题的接受答案可能不可能,您可能不得不使用更多的 lo-fi 。
第四种方案
使用 CSS media query @media
与 CSS viewport units 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);
}
}
这是非常相似的 max-width
和 max-height
approach 由 @Danield,更灵活。
第五种方案
我明白你要求你想要一个 CSS
具体的解决方案。为了保持纵横比,您需要将高度除以所需的纵横比。 16:9 = 1.777777777778 。
要获取容器的正确高度,您需要将当前宽度除以 1.777777777778 。由于您不能使用 CSS
检查容器的 width
,或者除以百分比是 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);
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。