6 ms·
A couple CSS tricks for HTML Dialog elements
- vintagedave 2y agoThe trick to prevent scrolling by setting overflow: hidden unfortunately results in visual page jumping for me. The reason is I have macOS set up to always show scroll bars, instead of hiding them. At least one browser (I forget which, but I test on Safari, Firefox and Chrome) doesn’t have a disabled scroll bar but removes it altogether. This makes the page wider and causes it to reflow and move. Does anyone know how to keep the scroll bar onscreen, just not enabled?
- KTibow 2y agoWebsite authors can set a scrollbar gutter.
- dsmmcken 2y agoscrollbar-gutter: stable; to those unfamiliar. https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-gutter#stable https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-g...
- andrewmcwatters 2y agoMan, this makes me feel old.
- culi 2y agoThis is only recently supported by all major browsers thanks to the interop efforts. pre-2024 browser versions will not support this
- andrewmcwatters 2y agoIt's been a while since I've tested this, but an explicit overflow-y: scroll used to keep the scrollbar there, so that when you needed to change the property, the user-agent controls wouldn't pop in or out.
- badlibrarian 2y agoyes, "html { overflow-y: scroll }" works.
- rado 2y agoFreezing the page isn't so simple, as overflow: hidden messes up things like the sticky header on that page. I had so much trouble with it, I decided to just let users scroll and hide the modal during scrolling: https://radogado.github.io/n-modal/ https://radogado.github.io/n-modal/
- deleted 2y ago[deleted]
- starikovs 2y agoThanks for the article! I remember I had a hard time trying to stretch dialog to full screen for mobile devices, but it actually didn't want to work. The code was something like this: dialog { position: absolute; top: 10px; right: 10px; bottom: 10px; left: 10px; }
- askew 2y agoYou can shorthand the last four declarations with a single `inset: 10px;` (or maybe `inset: .625rem;`?
- starikovs 2y agoThat's cool, actually I didn't know about this one :)
- skgough 2y agothis is most likely due to the absolute positioning. position: absolute will use the top-left corner of the closest ancestor that is "positioned" as the origin for it's layout [1]. If you want that origin to be the top-left corner of the viewport, use position: fixed. [1] https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_...
- Lvl999Noob 2y agoIn addition to `position: fixed`, shouldn't it be top, left, height, width, instead of top, left, bottom, right? In the second case, it would follow the top and left instructions then take the necessary amount of space, ignoring right and bottom?
- nicoburns 2y agoFor absolutely positioned elements, if you set all four sides then the height and width will be automatically computed.
- simonw 2y agoThis is a neat piece of modern CSS: body:has(dialog[open]) { overflow: hidden; } https://caniuse.com/css-has https://caniuse.com/css-has confirms the has() selector has had widespread browser support since December 2023.
- no_wizard 2y agoInert should be used instead of overflow. Achieves the same thing but is also compliant with accessibility in a way overflow isn’t
- todotask 2y agoI still can see my scrollbar and scroll with inert?
- no_wizard 2y agoIts intended to stop interaction[0] of background elements. It can be used as part of the solution to stop the background scrolling. Per MDN When implementing modal dialogs, everything other than the <dialog> and its contents should be rendered inert using the inert attribute.[1] `body[inert] { overflow: hidden; }` This would be better, and is what I was getting at. I can't edit the other comment unfortunately. [0]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inert https://developer.mozilla.org/en-US/docs/Web/HTML/Global_att... [1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog https://developer.mozilla.org/en-US/docs/Web/HTML/Element/di...
- extra88 2y agoYour original message was "Inert should be used instead of overflow" which is incorrect because `inert` doesn't affect scrolling of the viewport. Your CSS rule example is a good way to demonstrate using the presence of an `inert` attribute on the body to determine when `overflow: hidden` should be applied to the body. That section of the MDN article is somewhat confusing but if the dialog is opened using the `.showModal()` method, there's no need to add an `inert` attribute yourself, the browser automatically makes the rest of the page inert. If a <dialog> that's meant to be modal is opened not using `.showModal()`, say by making it a `popover` and the `popovertarget` of a button, then you might set `inert` yourself (and remove it when the <dialog> is closed). However, you can't simply do <body inert> if that <dialog> is inside the <body> because then the dialog itself would be inert.
- hk1337 2y agodatalist is one I stumbled upon and blew me away. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist https://developer.mozilla.org/en-US/docs/Web/HTML/Element/da... It's not a replacement for select as you still need an input to tie it to but it seems to handle filtering a list of options nicely. Also, if you have two selects with the same list in it, you can do it once with datalist and have two inputs, say a list of clients with client_a and client_b for inputs. I don't quite care for how it displays the value, like if you put the ID as the value and the client name in the option element, you can filter by the ID or the name but the input will show the ID only.
- bob1029 2y agoI've tried using datalist with text inputs and it never quite worked out from a UX perspective. Users would always complain about weird quirks with how it populates & clears values. A normal <select> element with an "Other" option + conditional input element is much more predictable.
- hk1337 2y agoYeah, for autocomplete it has a weird UX feel to it. Some of the other examples like using it with the slider and the color picker seem like they're useful.
- stronglikedan 2y agoIt looks like the UI would clash with the browser's autofill recommendations.
- lelandfe 2y agoMy frown continues to deepen at Apple's UI backslide as they crib more and more junk from iOS/iPadOS. I'm on Sonoma 14.5, and this is Safari 17.5. macOS Safari's <select>: https://imgur.com/a/05YWDCc https://imgur.com/a/05YWDCc macOS Safari's <datalist>: https://imgur.com/a/4f3JwuA https://imgur.com/a/4f3JwuA There are SO, SO, SO many things wrong with Safari's datalist element here. Esc doesn't close it (close from keyboard by switching tabs...). There's no hover effect on the options. The active background color is more saturated than the system's accent color (typical for iPadOS/Catalyst junk). There's no left/right margin, and no border radius, on the options. Option text isn't vertically centered. The font is different (it seems differently aliased? Perhaps just larger). The datalist element itself lacks the same border-radius of select. On select elements, selection does not wrap (down arrow with the last option active); on datalist it does. Here's an egregious one - when you zoom in with Cmd-+ a few times, this is how the <select> element looks: https://imgur.com/a/Vpu536j https://imgur.com/a/Vpu536j And this is <datalist>: https://imgur.com/a/JrfXLW9 https://imgur.com/a/JrfXLW9 Argh! I used to revere Apple for sweating the details. Their UI/UX quality inspired me to become a frontend dev. Today, they ship things that wouldn't pass Q/A at my worst jobs.
- Alifatisk 2y agoA demo of each trick would be nice to see
- dimaor 2y agoIs it weird that I expected the post to actually have running examples?
- extra88 2y agoFrom the article: > If you want to see a decent quick example of them in action, you can check out my game Jumblie and click the Settings gear button at the top. It has the backdrop filter but it doesn't prevent page scrolling. BTW, MDN's data on Safari's support for the unprefixed `backdrop-filter` property is wrong, it still sometimes requires using `-webkit-backdrop-filter` (works in iOS Safari 18.2.1, doesn't work in Safari 18.2 on macOS 14.7.1).
- dimaor 2y agoI have read the article, and saw the link, I simply thought it is so simple to actually add an example since the post itself is a web page.
- extra88 2y agoThat would require adding JavaScript to the page and some people don't do that in their blog, especially when it's published using a static site generator.
- cmgriffing 2y agoBe careful using: dialog::backdrop { backdrop-filter: blur(2px); } If there is frequently updating content on the page like a video, it can kill CPU performance. Restream does this and it punishes my M3 macbook air. It seems you can use the transform3d trick to kick it to the GPU to help fix it.
- extra88 2y agoI'd want to pause any video playing while a dialog with such a backdrop is open.
- cmgriffing 2y agoIn the case of Restream (or cases like their "stage"), thats not always doable. What about superfluous hero animations that marketing sites love to do these days? Pausing some generic canvas rendering logic is usually more annoying than you would want.
- nashashmi 2y agoOT: I really want to see marquee tag have native UI scrolling via CSS property. The many websites that use this horizontal scrolling layout with JS makes me want to cry.
- burgerzzz 2y ago160 likes for this?