使用 Flexbox 获取所有可用高度的组件(在 Quasar/Vue 中)

Posted

技术标签:

【中文标题】使用 Flexbox 获取所有可用高度的组件(在 Quasar/Vue 中)【英文标题】:Component to take all available height with Flexbox (in Quasar/Vue) 【发布时间】:2019-11-26 17:29:41 【问题描述】:

我正在构建一个带有页眉/主要内容/页脚的组件,其中主要内容可以滚动。虽然我可以在 Js 中执行此操作,但我需要组件将高度和页脚上的所有可用空间置于底部。 即使代码正确,我也无法让它占据整个高度。

这是一支无法使用代码的笔:https://codepen.io/SharpBCD/pen/MNgxgY

    .panel 
    width: 100%;
    height: 100%;

    display: flex;
    flex-direction: column;
    flex-grow: 1;

    justify-content: flex-start; /* align items in Main Axis */
    align-items: stretch; /* align items in Cross Axis */
    align-content: stretch; /* Extra space in Cross Axis */

    background-color: #00acc1;
  
   .panel-header
    flex: 0 1 auto;
    /*max-height: fit-content;*/
  
  .panel-main
    /*margin-bottom: auto;*/
    display: flex;
    flex-direction: column;
    flex: 1; /* same as flex: 1 1 auto; */
    justify-content: flex-start; /* align items in Main Axis */
    align-items: stretch; /* align items in Cross Axis */
    align-content: stretch; /* Extra space in Cross Axis */
    background-color: #0d47a1;
  
  .panel-footer
    margin-top: auto;
    max-height: fit-content;
  

这是我尝试过的工作代码的 jsfiddle:https://jsfiddle.net/MadLittleMods/LmYay/

.flexbox-parent

    width: 100%;
    height: 100%;

    display: flex;
    flex-direction: column;

    justify-content: flex-start; /* align items in Main Axis */
    align-items: stretch; /* align items in Cross Axis */
    align-content: stretch; /* Extra space in Cross Axis */

    background: rgba(255, 255, 255, .1);


.flexbox-item-grow

    flex: 1; /* same as flex: 1 1 auto; */

.fill-area

    display: flex;
    flex-direction: row;

    justify-content: flex-start; /* align items in Main Axis */
    align-items: stretch; /* align items in Cross Axis */
    align-content: stretch; /* Extra space in Cross Axis */


那么...有什么问题?我做错了什么?

【问题讨论】:

【参考方案1】:

如果你想使用 flex 模型并将你的#q-app 放置在窗口的整个高度上,你需要从根开始构建 flex 布局。

您可以使用以下样式:

 /* update */
#q-app 
  height:100vh;/* or min-height:100vh if you want it to grow */
  display:flex;

.q-pa-md
  flex:1;
  display:flex;
  flex-direction:column;

 /* end update */

Demos(sn-p 运行或 fork codepens)

/* update */
body 
  margin:0;
  
#q-app 
  min-height:100vh;
  display:flex;
  
.q-pa-md
  flex:1;
  display:flex;
  flex-direction:column;
  
 /* end update */
.panel 
    width: 100%;
    height: 100%;
  
    display: flex;
    flex-direction: column;
    flex-grow:1; 
    
    justify-content: flex-start; /* align items in Main Axis */
    align-items: stretch; /* align items in Cross Axis */
    align-content: stretch; /* Extra space in Cross Axis */
  
    background-color: #00acc1;
  
.panel-header
    flex: 0 1 auto;
    /*max-height: fit-content;*/
  
  .panel-main
    /*margin-bottom: auto;*/
    display: flex;
    flex-direction: column;
    flex: 1; /* same as flex: 1 1 auto; */
    justify-content: flex-start; /* align items in Main Axis */
    align-items: stretch; /* align items in Cross Axis */
    align-content: stretch; /* Extra space in Cross Axis */
    background-color: #0d47a1;
  
  .panel-footer
    margin-top: auto;
    max-height: fit-content;
  
<!--
  Forked from:
  https://quasar.dev/layout/grid/column#Example--Equal-Height-Example
-->
<div id="q-app">
  <div class="q-pa-md">
    <p> irelevant text to ocupy space before panel</p>
      <div class=" panel">
        <div class=" panel-header">
          I'm a header
        </div>
        <div class = "panel-main">
          Main content
        </div>
        <div class=" panel-footer">
          I'm a footer
        </div>
      </div>
    </div>
</div>

或者玩叉子https://codepen.io/gc-nomade/pen/RXbmYj

另一个带有溢出的版本,将页脚保持在底部并让主要内容滚动https://codepen.io/gc-nomade/pen/rXBgRV

【讨论】:

这是个好主意,但在真正的应用程序中,我无法找到根目录。这是一个可以在各个地方使用的组件,我无法控制它上面的内容。还有什么想法吗?用JS没问题,反正我用。【参考方案2】:

把责任交给父母

如果没有额外的修补,让组件负责占用整个空间对我来说并不成功。一个更简单的解决方案是将items-stretch 类用于row,然后将col 放入以进行拉伸。 这对其他人来说可能更直观。

q-card 为例如下所示。这应该适用于您选择的任何子组件,前提是您使用适当的 row / col 类。

<q-page id="addressesOverview" class="q-pa-md row items-stretch">
  <q-card class="col-12">
    <q-card-section> ... </q-card-section>
  </q-card>
</q-page>

如果你有一个通用组件来显示q-page,你可以把它改成:class,并动态添加items-stretch类。

链接:Quasar Docs - Flexbox - Alignment

【讨论】:

rowitems-strech 上的items-strech 成功了,我认为从父级设置大小的方法是正确的。我在页面内使用了一个 div,所以我还将那个孩子的 div 设置为 rowwidth:100% 支持这个回复也对我有用。绕过额外的div class='row',只需将q-page 设置为class='row'【参考方案3】:

只是你的&lt;html&gt;&lt;body&gt; 没有占据整个页面,对于子节点也是如此......只需将其添加到你的 css 中:

html,body,#q-app,.q-pa-md 
  height:100%;
  width: 100%;

codepen

【讨论】:

这使得.panel 相当于100vh。尝试将&lt;p&gt; irrelevant text to occupy space before panel&lt;/p&gt; 相乘,看看它是如何工作的。我已经更新了笔。另外,作为实际应用程序中的一个组件,我有其他和更多的父母直到根,所以我正在寻找另一个方法。 JS可以工作吗?

以上是关于使用 Flexbox 获取所有可用高度的组件(在 Quasar/Vue 中)的主要内容,如果未能解决你的问题,请参考以下文章

如何在Flexbox内部输入可用空间? [重复]

嵌套的 Flexbox 100% 高度在 Safari 中不起作用 [重复]

获取 flexbox 列换行以使用全宽并最小化高度

React Native 弹性布局FlexBox

React Native 弹性布局FlexBox

获取 flex-box 列以填充可用空间