Margin auto not working

in the picture below, blue box is my root div container inside the body. it is the only body child.(react app). - the root div is flex with flex direction column. justify content and align items is set to center - red is a main element with flex grow 1. it spans the whole height of the root div container. red box is NOT a flex container itself, but has a margin set to auto to center it horizontally and vertically. yes i know i can use justify content and align items on the root, but this is my setup right now. - yellow box is a div which contains stuff denoted with green. it has its margin set to auto, just like its parent(main). Since yellow box has its margin set to auto, i woul expect it to be vertical aligned. however that is not the case. Does it somehow ignore its parent(main), which is a flex child of the root div? please dont tell me how to change the css. i want to understand WHY this behavior occurs. thanks in advance. here is the codepen: https://codepen.io/pmevo/pen/KKGbpNM
pt
CodePen
KKGbpNM
...
19 Replies
Jochem
Jochemβ€’14mo ago
@pm1992 please don't cross post and ask for people to check your thread, it's against the #πŸ“rules (specifically the last part of number 2)
Silvershot
Silvershotβ€’14mo ago
sorry
Jochem
Jochemβ€’14mo ago
it'll make answering your question a lot easier if you can share your code instead of just a screenshot. There's probably some rule buried somewhere that's causing this, but no one can see that in a screenshot. You can make an example in a codepen (https://pen.new) or even just share the resulting HTML and CSS from your app in code blocks (#How To Ask Good Questions has instructions)
Silvershot
Silvershotβ€’14mo ago
@jochemm thanks. got it https://codepen.io/pmevo/pen/KKGbpNM
Jochem
Jochemβ€’14mo ago
margin-top and margin-bottom are set to 0 when you use auto, in the w3 spec for CSS https://www.w3.org/TR/CSS21/visudet.html#normal-block
If 'margin-top', or 'margin-bottom' are 'auto', their used value is 0.
Silvershot
Silvershotβ€’14mo ago
that doesnt justify the behavior. wait what hold up fine. heres the same pen with flex-grow: 0. main is now centered vertically. https://codepen.io/pmevo/pen/KKGbpNM
Jochem
Jochemβ€’14mo ago
you asked why margin: auto didn't center vertically, that's because in the spec the top and bottom margins are set to 0 when you use auto not sure what you mean with this and the next two messages
Silvershot
Silvershotβ€’14mo ago
sure. but now margin: auto DOES center it vertically meaning it sets a margin, or not?
Jochem
Jochemβ€’14mo ago
because it's a flex child and not just a block level element flex is centering, margin is doing nothing wait, not actually true
Silvershot
Silvershotβ€’14mo ago
i am not touching justify content
Jochem
Jochemβ€’14mo ago
but it is because it's a flex item, that changes the behavior
Silvershot
Silvershotβ€’14mo ago
i went through the calculated properties but the display is set to block i realise it is a flex item, sure so that means that flex children(direct ones) can use margin: auto for block direction? wish i could see this in a property that explains it
Jochem
Jochemβ€’14mo ago
looks like, yeah. though I'd still use justify-content over margin:auto just for legibility
Silvershot
Silvershotβ€’14mo ago
yes, i know, but i was trying to understand why πŸ™‚ the common pattern for aligning a div horizontally is doing margin: 0 auto ive seen in examples. why do they use 0 for the block value and not just omit it? since it is set to 0 anyway margin: 0 auto == margin: auto
Jochem
Jochemβ€’14mo ago
it's set to 0 in some circumstances, not in all, so if you're just looking to center horizontally, you're better off being explicit it seems that it has to do with this rule: https://www.w3.org/TR/css-flexbox-1/#main-alignment and this one https://www.w3.org/TR/css-flexbox-1/#item-margins
Silvershot
Silvershotβ€’14mo ago
thanks. to answer your question. i use a root container for my react app. this root container serves 2 or more different views where the main elements' layout differs. i wanted to keep the root element as universal as possible to avoid using classes on it, which led me to expleriment with the margin value and observe that behavior since i was trying to align the main without flex's justify content on the container level
Jochem
Jochemβ€’14mo ago
ah, that makes sense
Silvershot
Silvershotβ€’14mo ago
css isnt that complicated once you keep a few basic rules in mind. in this case i was completely ignoring that it sets the block margin to 0px thanks for helping out.
Jochem
Jochemβ€’14mo ago
no problem, glad we figured it out!