【问题标题】:Flexbox: center horizontally and verticallyFlexbox:水平和垂直居中
【发布时间】:2013-10-02 08:11:56
【问题描述】:

如何使用 flexbox 在容器内水平和垂直居中 div。在下面的示例中,我希望每个数字彼此下方(按行),它们水平居中。

.flex-container {
  padding: 0;
  margin: 0;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
row {
  width: 100%;
}
.flex-item {
  background: tomato;
  padding: 5px;
  width: 200px;
  height: 150px;
  margin: 10px;
  line-height: 150px;
  color: white;
  font-weight: bold;
  font-size: 3em;
  text-align: center;
}
<div class="flex-container">
  <div class="row">
    <span class="flex-item">1</span>
  </div>
  <div class="row">
    <span class="flex-item">2</span>
  </div>
  <div class="row">
    <span class="flex-item">3</span>
  </div>
  <div class="row">
    <span class="flex-item">4</span>
  </div>
</div>

http://codepen.io/anon/pen/zLxBo

【问题讨论】:

  • 在您的 CSS 中,row{ 对行没有影响。如果将其更改为.row{,结果将完全不同。

标签: html css flexbox


【解决方案1】:

我想你想要类似下面的东西。

html, body {
    height: 100%;
}
body {
    margin: 0;
}
.flex-container {
    height: 100%;
    padding: 0;
    margin: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
.row {
    width: auto;
    border: 1px solid blue;
}
.flex-item {
    background-color: tomato;
    padding: 5px;
    width: 20px;
    height: 20px;
    margin: 10px;
    line-height: 20px;
    color: white;
    font-weight: bold;
    font-size: 2em;
    text-align: center;
}
<div class="flex-container">
    <div class="row"> 
        <div class="flex-item">1</div>
        <div class="flex-item">2</div>
        <div class="flex-item">3</div>
        <div class="flex-item">4</div>
    </div>
</div>

查看演示:http://jsfiddle.net/audetwebdesign/tFscL/

如果您希望高度和顶部/底部填充正常工作,您的 .flex-item 元素应该是块级(div 而不是 span)。

另外,在.row 上,将宽度设置为auto 而不是100%

您的.flex-container 属性很好。

如果您希望 .row 在视口中垂直居中,请将 100% 高度分配给 htmlbody,并将 body 边距归零。

注意.flex-container需要一个高度才能看到垂直对齐效果,否则容器会计算包围内容所需的最小高度,在本例中小于视口高度。

脚注:
flex-flowflex-directionflex-wrap 属性可以使这个设计更容易实现。我认为不需要.row 容器,除非您想在元素周围添加一些样式(背景图像、边框等)。

一个有用的资源是:http://demo.agektmr.com/flexbox/

【讨论】:

  • 弹性项目不需要是块级的,除非它们包含的内容需要它。此外,您已经为所有显示属性添加了前缀,但没有为任何其他 Flexbox 属性添加前缀(在其他草稿中具有不同的名称)。
  • @cimmanon 我同意你关于块级别的观点,并相应地编辑了我的帖子。对齐不需要块级别​​,但如果用户想要指定高度等,则可能需要块级别​​。我对浏览器前缀很随意,我只是假设一个完美的浏览器是为了获得一个工作演示。再次感谢您的评论,感谢您的反馈。
  • 如果溢出,它会裁剪顶部。 i.imgur.com/3dgFfQK.png 有什么办法可以避免这种情况?
  • @BrianGates 如果窗口的高度太短,你希望 4 个元素如何显示,2x2、1x4?
【解决方案2】:

如何在 Flexbox 中垂直和水平居中元素

以下是两种通用的定心解决方案。

一个用于垂直对齐的弹性项目 (flex-direction: column),另一个用于水平对齐的弹性项目 (flex-direction: row)。

在这两种情况下,居中 div 的高度可以是可变的、未定义的、未知的,等等。居中 div 的高度无关紧要。

这是两者的 HTML:

<div id="container"><!-- flex container -->

    <div class="box" id="bluebox"><!-- flex item -->
        <p>DIV #1</p>
    </div>

    <div class="box" id="redbox"><!-- flex item -->
        <p>DIV #2</p>
    </div>

</div>

CSS(不包括装饰样式)

当弹性项目垂直堆叠时:

#container {
    display: flex;           /* establish flex container */
    flex-direction: column;  /* make main axis vertical */
    justify-content: center; /* center items vertically, in this case */
    align-items: center;     /* center items horizontally, in this case */
    height: 300px;
}

.box {
    width: 300px;
    margin: 5px;
    text-align: center;     /* will center text in <p>, which is not a flex item */
}

DEMO


当弹性项目水平堆叠时:

调整以上代码中的flex-direction 规则。

#container {
    display: flex;
    flex-direction: row;     /* make main axis horizontal (default setting) */
    justify-content: center; /* center items horizontally, in this case */
    align-items: center;     /* center items vertically, in this case */
    height: 300px;
}

DEMO


使弹性项目的内容居中

flex formatting context 的范围仅限于父子关系。子元素之外的 flex 容器的后代不参与 flex 布局,并且会忽略 flex 属性。本质上,flex 属性不能被子级继承。

因此,您始终需要将 display: flexdisplay: inline-flex 应用于父元素,以便将 flex 属性应用于子元素。

为了使弹性项目中包含的文本或其他内容垂直和/或水平居中,请将项目设为(嵌套)弹性容器,并重复居中规则。

.box {
    display: flex;
    justify-content: center;
    align-items: center;        /* for single line flex container */
    align-content: center;      /* for multi-line flex container */
}

更多详情:How to vertically align text inside a flexbox?

或者,您可以将margin: auto 应用于弹性项目的内容元素。

p { margin: auto; }

在此处了解 flex auto 边距:Methods for Aligning Flex Items(参见框#56)。


使多行 flex 项居中

当 flex 容器有多行(由于换行)时,align-content 属性将是横轴对齐所必需的。

来自规范:

8.4. Packing Flex Lines: the align-content property

align-content 属性在 当横轴有额外空间时,弹性容器,类似于 justify-content 如何在主轴内对齐单个项目。 请注意,此属性对单行 flex 容器没有影响。

更多详情:How does flex-wrap work with align-self, align-items and align-content?


浏览器支持

所有主流浏览器都支持 Flexbox,except IE < 10。一些最新的浏览器版本,例如 Safari 8 和 IE10,需要vendor prefixes。要快速添加前缀,请使用Autoprefixer。更多详情this answer


针对旧版浏览器的居中解决方案

有关使用 CSS 表格和定位属性的替代居中解决方案,请参阅此答案:https://stackoverflow.com/a/31977476/3597276

【讨论】:

  • 我们能做到水平右左垂直居中吗?
  • @kapil,将 justify-content 属性调整为 space-betweenspace-around... @ 987654335@
  • 这个答案应该在最上面。使用 Flex 应该是执行此操作的首选方式,因为它可以很好地跨设备和屏幕进行缩放。它比使用浮点数和管理多个 div 要容易得多。
  • 即11不能正常水平垂直居中
  • 感谢您注意到子元素不会自动伸缩项目。如果我们想要他们,我们需要迎合他们。
【解决方案3】:

添加

.container {
    display: flex;
    justify-content: center;
    align-items: center;
}

到任何你想居中的容器元素。文档: justify-contentalign-items.

【讨论】:

    【解决方案4】:

    你可以使用

    display: flex;
    align-items: center;
    justify-content: center;
    

    在你的父组件上

    【讨论】:

      【解决方案5】:

      别忘了使用重要的浏览器特定属性:

      对齐项目:居中; -->

      -webkit-box-align: center;
      -moz-box-align: center;
      -ms-flex-align: center;
      -webkit-align-items: center;
      align-items: center;
      

      对齐内容:居中; -->

      -webkit-box-pack: center;
      -moz-box-pack: center;
      -ms-flex-pack: center;
      -webkit-justify-content: center;
      justify-content: center;
      

      您可以阅读这两个链接以更好地理解 flex: http://css-tricks.com/almanac/properties/j/justify-content/http://ptb2.me/flexbox/

      祝你好运。

      【讨论】:

      • 这是一个很好的观点,今天(仅支持最新的浏览器)您只需要最后两行 -webkit.. 用于 safari,最后一行用于所有其他浏览器
      • +1 因为旧的 2009 年和 2012 年 3 月的工作草案仍然有很大的用户份额(根据caniuse.com 加起来约为 8%)。
      • Flext 在 safari 中不起作用,你怎么能解决这个问题?
      • 很多天前我在windows上查看了最后一个版本的safari,我不太记得了,但我会检查并告诉你。请告诉我你指的是哪个版本的 safari?在哪个操作系统上?
      • @user3378649 safari 最新版本可以支持 Flex-box,请看这个链接:caniuse.com/#search=flexbox
      【解决方案6】:

      1 - 将父 div 上的 CSS 设置为 display: flex;

      2 - 将父 div 上的 CSS 设置为 flex-direction: column;
      请注意,这将使该 div 中的所有内容从上到下排列。如果父 div 仅包含子 div 而没有其他内容,这将最有效。

      3 - 将父 div 上的 CSS 设置为 justify-content: center;

      下面是 CSS 的示例:

      .parentDivClass {
        display: flex;
        flex-direction: column;
        justify-content: center;
      }

      【讨论】:

        【解决方案7】:

        diplay: flex; 代表它的容器,margin:auto; 代表它的项目完美。

        注意:您必须设置widthheight 才能看到效果。

        #container{
          width: 100%; /*width needs to be setup*/
          height: 150px; /*height needs to be setup*/
          display: flex;
        }
        
        .item{
          margin: auto; /*These will make the item in center*/
          background-color: #CCC;
        }
        <div id="container">
           <div class="item">CENTER</div>
        </div>

        【讨论】:

          【解决方案8】:

          使用这个:

             html, body {
                display: flex;
                align-items: center;
                justify-content: center;
                height: 100%;
             }
          

          对于一些像这样的 HTML 标记:

             <html>
                <body>
                  <main>
                    <button> abc </button>
                    <p> something </p>
                  </main>
                </body>
              </html>
          

             html, body {
                display: flex;
                align-items: center;
                justify-content: center;
                height: 100%;
             }
             <html>
                <body>
                  <main>
                    <button> abc </button>
                    <p> something </p>
                  </main>
                </body>
              </html>

          【讨论】:

            【解决方案9】:

            margin: auto 与 flexbox “完美”配合,即它允许将项目垂直和水平居中。

            html, body {
              height: 100%;
              max-height: 100%;
            }
            
            .flex-container {
              display: flex;
                
              height: 100%;
              background-color: green;
            }
            
            .container {
              display: flex;
              margin: auto;
            }
            <!DOCTYPE html>
            <html>
            <head>
              <meta charset="utf-8">
              <meta name="viewport" content="width=device-width">
              <title>JS</title>
            </head>
            <body>
              <div class="flex-container">
                <div class="container">
                  <div class="row">
                    <span class="flex-item">1</span>
                  </div>
                  <div class="row">
                    <span class="flex-item">2</span>
                  </div>
                  <div class="row">
                    <span class="flex-item">3</span>
                  </div>
                 <div class="row">
                    <span class="flex-item">4</span>
                </div>
              </div>  
            </div>
            </body>
            </html>

            【讨论】:

              【解决方案10】:

              如果您需要将链接中的文本居中,则可以解决问题:

              div {
                display: flex;
              
                width: 200px;
                height: 80px;
                background-color: yellow;
              }
              
              a {
                display: flex;
                align-items: center;
                justify-content: center;
                text-align: center; /* only important for multiple lines */
              
                padding: 0 20px;
                background-color: silver;
                border: 2px solid blue;
              }
              <div>
                <a href="#">text</a>
                <a href="#">text with two lines</a>
              </div>

              【讨论】:

                【解决方案11】:

                结果:

                代码

                HTML:

                <div class="flex-container">
                  <div class="rows">
                
                    <div class="row">
                      <span class="flex-item">1</span>
                    </div>
                    <div class="row">
                      <span class="flex-item">2</span>
                    </div>
                    <div class="row">
                      <span class="flex-item">3</span>
                    </div>
                    <div class="row">
                      <span class="flex-item">4</span>
                    </div>
                
                  </div>  
                </div>
                

                CSS:

                html, body {
                  height: 100%;  
                }
                
                .flex-container {
                  display: flex;
                  justify-content: center;
                  align-items: center;
                  height: 100%;
                }
                
                .rows {
                  display: flex;
                  flex-direction: column;
                }
                

                其中flex-container div 用于将rows div 垂直和水平居中,rows div 用于对“项目”进行分组并在基于列的列中对它们进行排序。

                【讨论】:

                  【解决方案12】:

                  您可以将flex-direction:column 添加到flex-container

                  .flex-container {
                    flex-direction: column;
                  }
                  

                  display:inline-block 添加到 flex-item

                  .flex-item {
                   display: inline-block;
                  }
                  

                  因为您添加的width and height 对这个元素没有影响,因为它显示为inline。尝试添加 display:inline-blockdisplay:block 详细了解 widthheight

                  还添加到 row 类(您被赋予 row{} 不被视为样式)

                  .row{
                    width:100%;
                    margin:0 auto;
                    text-align:center;
                  }
                  

                  工作演示:

                  .flex-container {
                    padding: 0;
                    margin: 0;
                    list-style: none;
                    display: flex;
                    align-items: center;
                    justify-content:center;
                    flex-direction:column;
                  }
                  .row{
                    width:100%;
                    margin:0 auto;
                    text-align:center;
                  }
                  .flex-item {
                    background: tomato;
                    padding: 5px;
                    width: 200px;
                    height: 150px;
                    margin: 10px;
                    line-height: 150px;
                    color: white;
                    font-weight: bold;
                    font-size: 3em;
                    text-align: center;
                    display: inline-block;
                  }
                  <div class="flex-container">
                    <div class="row">
                      <span class="flex-item">1</span>
                    </div>
                    <div class="row">
                      <span class="flex-item">2</span>
                    </div>
                    <div class="row">
                      <span class="flex-item">3</span>
                    </div>
                    <div class="row">
                      <span class="flex-item">4</span>
                    </div>
                  </div>

                  专栏中的工作演示:

                  .flex-container {
                    padding: 0;
                    margin: 0;
                    width: 100%;
                    list-style: none;
                    display: flex;
                    align-items: center;
                  }
                  .row {
                    width: 100%;
                  }
                  .flex-item {
                    background: tomato;
                    padding: 5px;
                    width: 200px;
                    height: 150px;
                    margin: 10px;
                    line-height: 150px;
                    color: white;
                    font-weight: bold;
                    font-size: 3em;
                    text-align: center;
                    display: inline-block;
                  }
                  <div class="flex-container">
                    <div class="row">
                      <span class="flex-item">1</span>
                    </div>
                    <div class="row">
                      <span class="flex-item">2</span>
                    </div>
                    <div class="row">
                      <span class="flex-item">3</span>
                    </div>
                    <div class="row">
                      <span class="flex-item">4</span>
                    </div>
                  </div>

                  【讨论】:

                    【解决方案13】:

                    希望这会有所帮助。

                    .flex-container {
                      padding: 0;
                      margin: 0;
                      list-style: none;
                      display: flex;
                      align-items: center;
                      justify-content: center;
                    }
                    row {
                      width: 100%;
                    }
                    .flex-item {
                      background: tomato;
                      padding: 5px;
                      width: 200px;
                      height: 150px;
                      margin: 10px;
                      line-height: 150px;
                      color: white;
                      font-weight: bold;
                      font-size: 3em;
                      text-align: center;
                    }
                    

                    【讨论】:

                    • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
                    【解决方案14】:

                    使用CSS+

                    <div class="EXTENDER">
                      <div class="PADDER-CENTER">
                        <div contentEditable="true">Edit this text...</div>
                      </div>
                    </div>
                    

                    看看HERE

                    【讨论】:

                    • 因为这很容易被带有纯 flexbox 的现代浏览器广泛支持,所以你的库解决方案肯定是没有必要的。特别是因为他问如何使用 flex box 而不是 css 库来做到这一点。
                    猜你喜欢
                    • 2020-03-03
                    相关资源
                    最近更新 更多