Is there a way to do this with user CSS on Firefox?

The content has to have full opacity. So setting opacity through the compositor or the opacity CSS property does not count.

Setting a background-color with some alpha on userContent.css technically works but because the browser itself is fully opaque, doesn’t show the background. Trying to set background-related properties on #browser on userChrome.css doesn’t have an effect. If I can make only the background of #browser transparent, this’ll work. But I don’t know if that’s possible.

edit: it is possible, with lots of caveats. Site-specific fixes will be required, popups are hard to read. If you have dark wallpapers enable dark reader to make site content readable on a dark background.

1- set browser.tabs.allow_transparent_browser to true

2- in userChrome.css add #main-window, #tabbrowser-tabpanels{ background: transparent !important; }

3- userContent.css:

*{
  background-color: transparent !important;
}
/* if you don't want full transparency */
html:root{
  background-color: #00000080 !important;
}
  • MrOtherGuy@lemmy.world
    link
    fedilink
    arrow-up
    2
    ·
    2 days ago

    I don’t think I understand exactly what parts you want to make transparent, but this does work:

    1. set browser.tabs.allow_transparent_browser to true
    2. in userChrome.css add #main-window, #tabbrowser-tabpanels{ background: transparent !important; }
    3. in userContent.css add html:root{ background-color: transparent !important; }

    The above would make window background, and the are behind web-content transparent as well as background of html documents - otherwise the background of browser area wouldn’t show up anyway. Toolbars that have their own specified colors would still be colored - which might be opaque or not depending what theme you have selected.

    • Quail4789@lemmy.mlOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      2 days ago

      Your userContent.css didn’t work for me but body { background: transparent !important; } does.

      Although obvious in hindsight, on many sites, most of the webpage content isn’t actually background so it is going to take a lot of per-site CSS to get transparent webpages.

      • MrOtherGuy@lemmy.world
        link
        fedilink
        arrow-up
        2
        ·
        2 days ago

        Yeah, I just figured the safest option would be to only set the actual document root element transparent - in practice I think it’s possibly more likely that the <body> element has background set by the page - although the page might as well set both. So yes, it depends on the website.

        • Quail4789@lemmy.mlOP
          link
          fedilink
          English
          arrow-up
          1
          ·
          edit-2
          2 days ago

          I think the problem comes from !important not working as expected for me. Your html:root doesn’t work on my setup because most websites set background on body and that somehow overrides html:root despite the !important. Similarly, if I set it in the body, background or background-color set in lower levels still override my usercontent (again, despite me using !important). That’s causing the webpage to have some transparent bits but a lot of elements will have regular opaque backgrounds. Any ideas?

          PS I don’t have anything else in userContent.css or any extension that’s setting CSS rules.

          • MrOtherGuy@lemmy.world
            link
            fedilink
            arrow-up
            1
            ·
            2 days ago

            I think the answer depends on which elements exactly you want to make transparent. The page is a layered structure. The html root element is behind them all. Then body element is on top of that, the rest of the elements on top of body, etc.

            So if you intend to have transparency all the way down, then you need to make sure that all the elements in that stack are transparent. If any single item in a stack has an opaque background then the transparency effect stops at that.

            As an example, if you set background:transparent to just body but not the document root element, then body will indeed be transparent, but it does not matter because the root will still be opaque. Likewise, if root is made transparent, but there is any opaque layer on top of that, then only the parts of the root element that are not covered by that opaque layer will show up as transparent. If you have a glass table and put a sheet of paper on top of it, then you don’t see through the part covered by the paper even though the table itself is transparent.

            • Quail4789@lemmy.mlOP
              link
              fedilink
              English
              arrow-up
              1
              ·
              edit-2
              2 days ago

              I want the entire background of any webpage to be transparent. Like this user had here..

              For me, inheritance doesn’t work as you described. Inner level rules don’t always inherit from outer levels (I think if an inner background-color is set equal to a variable, it doesn’t inherit it’s parent’s background). Setting root background doesn’t affect body, setting body background doesn’t effect elements further down the tree (e.g. a lemmy post will still have a background color while it’s surroundings are transparent).

              I can achieve what I want by setting the rule globally with:

              * {
              	background: transparent !important;
              	background-color: transparent !important;
              }
              

              The problem with this approach is I don’t actually want 100% transparency. I want at least above 75% to keep the content readable. However, with something like this:

              * {
              	background: #00000080 !important;
              	background-color: #00000080 !important;
              }
              

              overlapping elements’ transparency stack and create regions with different opacities all over the page.

              edit: writing this game me an idea and combining the two works:

              * {
              	background: transparent !important;
              	background-color: transparent !important;
              }
              
              body {
              	background: #00000080 !important;
              	background-color: #00000080 !important;
              }
              
              • MrOtherGuy@lemmy.world
                link
                fedilink
                arrow-up
                1
                ·
                2 days ago

                Right, background-color is not an inherited property (compared to for example color (color of text) which is). But even if it were, inheritance is not “enforced” so if website css sets a backround-color specifically for that element then the inherited value would be lost anyway.

                But the way you now describe it doesn’t seem possible. There is not syntax to apply style rule to “just the innermost element”. I think the closest would be to have everything else have fully transparent background, but the html root element have only partial transparency:

                *{
                  background: transparent !important;
                }
                html:root{
                  background: #00000080 !important;
                }
                

                However, you will still face a problem; many websites draw graphics or images as a background-image so if you use the background shorthand property then those graphics will be effectively removed. On the other hand, if you instead set just background-color then parts might get opaque again because a website could be drawing even opaque backgrounds as background-image instead of background-color.

                • Quail4789@lemmy.mlOP
                  link
                  fedilink
                  English
                  arrow-up
                  1
                  ·
                  2 days ago

                  You’re right about the background. That was me going catch-all while testing. I’ll set background-color only for a while and observe how that works.

                  I assumed background-color would be inherited when marked !important since I haven’t seen that noted anywhere on MDN or similar.

  • myself@lemmy.ml
    link
    fedilink
    arrow-up
    3
    ·
    2 days ago

    If you’re using picom you can just write a custom pixel shader that makes one very specific color transparent and then use css to set background-color to that value. Essentially just writing yourself a very hacky greenscreen solution

    • Quail4789@lemmy.mlOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      2 days ago

      I am using Hyprland but it also supports custom shaders. I might give this a try, thanks.

    • Quail4789@lemmy.mlOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      edit-2
      2 days ago

      So, I’ve Googled my way to a very simple example to test how this’d work. However, the example below basically doesn’t have any effect. (Setting pixColor[1] = 1.0; makes everything green so the shader is loaded correctly).

      precision highp float;
      varying vec2 v_texcoord;
      uniform sampler2D tex;
      
      void main() {
      	// get the pixel color
             vec4 pixColor = texture2D(tex, v_texcoord);
      
      	// change the alpha
      	pixColor[3] = 0.75;
      
      	// set the pixel color
      	gl_FragColor = pixColor;
      }
      

      Since I don’t know anything about shaders, before I open an issue on Hyprland, is this how you’d set the alpha of each pixel on a screen?

      I suspect this might not be possible in Hyprland after all as it doesn’t natively support per-window shaders. IIUC, Hyprland applies the shader after it composits so there’s technically nothing behind the window I’m trying to make transparent.

      • Max-P@lemmy.max-p.me
        link
        fedilink
        arrow-up
        2
        ·
        2 days ago

        Post the Hyprland config too?

        Does it make the entire screen green by chance, not just the windows? If the shader applies to the whole screen, then setting alpha on it doesn’t really makes sense and is probably discarded since your monitor can’t display transparency. You need to make sure it applies on a per-window basis for them to be composited as transparent and show your wallpaper behind it.

        • Quail4789@lemmy.mlOP
          link
          fedilink
          English
          arrow-up
          1
          ·
          2 days ago

          Yes, turns out Hyprland doesn’t support per-window shaders and applies them after rendering so can’t do transparency with them.

  • Max-P@lemmy.max-p.me
    link
    fedilink
    arrow-up
    1
    ·
    2 days ago

    You might be able to convince Firefox to be transparent with a GTK theme as Firefox uses GTK under the hood for the window. If you’re lucky it won’t bother clearing it with black just in case and it’ll actually be transparent.

    The shader option is pretty neat and easy though.

    • Quail4789@lemmy.mlOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      2 days ago

      Please see my response to the other comment. I could use the help if you know about shaders.