Index: src/js/media/views/focus-manager.js
===================================================================
--- src/js/media/views/focus-manager.js	(revision 45565)
+++ src/js/media/views/focus-manager.js	(working copy)
@@ -16,6 +16,10 @@
 
 	/**
 	 * Gets all the tabbable elements.
+	 *
+	 * @since 5.3.0
+	 *
+	 * @returns {object} A jQuery collection of tabbable elements.
 	 */
 	getTabbables: function() {
 		// Skip the file input added by Plupload.
@@ -24,6 +28,10 @@
 
 	/**
 	 * Moves focus to the modal dialog.
+	 *
+	 * @since 3.5.0
+	 *
+	 * @returns {void}
 	 */
 	focus: function() {
 		this.$( '.media-modal' ).focus();
@@ -30,7 +38,13 @@
 	},
 
 	/**
-	 * @param {Object} event
+	 * Constrains navigation with the Tab key within the media view element.
+	 *
+	 * @since 4.0.0
+	 *
+	 * @param {Object} event A keydown jQuery event.
+	 *
+	 * @returns {void}
 	 */
 	constrainTabbing: function( event ) {
 		var tabbables;
@@ -50,8 +64,107 @@
 			tabbables.last().focus();
 			return false;
 		}
-	}
+	},
 
+	/**
+	 * Hides from assistive technologies all the body children except the
+	 * provided element and other elements that should not be hidden.
+	 *
+	 * The reason why we use `aria-hidden` is that `aria-modal="true"` is buggy
+	 * in Safari 11.1 and support is spotty in other browsers. In the future we
+	 * should consider to remove this helper function and only use `aria-modal="true"`.
+	 *
+	 * @since 5.3.0
+	 *
+	 * @param {object} visibleElement The jQuery object representing the element that should not be hidden.
+	 *
+	 * @returns {void}
+	 */
+	setAriaHiddenOnBodyChildren: function( visibleElement ) {
+		var bodyChildren,
+			self = this;
+
+		if ( this.isBodyAriaHidden ) {
+			return;
+		}
+
+		// Get all the body children.
+		bodyChildren = document.body.children;
+
+		// Loop through the body children and hide the ones that should be hidden.
+		_.each( bodyChildren, function( element ) {
+			// Don't hide the modal element.
+			if ( element === visibleElement[0] ) {
+				return;
+			}
+
+			// Determine the body children to hide.
+			if ( self.elementShouldBeHidden( element ) ) {
+				element.setAttribute( 'aria-hidden', 'true' );
+				// Store the hidden elements.
+				self.ariaHiddenElements.push( element );
+			}
+		} );
+
+		this.isBodyAriaHidden = true;
+	},
+
+	/**
+	 * Makes visible again to assistive technologies all body children
+	 * previously hidden and stored in this.ariaHiddenElements.
+	 *
+	 * @since 5.3.0
+	 *
+	 * @returns {void}
+	 */
+	removeAriaHiddenFromBodyChildren: function() {
+		_.each( this.ariaHiddenElements, function( element ) {
+			element.removeAttribute( 'aria-hidden' );
+		} );
+
+		this.ariaHiddenElements = [];
+		this.isBodyAriaHidden   = false;
+	},
+
+	/**
+	 * Determines if the passed element should not be hidden from assistive technologies.
+	 *
+	 * @since 5.3.0
+	 *
+	 * @param {object} element The DOM element that should be checked.
+	 *
+	 * @returns {boolean} Whether the element should not be hidden from assistive technologies.
+	 */
+	elementShouldBeHidden: function( element ) {
+		var role = element.getAttribute( 'role' ),
+			liveRegionsRoles = [ 'alert', 'status', 'log', 'marquee', 'timer' ];
+
+		/*
+		 * Don't hide scripts, elements that already have `aria-hidden`, and
+		 * ARIA live regions.
+		 */
+		return ! (
+			element.tagName === 'SCRIPT' ||
+			element.hasAttribute( 'aria-hidden' ) ||
+			element.hasAttribute( 'aria-live' ) ||
+			liveRegionsRoles.indexOf( role ) !== -1
+		);
+	},
+
+	/**
+	 * Whether the body children are hidden from assistive technologies.
+	 *
+	 * @since 5.3.0
+	 */
+	isBodyAriaHidden: false,
+
+	/**
+	 * Stores an array of DOM elements that should be hidden from assistive
+	 * technologies, for example when the media modal dialog opens.
+	 *
+	 * @since 5.3.0
+	 */
+	ariaHiddenElements: []
 });
 
 module.exports = FocusManager;
