如何在父容器中自动拉伸并约束HTML子元素?

时间:2017-01-03 12:49:16

标签: javascript html css flexbox constraints

如果我们从这个HTML元素设置开始:

enter image description here

...然后我们使用CSS flexbox并将flex-grow属性应用于" body"我们得到这个:

enter image description here

这很棒,它的行为可以完全在CSS中完成,而不需要任何JavaScript。

但是,假设我们希望父容器元素具有固定的高度,并且子元素(即标题,正文和页脚)不应溢出父元素。

假设页眉和页脚元素内容是固定的,但是正文内容是动态的(服务器端或客户端,它并不重要)并且我们希望body元素在内容时具有垂直滚动条太大了,就像这样:

enter image description here

但是,我找不到纯粹在CSS中实现该行为的方法(即不使用JavaScript),也没有为所有子元素指定固定高度(不合需要)。

只需在父级上使用固定高度的flex-grow属性,就会产生这种情况(当正文内容变得过大时):

enter image description here

有没有办法在纯CSS中做到这一点?

如果没有,我们是否认为扩展flexbox标准以封装此类行为可能值得?

修改1

所以我的用例与我发布的内容类似,但不同之处就是隐藏了这个问题,因此引起了一些关注,为什么我一开始就遇到问题。

扩展LGSon的答案,这是我的用例:



html, body {
  margin: 0;
}
body {
  display: flex;  /*  IE 11/10 min-height bug fix - or an extra wrapper in the markup  */
}
.wrapper {
  display: flex;
  flex-direction: column;
  height: 100vh;
  width: 100%;
}
.body {
  flex: 1;
}

.content {
  overflow: auto;  
}


/* below CSS is just for the extra styling */
.wrapper {
  height: calc(100vh - 44px);   /*  2*2px border + 2*10px margin  */
  width: calc(100% - 44px);     /*  + 2*10px padding = 44px       */
  border: 2px dashed black;
  margin: 10px;
  padding: 10px;
}
.wrapper > div {
  padding: 10px;
}
.header {
  border: 2px solid blue;
  margin-bottom: 10px;
}
.body {
  border: 2px solid green;
}
.footer {
  border: 2px solid red;
  margin-top: 10px;
}

<div class="wrapper">
  <div class="header">
    Header<br>
  </div>
  <div class="body">
    <h1>
      Hello world!
    </h1>
    <div class="content">
      Content<br> Content<br>
      Content<br> Content<br>
      Content<br> Content<br>
      Content<br> Content<br>
      Content<br> Content<br>
      Content<br> Content<br>
      Content<br> Content<br>
    </div>
  </div>
  <div class="footer">
    Footer<br>
  </div>
</div>
&#13;
&#13;
&#13;

所以我实际上在层次结构中有另一个级别,而overflow属性的级别太深了。

对我来说,拥有overflow似乎是合乎逻辑的,但是从你的答案/例子构建,甚至从我的用例,将其提升到一个水平,使其工作(反直觉,在我看来。)

我可以理解它为什么会起作用,但我认为滚动条会跨越整个身体元素,而不仅仅是内容部分。

对于无意的误导而感到抱歉。

谢谢大家。

修改2

我会奖励第一个改变答案(或创建一个新答案)的人,其中包含我的澄清(在第一次编辑中)和正确答案。

3 个答案:

答案 0 :(得分:2)

使用flexbox的此示例执行您的要求,并且没有固定的高度。

完全动态.header.footer以及.body,会在需要时滚动,因此全部保留在其父级.wrapper内。

注意,关于滚动,您要为要滚动的元素提供溢出,而不是可能导致溢出的元素。

html, body {
  margin: 0;
}
body {
  display: flex;  /*  IE 11/10 min-height bug fix - or an extra wrapper in the markup  */
}
.wrapper {
  display: flex;
  flex-direction: column;
  height: 100vh;
  width: 100%;
}
.body {
  flex: 1;
  overflow: auto;
}


