Dość podchwytliwa rzecz, zwłaszcza jeżeli pracujemy też z flexboxem. Postaramy się zrozumieć w końcu, jak ona działa. Do dzieła.

Ok, robimy bardzo prosty HTML:

<body>
    <div class="container">blabla</div>
</body>

I reset stylów CSS plus kolor naszego kontenera:

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

.container {
    background-color: tomato;
}

Kontener jak każdy div rozlał się nam na 100% width, co widzimy po kolorze tła. Ok, nadajmy mu max width:

.container {
    background-color: tomato;
    max-width: 800px;
}

Teraz nie przekracza 800px, zaczyna się od lewej, od pozycji 0,0. Ok, dodajmy margin auto:

.container {
    background-color: tomato;
    max-width: 800px;
    margin: auto;
}

Jest w środku, ale nadal jest przyklejony do góry. Możemy mu nadać jakiś margin-block:

.container {
    background-color: tomato;
    max-width: 800px;
    margin: 2rem auto;
}

Teraz margin góra/dół jest 2rem. Margin inline auto. Natomiast margin auto nie działa na margin block. Nawet teraz:

.container {
    background-color: tomato;
    max-width: 800px;
    margin: auto auto;
}

Możemy nawet dodać więcej elementów:

<div class="container">blabla</div>
<div class="container">blabla</div>
<div class="container">blabla</div>

Tylko w poziomie centruje. To może body na 100vh? Spróbujmy:

body {
    height: 100vh;
    background-color: aliceblue;
}
.container {
    background-color: tomato;
    max-width: 800px;
    margin: auto auto;
}

Nadal nic. Dla marginesów góra/dół auto to zawsze 0. Tylko dla tych inline margins centruje. Ale czy zawsze? Zmieniamy nasz html:

<div class="container">blabla</div>
    <div class="container">blabla</div>
    <div class="container">blabla</div>
    <div class="flex-parent">
        <p>blabla</p>
        <p>blabla</p>
        <p>blabla</p>
    </div>

Teraz robimy taki sam kontener, ale z display flex:

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

.container {
    background-color: tomato;
    max-width: 800px;
    margin: 1rem auto;
}

.flex-parent {
    display: flex;
    background-color: bisque;
    max-width: 800px;
    margin: 1rem auto;
}

Ok, ma 800px, siedzi w środku, jest display flex. To teraz nadajmy jego dzieciom margin auto:

.flex-parent > * {
    margin: auto;
}

Wycentrowało je poziomo. Ok, to teraz dodajmy rodzicowi więcej wysokości:

.flex-parent {
    display: flex;
    background-color: bisque;
    max-width: 800px;
    min-height: 300px;
    margin: 1rem auto;
}

.flex-parent > * {
    margin: auto;
}

Wycentrowało i w poziomie i w pionie. Tak działa margin auto w flex kontenerze. Dodam, że ten kontener ma flex direction row (domyślne). Flex direction nie jest ważne, margin auto tutaj centruje inaczej, niż poza flexem.

To jest, można przekazać auto także tym marginesom blokowym (góra/dół) i tam też będzie centrować. Jeżeli tego nie chcemy, musimy przekazać 0:

.flex-parent > * {
    margin: 0 auto;
}

Flexbox jest bardzo podstępny, trudniej go dogłębnie zrozumieć niż grida. Tym bardziej warto ogarniać takie różne dziwactwa. Więcej CSSa niedługo!