2

Why is it that a button placed inside a flex container is centered by using margin : 0px auto;, but a button placed inside a normal container is not?

Also, what can I do to center the button in the normal container (I cannot change my HTML, so a CSS solution would be appreciated.)

.flex-container {
  display: flex;
  background: yellow;
}
.normal-container {
  background: green;
}
button {
  margin: 0px auto;
}
<div class="flex-container">
  <button>Button in flex</button>
</div>
<div class="normal-container">
  <button>Button in normal</button>
</div>

jsFiddle link : https://jsfiddle.net/r8h3d9wy/1/

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
agdhruv
  • 575
  • 6
  • 20

5 Answers5

1

text-align:center on the parent as inputs/buttons are inline level elements.

margin:0 auto in flex-containers works because that's the way alignment works on flex-items. It effectively removes the inline level nature and makes it a flex-child.

.flex-container {
  display: flex;
  background: yellow;
  justify-content: center;
}
.normal-container {
  background: green;
  text-align: center;
}
<div class="flex-container">
  <button>Button in flex</button>
</div>
<div class="normal-container">
  <button>Button in normal</button>
</div>
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
1

In normal containers, margin: 0px auto is only applied to block elements. Try this:

button {
    display: block;
    margin: 0px auto;
}

Normally, block elements have a width of 100% by default. In this case it's not a problem because you use a button. Otherwise you would have to set the width to center the element.

Aloso
  • 5,123
  • 4
  • 24
  • 41
1

With inline-level elements, like button, margin-left: auto and margin-right: auto compute to 0.

10.3.1 Inline, non-replaced elements

The width property does not apply. A specified value of auto for left, right, margin-left or margin-right becomes a computed value of 0.

You can center the button element by:

  1. Applying text-align: center to the parent (demo), OR
  2. Switching to display: block on the button (demo).

In the flex container, you're working within a flex formatting context, which blockifies flex items and permits alignment with auto margins.

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

If you inspect the computed styles in chrome you will notice that the child elements in the flex container will have display:block while the child elements in the normal container will have display:inline-block. If you add display:block to the CSS for the button it will center the same in both containers.

Joseph Evans
  • 1,360
  • 9
  • 14
0

The following CSS code would do the trick. I've made explanations using comments.

.flex-container{
  display:flex;
  background:yellow;
}

.normal-container{
  background:green;
  text-align: center; /*aligns inline items to center.*/

button{
  margin : auto;
  display: inline; /* Not needed in this case as the button is an inline element naturally. However, if you have a block element, you would use this to make it an inline element. Explanation below. */
}

A display:block element takes up all the space to the right or left of it in the parent container. Thus, margin:auto does nothing as there is no margin. Making it an inline element changes this and frees up the margins allowing margin:auto to work.