openstyles / stylus

Stylus - Userstyles Manager
https://add0n.com/stylus.html
GNU General Public License v3.0
5.32k stars 300 forks source link

[Feature request] Add style option to insert at the beginning of document #1793

Open stanio opened 1 month ago

stanio commented 1 month ago

Feature

Description

Add a style option to insert its <style> element at the beginning of the document (possibly at the beginning of <head>) vs. currently (the default) at the end of the document. This would allow to override !important anonymous @layer author styles occurring earlier in the document. See the priority diagram at:

CSS Code

https://codepen.io/Stanimir-Stamenkov/details/rNELrxj

<style>
  /* Author style */
  @layer {
    body {
      color: red !important
    }
  }
</style>

<p>Foo bar</p>

<style>
  /* "User" Stylus style */
  @layer {
    body:not(:empty) {
      color: green !important
    }
  }
</style>

System Information

Additional Context

The latest version of Dark Reader places its styles in anonymous layer declarations. There are a few annoying rules including darkreader/darkreader#8906:

html {
  background-color: #212121 !important
}

I've previously overridden these by having a style with a more specific selector:

html:not(:empty) {
  background-color: unset !important
}

but it doesn't work with styles placed in anonymous layers.

tophf commented 1 month ago

Judging by the diagram you can probably use a fake animation where from and to have the same color.

stanio commented 1 month ago

If I'm reading the diagram and related docs correctly, the only rules with greater priority than !important layer rules, are !important rules in user and user-agent style sheets, and transitions:

While I could specify a transition, the property declaration I would like to "transition" would not have an effect, even when !important.

stanio commented 1 month ago

If I'm reading the diagram and related docs correctly, the only rules with greater priority than !important layer rules...

Named layers are fine in my specific use case as I could apply my previous approach (more specific selector) targeting specific layer names. Anonymous layers appear trickier as every declaration generates a unique layer that cannot be further amended (I wonder if that's a deliberate spec behavior), and only the order of the anonymous @layer declarations matters.

tophf commented 1 month ago

I wonder if the extension's default behavior should be to extract all @layer conditions with !important inside and put them at the beginning of DOM, i.e. no option?

stanio commented 1 month ago

Yes, it could be evaluated like that without introducing an option. An explicit setting might still turn out necessary if unexpected results appear because of possible combinations of !important and regular declarations in a single rule.

tophf commented 1 month ago

Then maybe just the important layer declarations should be lifted?

stanio commented 1 month ago

I can't currently assess if it could be deemed "too custom" behavior with its own set of side effects, hence I've suggested the addition of an option. Then yes, it could be a solution if it doesn't break another major behavior – I can't think of one at the moment.