Screen Size Warning Modal

Hello everyone, I am working on a website that will be used almost exclusively on ipads, laptops and desktops. I want to at least warn people who go to it on a phone that it's not optimized for mobile devices. I watched a video from Kevin and another one that both used a dialog element when an open button was pressed. I want my warning modal/popup to come up on load or seconds after it but only for users on a phone. So I have media queries setting it to visible or not visible depending on the screen size. I wasn't able to do it with display none/flex because it was messing with my javascript. Now it's fine on mobile, but on larger devices, the invisible modal is blocking me from clicking any links on the nav bar. I'm not sure of the best way to do this, especially in an accessible way. I know I can use z-index with display: grid, but as I mentioned, display was messing with the javascript to open/close it. Here's a codepen where I reproduced the issue. https://codepen.io/MathematiCode/pen/PorpqGZ You can see the links can't be clicked at larger screen widths because the invisible modal is in the way.
9 Replies
clevermissfox
clevermissfox3mo ago
Can't look at the codepen at the moment but make sure any styles that are applied to the dialog are when it's open
css dialog[open]
css dialog[open]
A common mistake is people override the display property and then it doesn't close because the dialog is set to display grid or flex when those should only be applied when it has the open attr. If it's not open it should be it's default display: none which will not impede links or anything on your page
Julianna
Julianna3mo ago
Ooh I will check in a bit. I wasn’t using the open attribute at all I was using modal.showModal() and modal.close() just like Kevin did in his video.
clevermissfox
clevermissfox3mo ago
Pull up your dev tools and find the dialog. When using those methods, it adds and removes the open attr on the dialog element when triggered. So for your css, you style the dialog to apply the styles when it has the [open] attr. Otherwise when you call modal.close() the styles you've defined just on dialog (as opposed to dialog[open]) will be overwriting the default styles it should have when it's :not(dialog[open])
Julianna
Julianna3mo ago
Okay that sort of worked for a minute but I broke it again. I put display:none as default and display: flex on .modal[open]. But in my javascript, I have it opening on load and only closing when the user closes it, so at larger screen sizes it will be open but invisible. I'm not sure if I should add to my javascript to only open if the screen is a certain size or if there's a better way to do this whole thing.
clevermissfox
clevermissfox3mo ago
Display:none is the default styles. I would def not have it opening on load if it won’t be used. I would use a media query and a resize event listener
const mediaQuery = window.matchMedia('(max-width: 600px)');

function handleScreenChange(e) {
if (e.matches) {
// Screen width is 600px or less
yourFunction();
}
}

function handleResize() {
if (window.innerWidth <= 600) {
yourFunction();
}
}

mediaQuery.addListener(handleScreenChange);
handleScreenChange(mediaQuery);

window.addEventListener('resize', handleResize);

function yourFunction() {
// Your code to run when screen width is 600px or less
console.log("Screen width is 600px or less");
}
const mediaQuery = window.matchMedia('(max-width: 600px)');

function handleScreenChange(e) {
if (e.matches) {
// Screen width is 600px or less
yourFunction();
}
}

function handleResize() {
if (window.innerWidth <= 600) {
yourFunction();
}
}

mediaQuery.addListener(handleScreenChange);
handleScreenChange(mediaQuery);

window.addEventListener('resize', handleResize);

function yourFunction() {
// Your code to run when screen width is 600px or less
console.log("Screen width is 600px or less");
}
Julianna
Julianna3mo ago
Thank you! This worked, I don’t understand it at all but I will ask my tutor. I appreciate your help and patience!
Felix the Cat
Felix the Cat3mo ago
IGNORE THIS add this under <body>: <meta name="viewport" content="width=device-width, initial scale=1.0"> nvm u got help My bad
clevermissfox
clevermissfox3mo ago
So the dialog is a very unique element. It lives on the very top layer of the page, it has the highest z-index. (Popover also lives on this top layer and of you look in dev tools on chrome, they both have a tag next them indicating this) By default the dialog element has a base style of display:none; when we open it with dialog.show() or dialog.showModal(), instead of adding a class to override the default styles like some developers will do when they make their own popups, the dialog gets an attribute added called [open]. When we close with dialog.close() , that open attribute is taken away . So toggling this open attribute is what adjusts the styles including the display property. So by default , dialog has a display: none; this strips the dialog from the visible page and the accessibility tree . when we style our dialog, we want to make sure our styles are only applied to the dialog when it’s visible and has that open attribute. Otherwise we are overriding the styles when it’s invisible. For example, Adding the selector
dialog {
display:grid; /*❌*/
}
dialog {
display:grid; /*❌*/
}
Now the default display:none has been overwritten and so even when we invoke dialog.close() and the open attribute is toggled off, the display property is no longer display:none; we’ve made it display: grid even when it’s closed with this selector. That’s why we want to make sure we only apply styles to the element when it has the open attribute
dialog[open] {display:grid;} /* ✅ */
dialog[open] {display:grid;} /* ✅ */
No description
clevermissfox
clevermissfox3mo ago
The freedom to target the dialogs state is helpful for applying other styles to other elements too. We can basically say something like “if the dialog is closed, I want to do x” a non practical example would be to style the button that opens the dialog to look functional if the dialog is closed , otherwise (or else) look disabled
:not(:has(dialog[open])) .button {
opacity:1;
cursor:pointer;
}

:has(dialog[open]) .button {
opacity: 0.6;
cursor: not-allowed;
}
:not(:has(dialog[open])) .button {
opacity:1;
cursor:pointer;
}

:has(dialog[open]) .button {
opacity: 0.6;
cursor: not-allowed;
}

Definitely ask your tutor so they can show you some visual examples in real time but hopefully that makes the flow more clear .
Want results from more Discord servers?
Add your server