如何让flexbox不要使用比容器更多的空间?

时间:2018-05-18 13:44:04

标签: html css css3 flexbox

我正在构建一个模态,并希望它在我的页面中居中并有机地生长,但直到它达到一定的宽度和高度。

我将此模态(.modal)置于flexbox中心,并且工作正常。

在这个模态中,我有另一个flexbox(.modal-content),有一个body(.modal-content__body)和一个footer(.modal-content__footer)元素。我希望身体长大,直到整个.modal到达max-height,此时我希望modal-content__body开始垂直滚动。

HTML层次结构是:

.modal-container // Full screen
  .modal // Centred box with max-width and max-height
    .modal-content // The content of the modal
      .modal-content__body // Potentially growing content
      .modal-content__footer

我无法让.modal-content不要溢出。它只是忽略了父级(.modal)的高度,并且增长为内容提供空间。

如果我删除 .modal-content的附加div,只需将.modal.modal-content 合并,就会按预期工作 ,但因为我使用的是框架(Angular),我无法改变HTML元素的封装方式。

注意:如果我在其max-height: -webkit-fill-available;上设置了.modal-content,但该属性不受支持,因此我无法使用它。

以下是展示此问题的代码:

/* Centers the child */
.modal-container {
  display: flex;
  align-items: center;
  justify-content: center;
}


/* The box in the middle, that should grow
   organically, but be restricted as well */
.modal,
.modal-content--merged-with-modal {
  width: 30rem;
  max-width: calc(50vw - 3rem);
  max-height: calc(100vh - 3rem);
  /* Irrelevant styling */
  background: rgba(255, 255, 255, 0.6);
  border-radius: 3px;
  line-height: 1.5rem;
}

.modal-content {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.modal-content__body {
  flex: 1;
  min-height: 0;
  overflow-y: scroll;
  /* Irrelevant styling */
  padding: 0.75rem;
  background: rgba(0, 0, 255, 0.1);
}

.modal-content__footer {
  /* Irrelevant styling */
  border-top: 1px solid silver;
  background: rgba(0, 255, 0, 0.1);
  padding: 0.75rem;
}


/* Irrelevant styling to present the problem */

html {
  font-family: arial, sans-serif;
  font-size: 16px;
}

main {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
}

section {
  flex: 1;
  background: rgba(255, 0, 0, 0.1);
}
<main>

  <section class="modal-container">
    <div class="modal-content modal-content--merged-with-modal">
      <div class="modal-content__body">
        <code>BODY // </code> srollable<br>
        <br> Container resizes as expected when<br> the container height is reduced.<br>
        <br> In this case, the modal is the same<br> element, as the flexbox handling<br> the body and the footer.<br> .
        <br> .
        <br> .
        <br> .
        <br> .
        <br> .
        <br>
      </div>
      <div class="modal-content__footer">
        <code>FOOTER // </code> Works
      </div>
    </div>
  </section>

  <section class="modal-container">
    <div class="modal">

      <div class="modal-content">
        <div class="modal-content__body">
          <code>BODY // </code>simply grows<br>
          <br> Container overflows when<br> the container height is reduced.<br>
          <br> In this case, the modal <strong>contains</strong><br> the flexbox, that handles the<br> body and the footer.<br> .
          <br> .
          <br> .
          <br> .
          <br> .
          <br> .
          <br>
        </div>
        <div class="modal-content__footer">
          <code>FOOTER // </code> Doesn't work
        </div>
      </div>

    </div>
  </section>

</main>

2 个答案:

答案 0 :(得分:3)

一个简单的解决方法是使.modal成为具有列方向的Flex容器。

/* Centers the child */
.modal-container {
  display: flex;
  align-items: center;
  justify-content: center;
}
  
/* The box in the middle, that should grow
   organically, but be restricted as well */
.modal, .modal-content--merged-with-modal {
  width: 30rem;
  max-width: calc(50vw - 3rem);
  max-height: calc(100vh - 3rem);

  /* Irrelevant styling */
  background: rgba(255, 255, 255, 0.6);
  border-radius: 3px;
  line-height: 1.5rem;
}
  
  
.modal-content {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
  
.modal-content__body {
  flex: 1;
  min-height: 0;
  overflow-y: scroll;

  /* Irrelevant styling */
  padding: 0.75rem;
  background: rgba(0, 0, 255, 0.1);
}
  
  
.modal-content__footer {
  /* Irrelevant styling */
  border-top: 1px solid silver;
  background: rgba(0, 255, 0, 0.1);
  padding: 0.75rem;
}
.modal {
  display:flex;
  flex-direction:column;
}
  
  
/* Irrelevant styling to present the problem */
html {
  font-family: arial, sans-serif;
  font-size: 16px;
}
main {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  
  display: flex;
}
section {
  flex: 1;
  background: rgba(255, 0, 0, 0.1);
}
<main>

  <section class="modal-container">
    <div class="modal-content modal-content--merged-with-modal">
      <div class="modal-content__body">
        <code>BODY // </code> srollable<br>
        <br>
        Container resizes as expected when<br>
        the container height is reduced.<br>
        <br>
        In this case, the modal is the same<br>
        element, as the flexbox handling<br>
        the body and the footer.<br>
        .<br>
        .<br>
        .<br>
        .<br>
        .<br>
        .<br>
      </div>
      <div class="modal-content__footer">
        <code>FOOTER // </code> Works
      </div>
    </div>
  </section>

  <section class="modal-container">
    <div class="modal">

      <div class="modal-content">
        <div class="modal-content__body">
          <code>BODY // </code>simply grows<br>
          <br>
          Container overflows when<br>
          the container height is reduced.<br>
          <br>
          In this case, the modal <strong>contains</strong><br>
          the flexbox, that handles the<br>
          body and the footer.<br>
          .<br>
          .<br>
          .<br>
          .<br>
          .<br>
          .<br>
        </div>
        <div class="modal-content__footer">
          <code>FOOTER // </code> Doesn't work
        </div>
      </div>

    </div>
  </section>

</main>

<强>为什么吗

最初.modal是一个设置为max-height的块元素,默认溢出行为(当出现溢出时)为visible,并且您正面临溢出问题。

通过将.modal设置为弹性容器,您可以引入收缩效果,因为默认情况下,弹性项目将具有flex-shrink:1,因此其高度不会超出高度灵活容器(它会缩小以适应),你将得到需要的结果。

您可以将flex-shrink:0设置为.modal-content,您会看到相同的溢出问题,就好像没有display:flex 一样。

答案 1 :(得分:1)

为了使overflow属性起作用,它需要一个固定的长度限制。

来自MDN

  

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

在您的代码中,nowrap(设置.modal-content__body的位置)没有高度限制:

overflow

父母也没有身高限制:

.modal-content__body {
    flex: 1;
    min-height: 0;
    overflow-y: scroll;
}

.modal-content { display: flex; flex-direction: column; min-height: 0; } - flex-basis: 0flex: 1的相关组件 - 不足以触发溢出条件。但是看看如果切换到.modal-content__body

会发生什么

&#13;
&#13;
flex-basis: 100px
&#13;
/* Centers the child */
.modal-container {
  display: flex;
  align-items: center;
  justify-content: center;
}
  
/* The box in the middle, that should grow
   organically, but be restricted as well */
.modal, .modal-content--merged-with-modal {
  width: 30rem;
  max-width: calc(50vw - 3rem);
  max-height: calc(100vh - 3rem);

  /* Irrelevant styling */
  background: rgba(255, 255, 255, 0.6);
  border-radius: 3px;
  line-height: 1.5rem;
}
  
  
.modal-content {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
  
.modal-content__body {
  flex: 1 0 100px; /* new for demo 1 */
  min-height: 0;
  overflow-y: scroll;

  /* Irrelevant styling */
  padding: 0.75rem;
  background: rgba(0, 0, 255, 0.1);
}
  
  
.modal-content__footer {
  /* Irrelevant styling */
  border-top: 1px solid silver;
  background: rgba(0, 255, 0, 0.1);
  padding: 0.75rem;
}
  
  
  
/* Irrelevant styling to present the problem */
html {
  font-family: arial, sans-serif;
  font-size: 16px;
}
main {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  
  display: flex;
}
section {
  flex: 1;
  background: rgba(255, 0, 0, 0.1);
}
&#13;
&#13;
&#13;

滚动有效。高度限制造成了不同。

这是一个潜在的解决方案:

由于<main> <section class="modal-container"> <div class="modal"> <div class="modal-content"> <div class="modal-content__body"> <code>BODY // </code>simply grows<br> <br> Container overflows when<br> the container height is reduced.<br> <br> In this case, the modal <strong>contains</strong><br> the flexbox, that handles the<br> body and the footer.<br> . <br> . <br> . <br> . <br> . <br> . <br> </div> <div class="modal-content__footer"> <code>FOOTER // </code> Doesn't work </div> </div> </div> </section> </main>(父级)和.modal(子级)的高度相同,因此将尺寸从父级移动到子级。这会使高度限制足够接近内容项以触发溢出。

而不是:

modal-content

试试这个:

.modal {
    width: 30rem;
    max-width: calc(50vw - 3rem);
    max-height: calc(100vh - 3rem);
}

.modal-content {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

&#13;
&#13;
.modal {    }

.modal-content {
    display: flex;
    flex-direction: column;
    min-height: 0;
    width: 30em;
    max-width: calc(50vw - 3rem);
    max-height: calc(100vh - 3rem);
}
&#13;
/* Centers the child */
.modal-container {
  display: flex;
  align-items: center;
  justify-content: center;
}
  
/* The box in the middle, that should grow
   organically, but be restricted as well */
.modal, .modal-content--merged-with-modal {


  /* Irrelevant styling */
  background: rgba(255, 255, 255, 0.6);
  border-radius: 3px;
  line-height: 1.5rem;
}
  
  
.modal-content {
  display: flex;
  flex-direction: column;
  min-height: 0;   
     width: 30rem;
     max-width: calc(50vw - 3rem);
     max-height: calc(100vh - 3rem);
}
  
.modal-content__body {
  flex: 1;
  min-height: 0;
  overflow-y: scroll;

  /* Irrelevant styling */
  padding: 0.75rem;
  background: rgba(0, 0, 255, 0.1);
}
  
  
.modal-content__footer {
  /* Irrelevant styling */
  border-top: 1px solid silver;
  background: rgba(0, 255, 0, 0.1);
  padding: 0.75rem;
}
  
  
  
/* Irrelevant styling to present the problem */
html {
  font-family: arial, sans-serif;
  font-size: 16px;
}
main {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  
  display: flex;
}
section {
  flex: 1;
  background: rgba(255, 0, 0, 0.1);
}
&#13;
&#13;
&#13;