【问题标题】:Why doesn't "margin: auto" center an element vertically?为什么“margin:auto”不垂直居中元素?
【发布时间】:2016-04-05 18:16:39
【问题描述】:

正如您在下面的演示中所见,margin: auto; 将蓝色 div 水平居中,但不是垂直居中。为什么不呢?

.box {
  border: 1px solid red;
  width: 100px;
  height: 100px;
}
.center {
  background: blue;
  width: 50px;
  height: 50px;
  margin: auto;
}
<div class="box">
  <div class="center"></div>
</div>

我的问题不是寻求解决方法。

【问题讨论】:

  • 它只是没有。水平居中内容的用例可能比垂直居中更常见。
  • @TZHX 从技术上讲,它可以垂直居中。请参阅此示例 - jsfiddle.net/skdjhpo8
  • CSS 中的垂直对齐是一个神话
  • @FabioPoloni Flexbox?
  • @FabioPoloni ¯\_(ツ)_/¯ IE do actually support flexbox 的较新版本,有一些注意事项。

标签: html css margin


【解决方案1】:

为什么...因为W3C spec 是这么说的。

如果 'margin-top' 或 'margin-bottom' 为 'auto',则它们的使用值为 0。

至于实际的“为什么”……应该在那里真正解决问题。

【讨论】:

    【解决方案2】:

    如前所述,此行为在 CSS2.1 的 section 10.6.2 中指定,与 CSS2 相比保持不变。

    方块盒在正常流程中从上到下垂直堆叠。此外,vertical margins may collapse,并且仅在某些情况下这样做(在您的演示中,父元素上的边框将防止子元素上的任何边距与其自身折叠)。如果你只有一个这样的块框,并且包含块的高度是自动的,那么它的顶部和底部边距无论如何都将为零。但是,如果您在同一个流中有多个块框,或者甚至影响流中框布局的流外框(例如clearance),您希望如何解决自动边距对于那些流入框?

    这就是为什么对于内联元素(包括原子内联)和浮动(尽管水平边距永远不会折叠),自动左边距和右边距同样被归零。内联框是laid along line boxes,浮动也服从unique layout rules

    绝对定位的盒子是另一回事:因为它们从不知道与自己处于相同定位上下文中的任何其他盒子,auto top and bottom margins can be calculated for them with respect to their containing blocks 而不必担心任何其他盒子会干扰。

    Flexbox 也是一个不同的故事:flex 布局与块布局的不同之处在于,根据定义,flex 项目总是知道同一 flex 格式化上下文中的其他 flex 项目,包括没有的事实。特别是neither can floats intrude into the flex container, nor can you float flex items to subvert this(尽管您仍然可以使用absolute positioning 完全从弹性布局中删除子元素)。弹性项目的边距表现非常不同,部分原因是这一点。请参阅4.29.59.6 部分。

    【讨论】:

      【解决方案3】:

      它不会垂直居中元素,因为它是正常流程中的块级元素。因此,following rule applies:

      如果margin-topmargin-bottomauto,则它们的使用值为0。

      还值得指出的是,上述规则也适用于以下元素:(有关更多信息和条件,请参阅点 10.6.210.6.3)。

      • 内联替换元素
      • 正常流程中的块级替换元素
      • inline-block 替换正常流程中的元素
      • 浮动替换元素
      • overflow 计算为visible 时,正常流中的块级非替换元素

      话虽如此,绝对定位的、不可替换的元素不具有topheightbottomauto 是此规则的一个例外。以下内容适用于point 10.6.4

      如果topheightbottom这三个都不是auto,并且如果margin-topmargin-bottom都是auto在额外的约束下求解方程两个边距获得相等的值

      请参阅下面的示例,演示如何使用margin: auto 将绝对定位元素垂直居中。之所以有效,是因为topheightbottom 三个属性都没有auto 的值:

      .box {
        border: 1px solid red;
        width: 100px;
        height: 100px;
        position: relative;
      }
      .center {
        background: blue;
        width: 50px;
        height: 50px;
        margin: auto;
        position: absolute;
        top: 0; right: 0;
        bottom: 0; left: 0;
      }
      <div class="box">
        <div class="center"></div>
      </div>

      此外,following rule 可能也值得指出:

      如果margin-topmargin-bottom 之一是auto,请求解该值的等式。如果值受到过度约束,请忽略 bottom 的值并求解该值。

      这意味着如果绝对定位元素的margin-top 值为automargin-bottom 值为0(即margin: auto auto 0),则该元素将绝对定位在底部相对于父级如下例所示:

      .box {
        border: 1px solid red;
        width: 100px;
        height: 100px;
        position: relative;
      }
      .center {
        background: blue;
        width: 50px;
        height: 50px;
        margin: auto auto 0;
        position: absolute;
        top: 0; right: 0;
        bottom: 0; left: 0;
      }
      <div class="box">
        <div class="center"></div>
      </div>

      【讨论】:

        【解决方案4】:

        这是因为知道要在其中垂直居中的元素的真实高度的实际可能性。要理解这一点,首先要考虑自动水平居中的工作原理。你有一个 div,你给它一个宽度(固定或百分比)。宽度可以计算到一定程度。如果它是固定宽度,那就太好了。如果它是灵活的或响应式的(百分比),至少你有一个宽度在到达下一个断点之前将覆盖的范围。你取那个宽度,减去里面的任何东西,然后把剩下的部分分成两边。

        现在,有了这些信息,浏览器如何计算出 div 垂直增长的无限变化量?请记住元素的大小、文本的换行、填充和响应性也会改变宽度并迫使文本进一步换行,等等。

        这是不可能完成的任务吗?不是真的,CSS 有没有花时间和精力来解决这个问题?不值得他们花时间,我猜。

        这基本上就是我告诉我的学生的答案。

        但是....不要担心! Bootstrap v4 alpha 发现了vertical centering

        编辑

        抱歉编辑得晚了,但我想你可能想考虑这个解决方案垂直居中,使用 calc 函数非常简单

        <div class="foo"></div>
        
        .foo {
          background-color: red;
          height: 6em;
          left: calc(50% - 3em);
          position: absolute;
          top: calc(50% - 3em);
          width: 6em;
        }
        

        HERE

        【讨论】:

        • 更准确的说法是 Flexbox 已经确定了我们的垂直居中位置,而 B4a 已经赶上了潮流。
        • 那个,我不知道
        【解决方案5】:

        为什么margin:auto 不能垂直工作?

        实际上,确实如此——只是不是针对每个 display 值。

        如果displayflex,则margin: auto 垂直和水平居中。

        这同样适用于display: inline-flexdisplay: griddisplay: inline-grid

        .box {
          border: 1px solid red;
          width: 100px;
          height: 100px;
          display: flex; /* new */
        }
        .center {
          background: blue;
          width: 50px;
          height: 50px;
          margin: auto;
        }
        <div class="box">
          <div class="center"></div>
        </div>

        【讨论】:

          猜你喜欢
          • 2020-05-10
          • 1970-01-01
          • 2011-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多