/* below CSS is just for the extra styling */
.wrapper {
  height: calc(100vh - 44px);   /*  2*2px border + 2*10px margin  */
  width: calc(100% - 44px);     /*  + 2*10px padding = 44px       */
  border: 2px dashed black;
  margin: 10px;
  padding: 10px;
}
.wrapper > div {
  padding: 10px;
}
.header {
  border: 2px solid blue;
  margin-bottom: 10px;
}
.body {
  border: 2px solid green;
}
.footer {
  border: 2px solid red;
  margin-top: 10px;
}
<div class="wrapper">
  <div class="header">
    Header<br>
  </div>
  <div class="body">
    <h1>
      Hello world!
    </h1>
    <div class="content">
      Content<br> Content<br>
      Content<br> Content<br>
      Content<br> Content<br>
      Content<br> Content<br>
      Content<br> Content<br>
      Content<br> Content<br>
      Content<br> Content<br>
    </div>
  </div>
  <div class="footer">
    Footer<br>
  </div>
</div>

当您说出整个 body 元素时,如果您的意思是实际的html body,而不是具有.body类的元素,那么请使用{{1}在min-height上移除.wrapper的溢出。

你可以将溢出设置为html .body元素,虽然它不需要,因为它默认滚动

body
html, body {
  margin: 0;
}
body {
  display: flex;  /*  IE 11/10 min-height bug fix - or an extra wrapper in the markup  */
}
.wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  width: 100%;
}
.body {
  flex: 1;
}


/* below CSS is just for the extra styling */
.wrapper {
  min-height: calc(100vh - 44px);   /*  2*2px border + 2*10px margin  */
  width: calc(100% - 44px);     /*  + 2*10px padding = 44px       */
  border: 2px dashed black;
  margin: 10px;
  padding: 10px;
}
.wrapper > div {
  padding: 10px;
}
.header {
  border: 2px solid blue;
  margin-bottom: 10px;
}
.body {
  border: 2px solid green;
}
.footer {
  border: 2px solid red;
  margin-top: 10px;
}

答案 1 :(得分:1)

这是一个包含最少CSS的版本,我认为这符合您的要求。

* { margin: 0; padding: 0; }
html,body {
  max-height: 100%;
  height: 100%;
  }
#header {
  border: 2px solid blue;
  color: blue;
  height: 4em;
  margin-bottom: .5em;
  }
#content {
  border: 2px solid green;
  color: green;
  height: calc(100vh - 10em);
  margin-bottom: .5em;
  overflow-y: scroll;
  }
#footer {
  border: 2px solid red;
  color: red;
  height: 4em;
  }
<body>
  <div id="header">This is the header</div>
  <div id="content"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p>

<p>Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. </p>

<p>Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. </p>

<p>Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. </p>

<p>Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor, cursus quis, aliquet eget, justo. Sed pretium blandit orci. </p>

<p>Ut eu diam at pede suscipit sodales. Aenean lectus elit, fermentum non, convallis id, sagittis at, neque. Nullam mauris orci, aliquet et, iaculis et, viverra vitae, ligula. Nulla ut felis in purus aliquam imperdiet. Maecenas aliquet mollis lectus. Vivamus consectetuer risus et tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. </p>

<p>Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. </p>

<p>Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. </p>

<p>Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. </p>

<p>Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. </p>

</div>
  <div id="footer">This is the footer</div>
</body>

答案 2 :(得分:0)

Flexbox就是这么做的..难道你忘记删除身体上的默认边距了吗?

.wrapper {
  height: 100vh;  
  display: flex;
  flex-direction: column;
}

body {
  margin: 0;  
}

header, footer {
  background: grey;
  flex-basis: 50px;
}

section.grow {
  flex-grow: 1;  
}
<div class="wrapper">
  <header></header>
  <section class="grow"></section>
  <footer></footer>
</div>