diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index 402d558c4cb..953d98c20d4 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -206,7 +206,7 @@ export default class Status extends ImmutablePureComponent {
         );
       } else {
         media = (
-          <Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery} >
+          <Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery}>
             {Component => <Component media={status.get('media_attachments')} sensitive={status.get('sensitive')} height={110} onOpenMedia={this.props.onOpenMedia} />}
           </Bundle>
         );
diff --git a/app/javascript/mastodon/containers/timeline_container.js b/app/javascript/mastodon/containers/timeline_container.js
index 8719bb5c9ee..a1a4bd024bc 100644
--- a/app/javascript/mastodon/containers/timeline_container.js
+++ b/app/javascript/mastodon/containers/timeline_container.js
@@ -1,4 +1,5 @@
-import React from 'react';
+import React, { Fragment } from 'react';
+import ReactDOM from 'react-dom';
 import { Provider } from 'react-redux';
 import PropTypes from 'prop-types';
 import configureStore from '../store/configureStore';
@@ -8,6 +9,7 @@ import { getLocale } from '../locales';
 import PublicTimeline from '../features/standalone/public_timeline';
 import CommunityTimeline from '../features/standalone/community_timeline';
 import HashtagTimeline from '../features/standalone/hashtag_timeline';
+import ModalContainer from '../features/ui/containers/modal_container';
 import initialState from '../initial_state';
 
 const { localeData, messages } = getLocale();
@@ -47,7 +49,13 @@ export default class TimelineContainer extends React.PureComponent {
     return (
       <IntlProvider locale={locale} messages={messages}>
         <Provider store={store}>
-          {timeline}
+          <Fragment>
+            {timeline}
+            {ReactDOM.createPortal(
+              <ModalContainer />,
+              document.getElementById('modal-container'),
+            )}
+          </Fragment>
         </Provider>
       </IntlProvider>
     );
diff --git a/app/javascript/mastodon/features/ui/components/modal_root.js b/app/javascript/mastodon/features/ui/components/modal_root.js
index 4185cba3220..a334318ce56 100644
--- a/app/javascript/mastodon/features/ui/components/modal_root.js
+++ b/app/javascript/mastodon/features/ui/components/modal_root.js
@@ -40,6 +40,17 @@ export default class ModalRoot extends React.PureComponent {
     onClose: PropTypes.func.isRequired,
   };
 
+  getSnapshotBeforeUpdate () {
+    const visible = !!this.props.type;
+    return {
+      overflowY: visible ? 'hidden' : null,
+    };
+  }
+
+  componentDidUpdate (prevProps, prevState, { overflowY }) {
+    document.body.style.overflowY = overflowY;
+  }
+
   renderLoading = modalId => () => {
     return ['MEDIA', 'VIDEO', 'BOOST', 'CONFIRM', 'ACTIONS'].indexOf(modalId) === -1 ? <ModalLoading /> : null;
   }
diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml
index 870dafdf520..fba46d54b74 100644
--- a/app/views/about/show.html.haml
+++ b/app/views/about/show.html.haml
@@ -142,3 +142,5 @@
             %p
               = link_to t('about.source_code'), @instance_presenter.source_url
               = " (#{@instance_presenter.version_number})"
+
+#modal-container
diff --git a/app/views/tags/show.html.haml b/app/views/tags/show.html.haml
index f8cdc995231..d46f3599926 100644
--- a/app/views/tags/show.html.haml
+++ b/app/views/tags/show.html.haml
@@ -34,3 +34,5 @@
               %p= t 'about.about_mastodon_html'
 
               = render 'features'
+
+#modal-container