I have an MUI Dialog, in which its height varies due to it being of a list that is filtered by the user. It ends up being annoying because the the dialog "jumps around" the screen trying to maintain it's center position as it grows and shrinks. This is what it looks like:
A simple solution for this particular issue would be simply to unset alignItems
from the dialogPaper
through the classes property. Something like this:
const useStyles = makeStyles((theme) => ({
pivottedDialog: {
alignItems: 'unset',
...
},
}));
const MyDialog = () => (
<Dialog
{...otherProps}
classes={{
scrollPaper: classes.pivottedDialog
}}
>
...
</Dialog>
)
This however, causes it to lose its centered positioning on the screen, when I do still need it to be centered (in reference to the dialog with the full list, without anything being filtered). I would like its starting point to be the same as the unchanged dialog, on all applicable screen sizes (above 600px of width)
How could I get this done?
I've tried to play around with the positioning and top
property on the pivottedDialog
class, but it changes depending on the screen size. This needs to be responsive and centered on all screen sizes above 600px width.
I made a sample app with the two dialogs, that can be played around with here: https://codesandbox.io/s/crazy-tesla-emc8m?file=/src/App.js
In this case. since the DialogContent
height changes based upon the filter, I'd recommend setting a height and width for the Dialog
and a height for the DialogContent
.
Working Demo:
Why is the content shifting? The problem comes from the fact that the Dialog uses a flex-blox (display: flex
) that justifies the content to the center (justify-content: center
) vertically (main-axis) and align items to the center (align-items: center
) horizontally (cross-axis) in relation to the view port. This makes the center of the screen and the center of the Dialog box the reference points for how to align content.
Are there any work-arounds? Yes, but they require a custom layout/custom modal. With a flexbox, you'd need something like the demo below to achieve a centered modal:
What this example demo does is creates a column with three rows and anchors the modal to the top of the second row:
___________________________
| |
| Empty Row |
| · 25% of view |
|___________________________|
| |------ Modal ------| |
| | · Top anchored | |
| | · Expandable † | |
| | · 50% of view | |
| |___________________| |
| |
| |
| |
|___________________________|
| |
| Empty Row |
| · 25% of view |
|___________________________|
† Modal can only expand to the max height of the row it resides within
This allows the modal to shrink and grow while maintaining a vertical and horizontal center. The center won't be the center of the row because that would require the modal to shift vertically to compensate for the height change (which brings you back to the previous problem of content shifting).
The disadvantages to this approach are that:
The advantages to this approach are that:
You have more fine control over how to divide your view port (25%/50%/25% or 33.33%/33.33%/33.33% or 20%/60%/20%, ...etc)
The modal shrinks and grows with the view port and with the number of filtered items:
Which would be the best approach? The easiest and recommended solution is to just set a height/width on the modal. Another solution would be to use a filterable dropdown select list that won't affect the modal height.