1) In your Layout you can add div which will be rendered only when page is opened in Experience Editor. You can use this condition in your code -
You can then style this div to push content down so it's not overlapped by Ribbon.
2) When you are using
position: fixed or
Problem in this case is that The Experience Editor ribbon UI is actually presented from within an iframe, presumably to avoid conflicting styles or scripts. The (unfixed) page content ends up being pushed down because of an empty div element, called scCrossPiece, that is sized in sync with the iframe content.
However, because position: fixed elements are positioned based on absolute coordinates, they aren’t affected by scCrossPiece. The solution, therefore, is to detect changes to the scCrossPiece container and update the position of the header.
You can see scripts here https://gist.github.com/richardszalay/f8fe2c90f21132ad7fb7d26d71c1faf3 and more details in his blog post https://blog.richardszalay.com/2017/03/24/sitecore-experience-ribbon-header/
3) Another option would be to customized Sitecore CSS but I wouldn't go this direction as after upgrade or updating to next version of Sitecore this "hack" would not need to work.