简体   繁体   English

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

[英]How to automatically stretch and yet constraint HTML child element within parent container?

If we start with this setup of HTML elements: 如果我们从此HTML元素设置开始:

在此处输入图片说明

...and then we make use of CSS flexbox and apply the flex-grow property to the "body" element, we get this: ...然后,我们利用CSS flexbox,将flex-grow属性应用于“ body”元素,我们得到:

在此处输入图片说明

Which is fantastic that it's behaviour that can be done purely in CSS without the need for any JavaScript. 它的行为可以完全在CSS中完成而无需任何JavaScript,这真是太棒了。

However, say we want to have a fixed height for the parent container element and that the child elements (ie 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: 假设header和footer元素的内容是固定的,但是主体内容是动态的(服务器端或客户端,这都没有关系),并且我们希望当内容太大时body元素具有垂直滚动条,例如所以:

在此处输入图片说明

However, I can't find a way to achieve that behaviour purely in CSS (ie without the use of JavaScript) and without specifying fixed heights for all the child elements (undesirable). 但是,我找不到纯粹在CSS中实现该行为的方法(即,不使用JavaScript)并且没有为所有子元素指定固定的高度(不希望的)。

Simply using the flex-grow property with a fixed height on the parent, results in this (when the body content gets too big): 只需在父级上使用固定高度的flex-grow属性,就会导致以下结果(当主体内容变得太大时):

在此处输入图片说明

Is there a way to do it in pure CSS? 有没有办法在纯CSS中做到这一点?

If not, do we think it might be worth extending the flexbox standard to encapsulate this kind of behaviour? 如果没有,我们认为扩展flexbox标准来封装这种行为是否值得?

Edit 1 编辑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: 扩展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> 

So I actually had another level in the hierarchy and I had the overflow property one level too deep. 因此,我实际上在层次结构中有另一个级别,并且我的overflow属性太深了一个级别。

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). 对我来说,在我那里有overflow似乎是合乎逻辑的,但是根据您的答案/示例(甚至从我的用例)进行构建,将其上移至一个级别,就可以使它起作用(在我看来,这是违反直觉的)。

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 编辑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. 使用flexbox此示例执行您所要求的操作,而子级没有固定的高度。

Fully dynamic .header and .footer , and a .body that will scroll when needed, so it all stays within its parent, the .wrapper . 完全动态的.header.footer ,以及.body会在需要时滚动,因此它们都位于其父级.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 . 当你说全身元素,如果你的意思,而不是实际的HTML body ,不与元素.body类,然后用min-height.wrapper并从取出溢.body

You could set the overflow to the html body element, though it's not needed as it scrolls by default 您可以将溢出设置为html 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; } 
 <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> 

Here's a version with minimal CSS, which allows for your requirements, I think. 我认为这是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> 

Flexbox does just that.. Could it be you forgot to remove the default margin on the body? 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM