diff --git a/lti_consumer/lti_consumer.py b/lti_consumer/lti_consumer.py
index 84e8430d60765f355b5ed7543cb1df84de3b6513..5140862f5b630171974fc6449402869400e1a165 100644
--- a/lti_consumer/lti_consumer.py
+++ b/lti_consumer/lti_consumer.py
@@ -339,21 +339,21 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
     modal_height = Integer(
         display_name="Modal Height",
         help=(
-            "Enter the desired pixel height of the modal overlay which will contain the LTI tool. "
+            "Enter the desired viewport percentage height of the modal overlay which will contain the LTI tool. "
             "This setting is only used when Hide External Tool is set to False and "
             "LTI Launch Target is set to Modal."
         ),
-        default=405,
+        default=80,
         scope=Scope.settings
     )
     modal_width = Integer(
         display_name="Modal Width",
         help=(
-            "Enter the desired pixel width of the modal overlay which will contain the LTI tool. "
+            "Enter the desired viewport percentage width of the modal overlay which will contain the LTI tool. "
             "This setting is only used when Hide External Tool is set to False and "
             "LTI Launch Target is set to Modal."
         ),
-        default=720,
+        default=80,
         scope=Scope.settings
     )
     has_score = Boolean(
@@ -834,7 +834,22 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
             'ask_to_send_email': self.ask_to_send_email,
             'button_text': self.button_text,
             'inline_height': self.inline_height,
-            'modal_height': self.modal_height,
+            'modal_vertical_offset': self._get_modal_position_offset(self.modal_height),
+            'modal_horizontal_offset': self._get_modal_position_offset(self.modal_width),
             'modal_width': self.modal_width,
             'accept_grades_past_due': self.accept_grades_past_due,
         }
