Just realised that I can use :has() to lock page scrolling under modals and menus without toggling classes with JS. Handy!

This more recent CSS feels so powerful.

Stuff like this in JS can get really messy if you have multiple UI elements that can lock and unlock scroll at the same time.

The body:has(.lock-scroll) utility class method doesn't care - if that class still exists anywhere in the <body>, the scroll stays locked.

@Robb Not enabled on firefox yet, though. So it's "back to the shelf you go, beautiful selector".
@Robb @lilo Will degrade fairly gracefully in this case though? So can as well keep it in?
@Robb Also very handy to unlock scroll again after getting rid of annoying modals in the dev tools :)

@Robb hot damn, that's neat!

I just used :has in production code base for the first time earlier this week. I'm hoping that Firefox finishes its support soon so I can start using it on more critical features

@tylerlwsmith Yeah, same. I'm only really using it for niceties and aesthetic touches at the moment.

Feels like this technique is a nice one to have in the back pocket once we get full support. It's wild to think of what it will open up once it drops in FF.

@Robb right now it fits neatly into the progressive enhancement space

I'm currently using it to add some padding to the top of the body if the fixed-position header has a notification banner attached to the bottom of it. It gives more breathing room between the header and the page content, but it isn't critical for usability

@tylerlwsmith @Robb Yeah, :has replaces so many JS-hacks, it's a real game changer. For FF, overscroll-behaviour:contain on the modal helps a lot to improve the double scrollbar problem in the meantime.
@Robb if the modal is a `dialog` element, it would have an `open` attribute so `body:has(dialog[open])` would do the trick. I think.
@dmc @Robb it should probably be `body:has(dialog:modal)` since `[open]` will also match non-modal dialogs. Could even drop the `dialog` to just check for the presence of any modal elements, so `body:has(:modal) { overflow: hidden; }`

@Robb It seems that overscroll-behavior: none does not work on ::backdrop

https://jsbin.com/qidehez/edit?html,css,output

JS Bin

A live pastebin for HTML, CSS & JavaScript and a range of processors, including SCSS, CoffeeScript, Jade and more...

@Robb I love this selector more with every day.
@Robb My problem with this is usually that the page under the modal can jump a bit if it suddenly loses its scrollbar for which some space was reserved. In the past I've solved this with JS by measuring the scrollbar width and readding it as padding to the page.
These days I'd probably just rely on overscroll-behavior:contain instead.
@Robb this is really neat, actually!