I think it is because margin collapsing. You will got different top in case a child node of the one you call getBoundingClientRect() has margin-top defined. For some reason Safari includes it when other browsers don't.
top
getBoundingClientRect()
margin-top