+
+    def _get_modal_position_offset(self, viewport_percentage):
+        """
+        Returns the css position offset to apply to the modal window
+        element when launch_target is modal. This enables us to position
+        the modal window as a percentage of the viewport dimensions.
+
+        Arguments:
+            viewport_percentage (int): The percentage of the viewport that the modal should occupy
+
+        Returns:
+            float: The css position offset to apply to the modal window
+        """
+        return (100 - viewport_percentage) / 2
diff --git a/lti_consumer/static/css/student.css b/lti_consumer/static/css/student.css
index 68a24f9b0516bd09e1e2c30db0717afcaac259f0..9cb835c6095a48985bb221256509f5e6df8b24db 100644
--- a/lti_consumer/static/css/student.css
+++ b/lti_consumer/static/css/student.css
@@ -1 +1 @@
-.xblock-student_view.xblock-student_view-lti_consumer h2.problem-header{display:inline-block}.xblock-student_view.xblock-student_view-lti_consumer div.problem-progress{display:inline-block;padding-left:5px;color:#666;font-weight:100;font-size:1em}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer{margin:0 auto}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer .wrapper-lti-link{font-size:14px;background-color:#f6f6f6;padding:20px}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer .wrapper-lti-link .lti-link{margin-bottom:0;text-align:right}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer .wrapper-lti-link .lti-link button{font-size:13px;line-height:20.72px}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer .lti-modal{top:80px !important}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer .lti-modal .inner-wrapper{height:100%;padding:0 0 0 0}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer form.ltiLaunchForm{display:none}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer iframe.ltiLaunchFrame{width:100%;height:100%;display:block;border:0px}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer h4.problem-feedback-label{font-weight:100;font-size:1em;font-family:"Source Sans", "Open Sans", Verdana, Geneva, sans-serif, sans-serif}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer div.problem-feedback{margin-top:5px;margin-bottom:5px}.lean-overlay{background:transparent;background-image:radial-gradient(circle at 50% 30%, rgba(0,0,0,0.4), rgba(0,0,0,0.6));display:none;height:100%;left:0;position:fixed;top:0;width:100%;z-index:100}
+.xblock-student_view.xblock-student_view-lti_consumer h2.problem-header{display:inline-block}.xblock-student_view.xblock-student_view-lti_consumer div.problem-progress{display:inline-block;padding-left:5px;color:#666;font-weight:100;font-size:1em}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer{margin:0 auto}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer .wrapper-lti-link{font-size:14px;background-color:#f6f6f6;padding:20px}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer .wrapper-lti-link .lti-link{margin-bottom:0;text-align:right}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer .wrapper-lti-link .lti-link button{font-size:13px;line-height:20.72px}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer .lti-modal{position:fixed;opacity:0;z-index:11000;box-sizing:border-box;margin-left:0;height:auto;padding:8px;border-radius:3px;box-shadow:0 0 5px 0 rgba(0,0,0,0.4);background:#464646;color:#3c3c3c}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer .lti-modal .close-modal{display:inline-block;position:absolute;right:2px;top:0px;z-index:100;cursor:pointer;padding:10px;background:transparent;border:none;text-align:center}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer .lti-modal .close-modal .fa{font:normal normal normal 14px/1 FontAwesome;font-size:inherit}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer .lti-modal .inner-wrapper{height:100%;padding:0 0 0 0}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer form.ltiLaunchForm{display:none}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer iframe.ltiLaunchFrame{width:100%;height:100%;display:block;border:0px}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer h4.problem-feedback-label{font-weight:100;font-size:1em;font-family:"Source Sans", "Open Sans", Verdana, Geneva, sans-serif, sans-serif}.xblock-student_view.xblock-student_view-lti_consumer div.lti_consumer div.problem-feedback{margin-top:5px;margin-bottom:5px}.lean-overlay{background:transparent;background-image:radial-gradient(circle at 50% 30%, rgba(0,0,0,0.4), rgba(0,0,0,0.6));display:none;height:100%;left:0;position:fixed;top:0;width:100%;z-index:100}
diff --git a/lti_consumer/static/js/xblock_lti_consumer.js b/lti_consumer/static/js/xblock_lti_consumer.js
index 041343561f15eb681036374a41e7d2d236c3a9a4..8a8070593eae3d110df2903f081fe210dd382d86 100644
--- a/lti_consumer/static/js/xblock_lti_consumer.js
+++ b/lti_consumer/static/js/xblock_lti_consumer.js
@@ -27,16 +27,11 @@ function LtiConsumerXBlock(runtime, element) {
                         $("#" + overlay_id).css({"display": "block", opacity: 0});
                         $("#" + overlay_id).fadeTo(200, o.overlay);
                         $(modal_id).css({
-                            "display": "block",
-                            "position": "fixed",
-                            "opacity": 0,
-                            "z-index": 11000,
-                            "left": 50 + "%",
-                            "margin-left": -(modal_width / 2) + "px",
-                            "top": o.top + "px"
+                            "display": "block"
                         });
                         $(modal_id).fadeTo(200, 1);
                         $(modal_id).attr('aria-hidden', false);
+                        $('body').css('overflow', 'hidden');
 
                         e.preventDefault();
 
@@ -65,6 +60,7 @@ function LtiConsumerXBlock(runtime, element) {
                     $("#" + overlay_id).fadeOut(200);
                     $(modal_id).css({"display": "none"});
                     $(modal_id).attr('aria-hidden', true);
+                    $('body').css('overflow', 'auto');
                     $trigger.focus();
                 }
             }
diff --git a/lti_consumer/static/sass/student.scss b/lti_consumer/static/sass/student.scss
index 0d96c38bf819f2b782927b0a59421f68a1b488a4..88df54431ac4ab7342c97f05abc42c984f46aa8d 100644
--- a/lti_consumer/static/sass/student.scss
+++ b/lti_consumer/static/sass/student.scss
@@ -31,7 +31,35 @@
         }
 
         .lti-modal {
-            top: 80px !important;
+            position: fixed;
+            opacity: 0;
+            z-index: 11000;
+            box-sizing: border-box;
+            margin-left: 0;
+            height: auto;
+            padding: 8px;
+            border-radius: 3px;
+            box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.4);
+            background: #464646;
+            color: #3c3c3c;
+
+            .close-modal {
+                display: inline-block;
+                position: absolute;
+                right: 2px;
+                top: 0px;
+                z-index: 100;
+                cursor: pointer;
+                padding: 10px;
+                background: transparent;
+                border: none;
+                text-align: center;
+
+                .fa {
+                    font: normal normal normal 14px/1 FontAwesome;
+                    font-size: inherit;
+                }
+            }
 
             .inner-wrapper {
                 height: 100%;
diff --git a/lti_consumer/templates/html/student.html b/lti_consumer/templates/html/student.html
index 11a67995b3bd9c4f81ece446e9e85feeda8f0b67..421a42c314fbfa4dd39509e6ce871852fb921f17 100644
--- a/lti_consumer/templates/html/student.html
+++ b/lti_consumer/templates/html/student.html
@@ -50,7 +50,7 @@
             id="${element_id}-lti-modal"
             class="modal lti-modal"
             aria-hidden="true"
-            style="width:${modal_width}px; height:${modal_height}px;"
+            style="width:${modal_width}%; left:${modal_horizontal_offset}%; top:${modal_vertical_offset}%; bottom:${modal_vertical_offset}%;"
         >
             <div class="inner-wrapper" role="dialog">
                 <button class="close-modal">
diff --git a/lti_consumer/tests/unit/test_lti_consumer.py b/lti_consumer/tests/unit/test_lti_consumer.py
index 652e59fce948301bab9df1cdc9c6dab1c643faa1..fa2ebe2ebcca3520891a7a0e14f97fc9c7604bc0 100644
--- a/lti_consumer/tests/unit/test_lti_consumer.py
+++ b/lti_consumer/tests/unit/test_lti_consumer.py
@@ -671,9 +671,25 @@ class TestGetContext(TestLtiConsumerXBlock):
         context_keys = (
             'launch_url', 'element_id', 'element_class', 'launch_target', 'display_name', 'form_url', 'hide_launch',
             'has_score', 'weight', 'module_score', 'comment', 'description', 'ask_to_send_username',
-            'ask_to_send_email', 'button_text', 'modal_height', 'modal_width', 'accept_grades_past_due'
+            'ask_to_send_email', 'button_text', 'modal_vertical_offset', 'modal_horizontal_offset', 'modal_width',
+            'accept_grades_past_due'
         )
         context = self.xblock._get_context_for_template()  # pylint: disable=protected-access
 
         for key in context_keys:
             self.assertIn(key, context)
+
+
+class TestGetModalPositionOffset(TestLtiConsumerXBlock):
+    """
+    Unit tests for LtiConsumerXBlock._get_modal_position_offset()
+    """
+
+    def test_offset_calculation(self):
+        """
+        Test `_get_modal_position_offset` returns the correct value
+        """
+        offset = self.xblock._get_modal_position_offset(self.xblock.modal_height)  # pylint: disable=protected-access
+
+        # modal_height defaults to 80, so offset should equal 10
+        self.assertEqual(offset, 10)
diff --git a/setup.py b/setup.py
index 3622d3d8c6b7c1c9c53baa9dfe4288608bcf8c74..8a286e51f436e39dc674240087cf63d0ccefcd84 100644
--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@ def package_data(pkg, roots):
 
 setup(
     name='lti_consumer-xblock',
-    version='1.0.2',
+    version='1.0.3',
     description='This XBlock implements the consumer side of the LTI specification.',
     packages=[
         'lti_consumer',