保持div的宽高比,但在CSS中填充屏幕的宽度和高度?

我有一个网站放在一起,有一个固定的纵横比约为16:9景观,就像一个video。

我想让它居中并展开以填充可用的宽度和可用的高度,但不要在两侧都增大。

例如:

  1. 高而薄的页面将使内容伸展整个宽度,同时保持成比例的高度。
  2. 一个简短的宽页面可以将内容拉伸到整个高度,并具有相应的宽度。

有两种方法我一直在看:

  1. 使用具有正确宽高比的图像来展开容器div ,但是我无法让它在主stream浏览器中performance得相同。
  2. 设置一个比例底部填充,但只能相对于宽度而忽略高度。 它只是随着宽度不断变大,并显示垂直滚动条。

我知道你可以很容易地做到这一点,但我想要一个纯粹的CSS解决scheme。

有任何想法吗?

使用新的CSS视口单位 vwvh (视口宽度/视口高度)

小提琴

垂直和水平resize,你会发现元素将永远填充最大的视口大小,而不会中断比例和没有滚动条!

(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> 

只需在LESS mixin中重新组织Danield的答案,以便进一步使用:

 // 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; } 

我最初的问题是如何都有一个固定的方面的元素,但要适应在一个指定的容器内,这使得它有点烦琐。 如果你只是想要一个单独的元素来保持它的宽高比,那就容易多了。

我遇到的最好的方法是给元素零高度,然后使用百分比填充底部给它的高度。 百分比填充总是与元素的宽度成正比,而不是其高度,即使其顶部或底部填充。

W3C填充属性

所以利用这一点,你可以给一个元素的一个百分比的宽度坐在一个容器内,然后用填充来指定宽高比,或者换言之,宽度和高度之间的关系。

 .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,那么底部填充,因此高度将是90px – 16:9的方面。

这个小问题对你来说可能不是问题,因为你的新对象内部没有自然空间。 例如,如果您需要放置一些文本,并且文本需要自己的填充值,则需要在其中添加容器并在其中指定属性。

此外,一些旧的浏览器不支持vw和vh单元,因此我的问题的接受答案可能不适用于您,您可能需要使用更低保真的东西。

将CSS媒体查询 @media与CSS视口单位 vwvh一起使用,以适应视口的高宽比。 这有利于更新其他属性,如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-widthmax-height 方法非常相似,只是更加灵活。

我明白你问你想要一个CSS特定的解决scheme。 要保持纵横比,您需要将高度除以所需的纵横比。 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); 

现在有一个新的CSS属性指定来解决这个问题: object-fit

http://docs.webplatform.org/wiki/css/properties/object-fit

浏览器的支持还有些不足( http://caniuse.com/#feat=object-fit ) – 目前在除了微软以外的大多数浏览器上都有一定的作用 – 但是给定的时间正是这个问题所要求的。

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>