如何自动拉伸并在父容器中约束HTML子元素? [英] How to automatically stretch and yet constraint HTML child element within parent container?

查看:293
本文介绍了如何自动拉伸并在父容器中约束HTML子元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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





...然后我们使用CSS flexbox并将 flex-grow 属性应用到body元素,我们得到:





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



但是,假设我们想要一个固定的高度为父容器元素,子元素(即头,



假设页眉和页脚元素内容是固定的,但正文内容是动态的(服务器端或客户端,没有关系),并且当内容太大时,我们希望body元素有垂直滚动条,例如:





然而,我找不到一种方法来实现纯粹的CSS行为没有使用JavaScript),并且没有为所有子元素指定固定高度(不期望的)。



只需使用 flex-grow 属性在父级上具有固定高度,导致此(当主体内容变得过大时):





在纯CSS中有办法吗?



可能值得扩展flexbox标准来封装这种行为?



编辑1



所以我的用例类似于我发布的,但不同的足以隐藏的问题,因此提出了一些眉毛,为什么我甚至有问题在第一位。



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



  html,body {margin:0;} body {display:flex; / * IE 11/10 min-height bug fix  - 或者一个额外的包装器在标记* /}。 flex-direction:column;高度:100vh; width:100%;}。body {flex:1;}。content {overflow:auto; } / *下面CSS只是为额外的样式* /。wrapper {height:calc(100vh  -  44px); / * 2 * 2px border + 2 * 10px margin * / width:calc(100% -  44px); / * + 2 * 10px padding = 44px * / border:2px black 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>标题< br> < / div> < div class =body> < h1>你好,世界! < / h1> < div class =content>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br> < / div> < / div> < div class =footer> Footer< br> < / div>< / div>  



在层次结构中有另一个级别,我有溢出属性一级太深。



溢出在我有它,但从你的答案/例子,即使从我的用例,将它移动一个级别,使其工作(反直觉,在我看来)。



我可以一半理解为什么它的工作,但我会认为滚动条将跨越整个body元素,而不只是内容部分。



对于无意的误导,抱歉。



感谢大家。



编辑2



我会奖励第一个人修改他们的答案(或创建一个)

这个示例使用 flexbox



完全动态 .header .footer 和一个 .body 将在需要时滚动, code> .wrapper



注意,关于滚动,你给元素你想滚动



  html,body {margin:0;} body {display:flex; / * IE 11/10 min-height bug fix  - 或者一个额外的包装器在标记* /}。 flex-direction:column;高度:100vh; width:100%;}。body {flex:1; overflow:auto;} / *下面CSS只是为额外的样式* /。wrapper {height:calc(100vh  -  44px); / * 2 * 2px border + 2 * 10px margin * / width:calc(100% -  44px); / * + 2 * 10px padding = 44px * / border:2px black 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>标题< br> < / div> < div class =body> < h1>你好,世界! < / h1> < div class =content>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br> < / div> < / div> < div class =footer> Footer< br> < / div>< / div>  






当你说整个 body 元素时,如果你的意思是实际的html body .body 类,然后在 .wrapper min-height $ c>并从 .body 中删除​​溢出。



可以将溢出设置为html <$默认情况下不需要滚动。



  html,body {margin:0;} body {display:flex; / * IE 11/10 min-height bug fix  - 或者一个额外的包装器在标记* /}。 flex-direction:column; min-height:100vh; width:100%;}。body {flex:1;} / *下面CSS只是为额外的样式* /。wrapper {min-height:calc(100vh  -  44px); / * 2 * 2px border + 2 * 10px margin * / width:calc(100% -  44px); / * + 2 * 10px padding = 44px * / border:2px black 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;}  

  wrapper> < div class =header>标题< br> < / div> < div class =body> < h1>你好,世界! < / h1> < div class =content>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br>内容< br> < / div> < / div> < div class =footer> Footer< br> < / div>< / div>  


If we start with this setup of HTML elements:

...and then we make use of CSS flexbox and apply the flex-grow property to the "body" element, we get this:

Which is fantastic that it's behaviour that can be done purely in CSS without the need for any JavaScript.

However, say we want to have a fixed height for the parent container element and that the child elements (i.e. header, body and footer), should not overflow the parent.

Say the header and footer element content are fixed, but the body content is dynamic (server-side or client-side, it doesn't matter) and that we want the body element to have vertical scrollbars when the content gets too big, like so:

However, I can't find a way to achieve that behaviour purely in CSS (i.e. without the use of JavaScript) and without specifying fixed heights for all the child elements (undesirable).

Simply using the flex-grow property with a fixed height on the parent, results in this (when the body content gets too big):

Is there a way to do it in pure CSS?

If not, do we think it might be worth extending the flexbox standard to encapsulate this kind of behaviour?

Edit 1

So my use-case is similar to what I posted, but different enough to have hidden the problem and hence raised a few eyebrows as to why I'm even having problems in the first place.

Expanding on LGSon's answer, this is my use-case:

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>

So I actually had another level in the hierarchy and I had the overflow property one level too deep.

To me it seems logical to have the overflow where I had it, but building from your answers/examples, even from my use-case, moving it up a level, makes it work (counter-intuitively, in my opinion).

I can half understand why it works, but I would have thought the scroll bar would span the whole body element and not just the content part.

Sorry about the unintentional misleading.

Thanks everyone.

Edit 2

I'll reward the first person to alter their answer (or create a new one), that incorporates my clarification (in the first edit), with the correct answer.

解决方案

This sample using flexbox does what you asked, with no fixed height on the children.

Fully dynamic .header and .footer, and a .body that will scroll when needed, so it all stays within its parent, the .wrapper.

Note, regarding the scroll, you give the element you want to have the scroll an overflow, not the element that might cause the overflow.

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>


When you say the whole body element, if you instead mean the actual html body, not the element with the .body class, then use a min-height on the .wrapper and remove the overflow from the .body.

You could set the overflow to the html body element, though it's not needed as it scrolls by default

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

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

这篇关于如何自动拉伸并在父容器中约束HTML子元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