Index: src/js/media/views/modal.js
===================================================================
--- src/js/media/views/modal.js	(revision 45565)
+++ src/js/media/views/modal.js	(working copy)
@@ -117,6 +117,9 @@
 		// Set initial focus on the content instead of this view element, to avoid page scrolling.
 		this.$( '.media-modal' ).focus();
 
+		// Hide the page content from assistive technologies.
+		this.focusManager.setAriaHiddenOnBodyChildren( $el );
+
 		return this.propagate('open');
 	},
 
@@ -135,6 +138,12 @@
 		// Hide modal and remove restricted media modal tab focus once it's closed
 		this.$el.hide().undelegate( 'keydown' );
 
+		/*
+		 * Make visible again to assistive technologies all body children that
+		 * have been made hidden when the modal opened.
+		 */
+		this.focusManager.removeAriaHiddenFromBodyChildren();
+
 		// Move focus back in useful location once modal is closed.
 		if ( null !== this.clickedOpenerEl ) {
 			// Move focus back to the element that opened the modal.
Index: src/wp-includes/css/media-views.css
===================================================================
--- src/wp-includes/css/media-views.css	(revision 45565)
+++ src/wp-includes/css/media-views.css	(working copy)
@@ -542,7 +542,7 @@
 	right: 0;
 	bottom: 0;
 	margin: 0;
-	padding: 10px 0;
+	padding: 50px 0 10px;
 	background: #f3f3f3;
 	border-right-width: 1px;
 	border-right-style: solid;
@@ -2530,8 +2530,9 @@
 
 /* Landscape specific header override */
 @media screen and (max-height: 400px) {
-	.media-menu {
-		padding: 0;
+	.media-menu,
+	.media-frame:not(.hide-menu) .media-menu {
+		top: 44px;
 	}
 
 	.media-frame-router {
@@ -2552,6 +2553,14 @@
 	}
 }
 
+@media only screen and (min-width: 901px) and (max-height: 400px) {
+	.media-menu,
+	.media-frame:not(.hide-menu) .media-menu {
+		top: 0;
+		padding-top: 44px;
+	}
+}
+
 @media only screen and (max-width: 480px) {
 	.media-modal-close {
 		top: -5px;
@@ -2578,6 +2587,7 @@
 	.media-frame-router,
 	.media-frame:not(.hide-menu) .media-menu {
 		top: 40px;
+		padding-top: 0;
 	}
 
 	.media-frame-content {
Index: src/wp-includes/media-template.php
===================================================================
--- src/wp-includes/media-template.php	(revision 45565)
+++ src/wp-includes/media-template.php	(working copy)
@@ -177,8 +177,8 @@
 
 	<?php // Template for the media frame: used both in the media grid and in the media modal. ?>
 	<script type="text/html" id="tmpl-media-frame">
+		<div class="media-frame-title" id="media-frame-title"></div>
 		<div class="media-frame-menu"></div>
-		<div class="media-frame-title"></div>
 		<div class="media-frame-router"></div>
 		<div class="media-frame-content"></div>
 		<div class="media-frame-toolbar"></div>
@@ -187,11 +187,11 @@
 
 	<?php // Template for the media modal. ?>
 	<script type="text/html" id="tmpl-media-modal">
-		<div tabindex="0" class="<?php echo $class; ?>">
+		<div tabindex="0" class="<?php echo $class; ?>" role="dialog" aria-modal="true" aria-labelledby="media-frame-title">
 			<# if ( data.hasCloseButton ) { #>
 				<button type="button" class="media-modal-close"><span class="media-modal-icon"><span class="screen-reader-text"><?php _e( 'Close dialog' ); ?></span></span></button>
 			<# } #>
-			<div class="media-modal-content"></div>
+			<div class="media-modal-content" role="document"></div>
 		</div>
 		<div class="media-modal-backdrop"></div>
 	</script>
