CSS Calc视口单位解决方案?

70

根据我在其他 答案中看到的,CSS视口单位目前无法在calc()语句中使用。我想实现的是以下语句:

height: calc(100vh - 75vw)

即使在calc()语句中无法使用视口单位,我是否可以通过纯CSS的解决方法来实现这一目标?还是只用CSS和HTML? 我知道我可以使用JavaScript动态地完成它,但我更喜欢CSS。


你能不能不用 JavaScript? - ggdx
1
你能提供更多关于你所尝试做的事情的上下文吗?有时候,问题的狭义定义之外可能会有人找到解决方案。 - Andrew
你的使用场景是什么? - apaul
@golmschenk 你怎么指望在纯CSS中实现这个功能,明明知道这些单位不被支持呢? - Mr. Alien
@golmschenk 使用JS代替CSS反转逻辑并实现它,将会很难维护。 - Mr. Alien
显示剩余4条评论
4个回答

79

在我回答这个问题之前,我想指出Chrome和IE 10+实际上支持使用视窗单位进行calc的计算。

代码演示(在IE10+中可用)

解决方案(适用于其他浏览器):box-sizing

1)首先将高度设置为100vh。

2)使用box-sizing设置为border-box后,添加一个75vw的padding-top。这意味着填充将成为内部高度的一部分。

3)只需使用负边距抵消额外的padding-top即可。

代码演示

div
{
    /*height: calc(100vh - 75vw);*/
    height: 100vh;
    margin-top: -75vw;
    padding-top: 75vw;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    background: pink;
}

3
为什么会有负面评价呢?这个回答看起来很好啊。能不能请给出负面评价的人解释一下原因呢? - golmschenk
与我的唯一区别是兼容性(参见http://caniuse.com/#feat=viewport-units和http://caniuse.com/#feat=css3-boxsizing)。不确定这是否是downvote的原因。 - MatTheCat
@golmschenk MatTheCat的解决方案不好,因为它使用了百分比的margin-top。请采用这个解决方案。 - Mr_Green
Danield,使用CSS translate能否改进这个?我只是好奇地问一下。 - Mr_Green
@Mr_Green,百分比的margin-top有什么问题吗? - MatTheCat

6

6

作为一种解决方法,您可以利用百分比垂直填充和边距是从容器宽度计算出来的这个事实。这是一个相当丑陋的解决方案,我不知道您是否能够使用它,但是好吧,它有效:http://jsfiddle.net/bFWT9/

<!DOCTYPE html>
<html>
    <head>
        <title></title>
    </head>
    <body>
        <div>It works!</div>
    </body>
</html>

html, body, div {
    height: 100%;
}
body {
    margin: 0;
}
div {
    box-sizing: border-box;
    margin-top: -75%;
    padding-top: 75%;
    background: #d35400;
    color: #fff;
}

非常高兴看到唯一的(?)情况,其中边距行为符合规范的要求。 - Oleg

0

使用CSS Grid来完成这个任务非常容易。诀窍是将网格的高度设置为100vw,然后将其中一行分配给75vw,剩余的一行(可选)分配给1fr。这将为您提供一个我认为是您想要的比例锁定调整大小的容器。

示例在此处:https://codesandbox.io/s/21r4z95p7j

甚至可以通过添加另一个“项目”来利用底部的间距空间。

编辑:StackOverflow内置的代码运行程序会产生某些副作用。请转到codesandbox链接,您将看到该比例正在实际操作中。

body {
  margin: 0;
  padding: 0;
  background-color: #334;
  color: #eee;
}

.main {
  min-height: 100vh;
  min-width: 100vw;
  display: grid;
  grid-template-columns: 100%;
  grid-template-rows: 75vw 1fr;
}

.item {
  background-color: #558;
  padding: 2px;
  margin: 1px;
}

.item.dead {
  background-color: transparent;
}
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="src/index.css" />
  </head>

  <body>
    <div id="app">
      <div class="main">
        <div class="item">Item 1</div>
        <!-- <div class="item dead">Item 2 (dead area)</div> -->
      </div>
    </div>
  </body>
</html>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接