Riguarda il modo in cui i margini si sovrappongono e il modo in cui determinate proprietà li costringono a essere contenuti. Se posizioni due div in una pagina, entrambi con margini di 100 px, la spaziatura tra quelle div sarà di 100 px. Non 200 px. Questo perché i margini possono sovrapporsi ad altri margini. È così che funzionano i margini. È una buona cosa.
Ma se si inserisce un div all'interno di un altro div, entrambi con margini, anche quei margini si sovrappongono. I margini dell'elemento figlio si sovrappongono a quelli del genitore.
Tuttavia, alcune proprietà - border, come hai scoperto, ma anche padding e overflow - costringono il genitore a contenere i margini del figlio invece di sovrapporlo.
Sono sicuro che qualcuno può dare una spiegazione più tecnica, ma è così che penso a cosa sta succedendo.
Ecco un caso di test semplificato: http://jsbin.com/ukodus/2/
Rimuovere il //
prima di qualsiasi delle linee di CSS per vedere l'effetto.
"Questo comportamento è chiamato collasso margine. Solo all'inizio/margini inferiore crollerà, non sinistra/destra". - @cimmanon
Può essere un problema con jsbin .. o sta succedendo anche nel codice di test? –
In ambiente pulito: http://jsbin.com/ibowed/1/quiet -> F12, spuntare il bordo sul div di classe .top. Stesso. – zsitro
+1; molto strano. Viene innescato dal negativo 'margin-top' sul div interno; rimuovilo dall'equazione e alternando il bordo ora funziona come previsto. Per il momento non posso spiegare perché lo stile dell'elemento interno debba avere questo effetto sull'elemento esterno. – Spudley