1// .modal-open      - body class for killing the scroll
2// .modal           - container to scroll within
3// .modal-dialog    - positioning shell for the actual modal
4// .modal-content   - actual modal w/ bg and corners and stuff
5
6
7.modal-open {
8  // Kill the scroll on the body
9  overflow: hidden;
10
11  .modal {
12    overflow-x: hidden;
13    overflow-y: auto;
14  }
15}
16
17// Container that the modal scrolls within
18.modal {
19  position: fixed;
20  top: 0;
21  left: 0;
22  z-index: $zindex-modal;
23  display: none;
24  width: 100%;
25  height: 100%;
26  overflow: hidden;
27  // Prevent Chrome on Windows from adding a focus outline. For details, see
28  // https://github.com/twbs/bootstrap/pull/10951.
29  outline: 0;
30  // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
31  // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
32  // See also https://github.com/twbs/bootstrap/issues/17695
33}
34
35// Shell div to position the modal with bottom padding
36.modal-dialog {
37  position: relative;
38  width: auto;
39  margin: $modal-dialog-margin;
40  // allow clicks to pass through for custom click handling to close modal
41  pointer-events: none;
42
43  // When fading in the modal, animate it to slide down
44  .modal.fade & {
45    @include transition($modal-transition);
46    transform: $modal-fade-transform;
47  }
48  .modal.show & {
49    transform: $modal-show-transform;
50  }
51
52  // When trying to close, animate focus to scale
53  .modal.modal-static & {
54    transform: $modal-scale-transform;
55  }
56}
57
58.modal-dialog-scrollable {
59  display: flex; // IE10/11
60  display: -webkit-flex; // IE10/11
61  max-height: subtract(100%, $modal-dialog-margin * 2);
62
63  .modal-content {
64    max-height: subtract(100vh, $modal-dialog-margin * 2); // IE10/11
65    overflow: hidden;
66  }
67
68  .modal-header,
69  .modal-footer {
70    flex-shrink: 0;
71    -webkit-flex-shrink: 0;
72  }
73
74  .modal-body {
75    overflow-y: auto;
76  }
77}
78
79.modal-dialog-centered {
80  display: flex;
81  display: -webkit-flex;
82  align-items: center;
83  -webkit-align-items: center;
84  min-height: subtract(100%, $modal-dialog-margin * 2);
85
86  // Ensure `modal-dialog-centered` extends the full height of the view (IE10/11)
87  &::before {
88    display: block; // IE10
89    height: subtract(100vh, $modal-dialog-margin * 2);
90    height: min-content; // Reset height to 0 except on IE
91    height: -webkit-min-content; // Reset height to 0 except on IE
92    height: -moz-min-content; // Reset height to 0 except on IE
93    height: -ms-min-content; // Reset height to 0 except on IE
94    height: -o-min-content; // Reset height to 0 except on IE
95    content: "";
96  }
97
98  // Ensure `.modal-body` shows scrollbar (IE10/11)
99  &.modal-dialog-scrollable {
100    flex-direction: column;
101    -webkit-flex-direction: column;
102    justify-content: center;
103    -webkit-justify-content: center;
104    height: 100%;
105
106    .modal-content {
107      max-height: none;
108    }
109
110    &::before {
111      content: none;
112    }
113  }
114}
115
116// Actual modal
117.modal-content {
118  position: relative;
119  display: flex;
120  display: -webkit-flex;
121  flex-direction: column;
122  -webkit-flex-direction: column;
123  width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
124  // counteract the pointer-events: none; in the .modal-dialog
125  color: $modal-content-color;
126  pointer-events: auto;
127  background-color: $modal-content-bg;
128  background-clip: padding-box;
129  border: $modal-content-border-width solid $modal-content-border-color;
130  @include border-radius($modal-content-border-radius);
131  @include box-shadow($modal-content-box-shadow-xs);
132  // Remove focus outline from opened modal
133  outline: 0;
134}
135
136// Modal background
137.modal-backdrop {
138  position: fixed;
139  top: 0;
140  left: 0;
141  z-index: $zindex-modal-backdrop;
142  width: 100vw;
143  height: 100vh;
144  background-color: $modal-backdrop-bg;
145
146  // Fade for backdrop
147  &.fade { opacity: 0; }
148  &.show { opacity: $modal-backdrop-opacity; }
149}
150
151// Modal header
152// Top section of the modal w/ title and dismiss
153.modal-header {
154  display: flex;
155  display: -webkit-flex;
156  align-items: flex-start; // so the close btn always stays on the upper right corner
157  -webkit-align-items: flex-start; // so the close btn always stays on the upper right corner
158  justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends
159  -webkit-justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends
160  padding: $modal-header-padding;
161  border-bottom: $modal-header-border-width solid $modal-header-border-color;
162  @include border-top-radius($modal-content-inner-border-radius);
163
164  .close {
165    padding: $modal-header-padding;
166    // auto on the left force icon to the right even when there is no .modal-title
167    margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto;
168  }
169}
170
171// Title text within header
172.modal-title {
173  margin-bottom: 0;
174  line-height: $modal-title-line-height;
175}
176
177// Modal body
178// Where all modal content resides (sibling of .modal-header and .modal-footer)
179.modal-body {
180  position: relative;
181  // Enable `flex-grow: 1` so that the body take up as much space as possible
182  // when there should be a fixed height on `.modal-dialog`.
183  flex: 1 1 auto;
184  -webkit-flex: 1 1 auto;
185  padding: $modal-inner-padding;
186}
187
188// Footer (for actions)
189.modal-footer {
190  display: flex;
191  display: -webkit-flex;
192  flex-wrap: wrap;
193  -webkit-flex-wrap: wrap;
194  align-items: center; // vertically center
195  -webkit-align-items: center; // vertically center
196  justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
197  -webkit-justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
198  padding: $modal-inner-padding - $modal-footer-margin-between / 2;
199  border-top: $modal-footer-border-width solid $modal-footer-border-color;
200  @include border-bottom-radius($modal-content-inner-border-radius);
201
202  // Place margin between footer elements
203  // This solution is far from ideal because of the universal selector usage,
204  // but is needed to fix https://github.com/twbs/bootstrap/issues/24800
205  > * {
206    margin: $modal-footer-margin-between / 2;
207  }
208}
209
210// Measure scrollbar width for padding body during modal show/hide
211.modal-scrollbar-measure {
212  position: absolute;
213  top: -9999px;
214  width: 50px;
215  height: 50px;
216  overflow: scroll;
217}
218
219// Scale up the modal
220@include media-breakpoint-up(sm) {
221  // Automatically set modal's width for larger viewports
222  .modal-dialog {
223    max-width: $modal-md;
224    margin: $modal-dialog-margin-y-sm-up auto;
225  }
226
227  .modal-dialog-scrollable {
228    max-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
229
230    .modal-content {
231      max-height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);
232    }
233  }
234
235  .modal-dialog-centered {
236    min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
237
238    &::before {
239      height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);
240      height: min-content;
241      height: -webkit-min-content;
242      height: -moz-min-content;
243      height: -ms-min-content;
244      height: -o-min-content;
245    }
246  }
247
248  .modal-content {
249    @include box-shadow($modal-content-box-shadow-sm-up);
250  }
251
252  .modal-sm { max-width: $modal-sm; }
253}
254
255@include media-breakpoint-up(lg) {
256  .modal-lg,
257  .modal-xl {
258    max-width: $modal-lg;
259  }
260}
261
262@include media-breakpoint-up(xl) {
263  .modal-xl { max-width: $modal-xl; }
264}
265