CSS网格行最大高度1fr,滚动内容

时间:2017-07-30 00:08:15

标签: html css css3 css-grid

我有一个'日历'使用以下css-grid样式进行布局:

.calendar {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  grid-template-rows: 1.5em 1.5em repeat(6, 1fr);
  width: 100%;
  height: 100%;
}

(Codepen https://codepen.io/joelhoward0/pen/vJLmWK

前两行是'控件'标题和星期几天的标题,然后是当月每天的div:

<div class="day">
  <div class="header">26</div>
  <div class="content"></div>
</div>

每天都有一个.header.content div。我希望.header div占据行高度的1/5,内容占用4/5并在内容溢出时滚动。

然而,我尝试的任何样式组合只会导致.content增长,缩小其他网格行以进行补偿。我假设这是由于在容器grid-template-rows上使用了1fr

是否可以在.content div上实现网格行高度的4/5的最大高度,这是可用垂直空间的1/6?

注意: overflow-y: auto;上的.day设置达到我想要的效果,但标题包含在滚动区域中。overflow-y: auto;设置.content似乎没有做任何事情。)

3 个答案:

答案 0 :(得分:5)

网格中的每一行(标题除外)都设置为1fr高度。这意味着每行将占用容器中相等比例的可用空间。

请注意,fr大小调整实际上并未定义长度 - widthheight。使用fr,您只需分配可用空间。

但要使overflow属性起作用,必须定义实际高度:

  

要使overflow生效,块级容器的设置高度(heightmax-height)或white-space必须设置为{{ 1}}。

     

来源:https://developer.mozilla.org/en-US/docs/Web/CSS/overflow

因此,考虑使用实际高度而不是空间分布。这是一个例子:

nowrap
html,
body {
  height: 100%;
}

body {
  position: relative;
  margin: 0;
}

.calendar {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  grid-template-rows: 1.5em 1.5em repeat(6, 175px);  /* adjusment */
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  border: solid grey;
  border-width: 1px 0 0 1px;
  position: relative;
}

.dayHeader {
  border: solid grey;
  border-width: 0 1px 1px 0;
}

.day {
  height: 175px;  /* new */
  border: solid grey;
  border-width: 0 1px 1px 0;
}

.header { /* new */
  height: 20%;
  background-color: yellow;
}

.content {
  height: 80%; /* new */
  overflow-y: auto;
  background-color: aqua;
}

.controls {
  grid-column-start: 1;
  grid-column-end: 8;
  border: solid grey;
  border-width: 0 1px 1px 0;
}

revised demo

答案 1 :(得分:1)

如果您将标头设置为position: fixed,请设置calc(100%/7)并为其指定不透明的background。将.day设置为overflow-y:auto,并为.content margin-top提供一个似乎与将日历流体保持在浏览器高度相同的效果。

如果标题是带边框的日期框的整个宽度很重要,您可以将当前边框属性添加到仅右侧并添加box-sizing: border-box

.header{
  position:fixed;
  background: white;
  width: calc(100%/7);
  border: solid grey;
  border-width: 0 1px 0 0;
  box-sizing: border-box;
}

.day {
  border: solid grey;
  border-width: 0 1px 1px 0;
  overflow-y: auto;
}

.content {
  margin-top: 20px;
}

Demo

答案 2 :(得分:1)

尽管@MichaelB的回复在技术上是正确的,但我发现您可以做到这一点,而无需手动指定高度。而且做到这一点也很简单。

除了将overflow:auto添加到要在其上滚动条的网格项目外,还需要向该网格项目的父级添加overflow:auto。 / p>

https://codepen.io/kumarharsh/pen/jejGMm?editors=1100

html,
body {
  height: 100%;
}

body {
  position: relative;
  margin: 0;
}

.calendar {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  grid-template-rows: 1.5em 1.5em repeat(6, 1fr);
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  border: solid grey;
  border-width: 1px 0 0 1px;
  position: relative;
}

.dayHeader {
  border: solid grey;
  border-width: 0 1px 1px 0;
}

.day {
  border: solid grey;
  border-width: 0 1px 1px 0;
  overflow: auto; /* added overflow here! */
}

.content {
  overflow-y: auto;
}

.controls {
  grid-column-start: 1;
  grid-column-end: 8;
  border: solid grey;
  border-width: 0 1px 1px 0;
}
<div class="calendar">
  <div class="controls">July 2017</div>
  <div class="dayHeader">Sunday</div>
  <div class="dayHeader">Monday</div>
  <div class="dayHeader">Tuesday</div>
  <div class="dayHeader">Wednesday</div>
  <div class="dayHeader">Thursday</div>
  <div class="dayHeader">Friday</div>
  <div class="dayHeader">Saturday</div>
  <div class="day">
    <div class="header">25</div>
    <div class="content">
      this is a lot of content that I want to have scroll instead of just stretching the grid row and forcing the other rows to be smaller to compensate for this one's increased size due
    </div>
  </div>
  <div class="day">
    <div class="header">26</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">27</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">28</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">29</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">30</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">1</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">2</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">3</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">4</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">5</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">6</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">7</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">8</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">9</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">10</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">11</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">12</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">13</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">14</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">15</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">16</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">17</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">18</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">19</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">20</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">21</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">22</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">23</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">24</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">25</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">26</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">27</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">28</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">29</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">30</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">31</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">1</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">2</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">3</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">4</div>
    <div class="content"></div>
  </div>
  <div class="day">
    <div class="header">5</div>
    <div class="content"></div>
  </div>
</div>

最棒的是,它适用于所有浏览器(在Firefox,Chrome和Edge中经过测试),因此它可能不是黑客,而是预期的行为。

为什么会这样?

在规格中我还没有找到明确的答案,但是我会继续寻找并在有具体内容时在此处进行更新。