Маржины складываются, вот и всё. То есть например у верхнего блока был нижний маржин 20, а у нижнего блока верхний 10, то сам маржин между ними будет 10. Это то, как работает маржин.
А как может быть между ними если там один блок внутри другого. У боди сброшен в 0. Получается если у первого блока маджин топ 0 у второго 10 то получается по верхнему значению
Про схлопывание отступов можно почитать на MDN, например. Ваш случай - "Родительский и первый/последний дочерние элементы". Потом можно пойти в спецификацию
Не забудьте, что у body тоже по умолчанию тоже есть ненулевой margin