垂直居中的嵌套弹性框

时间:2016-08-16 18:02:35

标签: css flexbox

我正在尝试使用三个垂直部分实现简单布局:

  1. 页面顶部的小标题。
  2. 主要内容,必要时展开,以便页脚保留在页面底部。
  3. 页面底部的页脚。
  4. 主要内容部分应进一步分为两部分:一个带有输入框和一个按钮的非常小的表格和一个显示一些表格数据的5行最大表格。该表应该占用所需的垂直空间,小形式应该在剩余的垂直空间中居中。

    我尝试过使用柔性盒子但是我做错了;我无法在可用空间中将微小的形状垂直居中。这是我到目前为止所做的简化版本(最好以全屏方式查看):

    body {
      margin:0;
      min-height:100vh;
      display:flex;
      flex-direction:column;
      align-items:center;
    }
    
    main {
      flex:1;
      display:flex;
      flex-direction:column;
    }
    
    main>form {
      flex:1;
    }
    <body>
      <header>header</header>
      <main>
        <form>
          <h1>Form with inputs</h1>
          <label>Inputs</label>
          <input type="text">
          <button>Button</button>
        </form>
        <div>
          <h1>Other content</h1>
          <ul>
            <li>Item 1</li>
            <li>Item 2</li>
            <li>Item 3</li>
          </ul>
        </div>
      </main>
      <footer>footer</footer>
    </body>

    我尝试了justify-contentalign-contentalign-itemsalign-self的多种组合,但我尝试的越多,我似乎就越不了解我在做什么: - (

    任何人都可以,向我提供任何关于我做错的提示吗?

    编辑:如果我可以使用某些元素的固定高度,我可能会做这样的事情(这也说明了我的目标,更好地全屏观看):

    * {
      box-sizing:border-box;
    }
          
    html {
      height:100%;
    }
      
    body {
      margin:0;
      height:100%;
      position:relative;
    }
    
    header {
      height:40px;
      background-color:#E6ECC1;
    }
    
    main {
      height:calc(100% - 80px);
      background-color:#dfd;
    }
    
    h1 {
      margin:0;
      padding:10px 0;
    }
    
    main>form {
      height:calc(100% - 150px);
      background-color:#C1E4EC;
    }
    
    main>form:before {
      content:"";
      display:inline-block;
      height:100%;
      vertical-align:middle;
    }
    
    main>form>div {
      display: inline-block;
      vertical-align: middle;
      width: calc(100% - 4px);
      text-align: center;
    }
    
    main>div {
      padding:0 20px;
      height:150px;
      position:absolute;
      bottom:40px;
    }
    
    footer {
      position:absolute;
      height:40px;
      width:100%;
      bottom:0;
      background-color:#fdd;
    }
    <body>
      <header>header</header>
      <main>
        <form>
          <div>
            <h1>Form with inputs</h1>
            <label>Inputs</label>
            <input type="text">
            <button>Button</button>
          </div>
        </form>
        <div>
          <h1>Other content</h1>
          <ul>
            <li>Item 1</li>
            <li>Item 2</li>
            <li>Item 3</li>
          </ul>
        </div>
      </main>
      <footer>footer</footer>
    </body>

    我以为我可以使用两个嵌套的柔性盒更干净地实现它;一个外部为顶部的标题提供空间,底部的页脚和中间部分可以生长以填充其间的所有可用空间,内部部分将外部中间部分分成两部分;一个底部有一个恒定但未知的高度,一个顶部占据中间部分的所有剩余空间。该块的内容远小于在大型显示器中查看页面时的可用区域,应该在可用区域中水平和垂直居中。

    当我只使用外部弹性框(原始代码段中的<body>元素)时,内容在页眉和页脚之间垂直居中。但是当我尝试拆分中间部分(原始代码段中的<main>元素)时,表单会向上推。就好像外框中flex:1元素的高度不可用于其子元素。

    非常感谢,祝你有个美好的一天。

3 个答案:

答案 0 :(得分:0)

您的居中(对齐/对齐内容)不会被继承,因此您必须为每个弹性容器重新设置它。

&#13;
&#13;
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
}
header {
  background: green
}
main {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: pink;
}
main>form {
  background: orange;
}
&#13;
<body>
  <header>header</header>
  <main>
    <form>
      <h1>Form with inputs</h1>
      <label>Inputs</label>
      <input type="text">
      <button>Button</button>
    </form>
    <div>
      <h1>Other content</h1>
      <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
      </ul>
    </div>
  </main>
  <footer>footer</footer>
</body>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我感谢所有回答的人,尽管答案并没有完全符合我的要求。最后,我通过将表单包装到我应用了flex属性的额外div中来管理我之后的事情:

&#13;
&#13;
body {
  margin: 0;
  background-color: #F3F3F3;
  display: flex;
  flex-direction: column;
  height: 100vh;
}

header {
  background-color: #fdd;
}

main {
  flex: 1;
  display: flex;
  flex-direction: column;
}

div.form {
  background-color: #dfd;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-bottom: 20px;
}

div.other {
  background-color: #fdb;
  padding: 0 10vw;
}

footer {
  background-color: #ddf;
}
&#13;
<body>
  <header>header</header>
  <main>
    <div class="form">
      <form>
        <h1>Form with inputs</h1>
        <label>Inputs</label>
        <input type="text">
        <button>Button</button>
      </form>
    </div>
    <div class="other">
      <h1>Other content</h1>
      <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
      </ul>
    </div>
  </main>
  <footer>footer</footer>
</body>
&#13;
&#13;
&#13;

我希望将来可以帮助其他有类似问题的人!

答案 2 :(得分:-1)

  1. 摆脱align-items: center;,因为它会将块元素转换为内联块,而是使用text-align: center
  2. flexbox align items center problems

    1. htmlbody都需要定义height 100%

    2. 如果您希望form内的main占用大部分空间,只需将flex: 1应用于此。

    3. 简化演示工作:

      html, body {margin: 0; padding: 0; height: 100%; text-align: center;}
      
      body { width: 100%; display:flex; flex-direction:column; }
      
      header { padding: 1em; background: lightblue; }
      
      footer { padding: 1em; background: gray; }
      
      main { flex:1; display:flex; flex-direction:column; background: lightyellow; overflow: auto;}
      
      main > form { border-bottom:1px dashed gold; flex:1; }
      
      #data { padding: 1em; }
      
      main ul  { margin: 0; padding: 0; display: inline-block }
      <header>header</header>
      <main>
        <form>
          <h1>Form with inputs</h1>
          <label>Inputs</label>
          <input type="text">
          <button>Button</button>
        </form>
        <div id="data">
          <h1>Other content</h1>
          <ul>
            <li>Item 1</li>
            <li>Item 2</li>
            <li>Item 3</li>
          </ul>
        </div>
      </main>
      <footer>footer</footer>

      jsFiddle:https://jsfiddle.net/azizn/hLse4wa7/