Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inject stylesheets automatically in the JS #137

Merged
merged 5 commits into from
Oct 19, 2023

Conversation

keithamus
Copy link
Collaborator

@keithamus keithamus commented Oct 17, 2023

Description

As popover support is gradually being added to various browsers we find ourselves sometimes hitting compatibility issues where a browser supports the CSS syntax, but not the API, or the other way around, or it supports some outdated syntax like we saw in #128.

Most recently we've realised that Firefox on iOS 17 supports @supports selector(:popover-open) but doesn't support any of the APIs, and as such gets polyfilled.

The net result is that there is no way to detect in CSS alone whether or not popover is supported. So we need to look at other options.

In this PR I've adjusted the CSS we ship to apply some safe defaults (although we could look at emptying it or otherwise removing it in a subsequent version), and instead of a CSS file, the JS directly injects the CSS into the page.

The benefit of injecting the CSS is that we can do it at a time when we know the polyfill needs to be applied. This helps us in several ways:

  1. The polyfill is easier to consume. Just import the JS. This is especially helpful for React or other frameworks where CSS loading is heavily dependant on an individual projects infrastructure, and we can skip all that complexity by not expecting the user to load our CSS.
  2. The CSS is no longer loaded for browsers which support popover, this means that there are less styles conflicting with the UA styles, and if the patch doesn't apply then there are no other side effects.
  3. More browsers work!

Steps to test/reproduce

You can manually test the polyfill in a variety of browsers to get a sense of this change. I tested in the following:

  • Chrome 118
  • Chrome 113
  • Chrome 111
  • Firefox 118 with popovers enabled and disabled.
  • Firefox nightly with popovers enabled and disabled.
  • Firefox 115
  • Firefox 102
  • Firefox 80
  • Safari 17 on macos
  • Safari 16.5 on macos
  • Safari iOS 14 (Big Sur)
  • Safari iOS
  • Firefox iOS 17
  • Gnome Web on Linux

Show me

@netlify
Copy link

netlify bot commented Oct 17, 2023

Deploy Preview for popover-polyfill ready!

Name Link
🔨 Latest commit b861954
🔍 Latest deploy log https://app.netlify.com/sites/popover-polyfill/deploys/65301173daf0d700086776f1
😎 Deploy Preview https://deploy-preview-137--popover-polyfill.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Member

@jgerigmeyer jgerigmeyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me! @mirisuzanne Would you be willing to review this too?

@keithamus It's not new in this PR, but I notice that the "Click to toggle shadowed Popover" button crashes the tab for me when clicked in FF 118.

Copy link
Member

@mirisuzanne mirisuzanne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this approach! The polyfill is going to to require JS either way, so no point shipping the CSS without it.

Realizing the comments I left aren't really specific to the PR - so feel free to merge. I'm still curious about your thinking on the styles, but that shouldn't hold up the actual change here.

@@ -35,6 +35,86 @@ function patchSelectorFn<K extends string>(

const nonEscapedPopoverSelector = /(^|[^\\]):popover-open\b/g;

const styles = `
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious where these styles come from (besides z-index which is filling in for top-layer)? Are they the proposed browser defaults? It looks like this is attempting to reset styles that may be applied on the popover element itself, and return them to spec initial values? I'm a bit skeptical about overstepping the role of a polyfill, into supplying our own recommended styles – if there's any chance these confuse the transition onto the browser-native feature?

Copy link
Collaborator Author

@keithamus keithamus Oct 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes these are all the UA defaults (aside from - as you rightly said - z-index). Here's chromes UA stylesheet, Firefox's UA sheet, and Webkit's is here.

These have some small differences, mostly vestigial from the initial implementation, but some are to account for some subtle differences. I can follow up with some PRs to better align these to the UA stylesheets but I'd like to test those changes independently.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, looks good and sounds great :)

display: revert;
}

[anchor].\\:popover-open {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably keep things simpler with .popover-open rather than trying to duplicate pseudo-class syntax inside the class syntax. Maybe that ship has already sailed, though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally this pseudo class was :open, and so I opted for .:open to provide a classname that would be different enough that it wouldn't conflict with existing styles. The pseudo class has since shifted to :popover-open and so we followed up with a name change, but even so .popover-open seems to be in common enough usage that it felt best to stick with the : prefix.

@keithamus
Copy link
Collaborator Author

It's not new in this PR, but I notice that the "Click to toggle shadowed Popover" button crashes the tab for me when clicked in FF 118

That's interesting. Is that on stock Firefox, or have you enabled popovers or some shadowdom features? I can't reproduce locally, but it'd be interesting to investigate. Do you have a crash report?

@jgerigmeyer
Copy link
Member

It's not new in this PR, but I notice that the "Click to toggle shadowed Popover" button crashes the tab for me when clicked in FF 118

That's interesting. Is that on stock Firefox, or have you enabled popovers or some shadowdom features? I can't reproduce locally, but it'd be interesting to investigate. Do you have a crash report?

This is stock Firefox 118.0.2 with popovers disabled. It works fine for me in Safari 16.6 (using the polyfill). If I test in Chrome (popovers enabled) or Firefox (popovers enabled), the button just doesn't do anything. Crash report: https://crash-stats.mozilla.org/report/index/7ac206de-9229-402a-9e6f-31ee80231019

@jgerigmeyer jgerigmeyer merged commit 5a85537 into main Oct 19, 2023
6 checks passed
@jgerigmeyer jgerigmeyer deleted the inject-stylesheets-automatically-in-the-js branch October 19, 2023 14:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants