commit c6e990c2b7dcc6f94c54d3136b0606658eb286fa Author: Tilman Kranz Date: Sun Jan 5 22:28:39 2025 +0100 initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..c236a58 --- /dev/null +++ b/README.md @@ -0,0 +1,82 @@ +# firefox-user-chrome-css + +## Overview + +The `userChrome.css` presented in this repository will turn the "floating" +browser tabs in Firefox introduced by the Proton UI back into regular "tabs". +The following screenshot demonstrates this: + +![screenshot](doc/screenshot.png "screenshot") + +The primary source for creating the userChrome CSS was the generator provided +here: + +- + +The resulting CSS was tweaked by me manually and then processed with Stylelint +to apply best CSS practises: + +- + +## Requirements + +1. Activate legacy user profile customizations: + +- Run Firefox. +- Open . +- Search for setting `toolkit.legacyUserProfileCustomizations.stylesheets`. +- Set value to `True`. + +2. Locate your Firefox profile folder: + +*Note:* There are multiple ways of locating your Firefox profile folder; this +one should work on all platforms. + +- Run Firefox. +- Open . +- The value of "profile directory" is the location of your active Firefox profile folder. + +## Installation + +3. Create new folder `chrome` in your profile folder. + +4. Copy `userChrome.css` to folder `chrome` in your profile folder. + +5. Restart Firefox to apply changes. + +## Copyright and License + +``` +This software is heavily based on `firefox-89-styling-proton-ui`: + +Copyright © 2022 Jefferson Scher. All Rights Reserved. CSS examples available under CC BY 4.0 or BSD-3-Clause License. + +Contributions to this software were made by: + +Copyright © 2025 Tilman Kranz. The CSS code in this repository is available under CC BY 4.0 or BSD-3-Clause License. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +``` diff --git a/chrome/userChrome.css b/chrome/userChrome.css new file mode 100644 index 0000000..9249083 --- /dev/null +++ b/chrome/userChrome.css @@ -0,0 +1,95 @@ +/* some exceptions for the stylelint CSS linter: */ + +/* stylelint-disable selector-id-pattern */ +/* stylelint-disable selector-type-no-unknown */ +/* stylelint-disable declaration-block-single-line-max-declarations */ + +/* OPTIONAL: Remove items from image context menu; see also view-source:chrome://browser/content/browser.xhtml */ + +/* +#context-sendimage, #context-sep-setbackground, #context-setDesktopBackground, #context-sep-sharing, #context-inspect-a11y, #context-take-screenshot, #context-translate-selection, #context-savelinktopocket, #context-pocket, #translations-button, #reader-mode-button { display: none !important; } +*/ + +/* OPTIONAL: Tighten up drop-down/context/popup menu spacing */ + +/* +menupopup:not(.in-menulist) > menuitem, menupopup:not(.in-menulist) > menu { padding-block: 4px !important; min-height: unset !important; } +:root { --arrowpanel-menuitem-padding: 4px 8px !important; } +*/ + +/* Adjust tab corner shape, optionally remove space below tabs */ +#tabbrowser-tabs { --user-tab-rounding: 5px; } +.tab-background { border-radius: var(--user-tab-rounding) var(--user-tab-rounding) 0 0 !important; /* Connected */ margin-block: 1px 0 !important; /* Connected */ } +#scrollbutton-up, #scrollbutton-down { border-top-width: 1px !important; border-bottom-width: 0 !important; } + +/* Change active tab background color, https://stackoverflow.com/a/78252258 */ +.tab-background:is([selected], [multiselected]) { border-left: 1px solid grey; border-right: 1px solid grey; border-top: 1px solid grey; border-bottom: none; background-image: none !important; box-shadow: 9px 0 8px -4px rgb(0 0 0 / 80%); } + +/* OPTIONAL: analogous to the above, change inactive tab to a grey-to-white gradient */ + +/* +.tab-background:not([selected], [multiselected]) { background-image: linear-gradient( to top, hsl(137.28deg 0% 70% / 0%), hsl(137.28deg 0% 72.72% / 5%), hsl(137.28deg 0% 75.43% / 9.2%), hsl(137.28deg 0% 78.1%) 13.2%, hsl(137.28deg 0% 80.72%) 17%, hsl(137.28deg 0% 83.26%) 20.8%, hsl(137.28deg 0% 85.71%) 24.8%, hsl(137.28deg 0% 88.04%) 29.2%, hsl(137.28deg 0% 90.24%) 34.2%, hsl(137.28deg 0% 92.28%) 39.9%, hsl(137.28deg 0% 94.14%) 46.5%, hsl(137.28deg 0% 95.8%) 54.3%, hsl(137.28deg 0% 97.23%) 63.3%, hsl(137.28deg 0% 98.43%) 73.8%, hsl(137.28deg 0% 99.36%) 86%, hsl(165.09deg 100% 100%) 100%); } +*/ + +/* 1/16/2022 Tone down the Fx96 tab border with add-on themes in certain fallback situations */ +.tab-background:is([selected], [multiselected]):-moz-lwtheme { --lwt-tabs-border-color: rgb(0 0 0 / 0%) !important; border-bottom-color: transparent !important; } + +/* Container color bar visibility */ +.tabbrowser-tab[usercontextid] > .tab-stack > .tab-background > .tab-context-line { margin: 0 max(calc(var(--user-tab-rounding) - 3px), 0px) !important; } + +/* Override Normal Density height to Compact Density height only for tabs */ +#TabsToolbar, #tabbrowser-tabs { --tab-min-height: 29px !important; } + +/* [Connected Tabs] Set a max height based on min-height plus margin-block: 1px 0 */ +#TabsToolbar, #TabsToolbar > hbox, #TabsToolbar-customization-target, #tabbrowser-arrowscrollbox { max-height: calc(var(--tab-min-height) + 1px) !important; } + +/* Audio Playing / Mute Button side-by-side when sound is playing */ +#TabsToolbar { --user-mute-button-height: 20px; /* default size is 12px, site icon is 16px */ } + +/* Tweak for covering a line at the bottom of the active tab on some themes 8/11/2021 */ +#main-window[sizemode="normal"] #toolbar-menubar[autohide="true"] + #TabsToolbar, #main-window[sizemode="normal"] #toolbar-menubar[autohide="true"] + #TabsToolbar #tabbrowser-tabs { --tab-min-height: 30px !important; } + +/* [Connected Tabs] Adjust padding around icons on buttons to avoid crushed images */ +#TabsToolbar-customization-target toolbarbutton > .toolbarbutton-icon, #TabsToolbar-customization-target .toolbarbutton-text, #TabsToolbar-customization-target .toolbarbutton-badge-stack, #scrollbutton-up,#scrollbutton-down { padding-top: 7px !important; padding-bottom: 6px !important; } + +/* [Connected Tabs] Make sure tab attention dot isn't too high - 10 Dec 2022 */ +.tabbrowser-tab:is([image], [pinned]) > .tab-stack > .tab-content[attention]:not([selected="true"]), +.tabbrowser-tab > .tab-stack > .tab-content[pinned][titlechanged]:not([selected="true"]), +#firefox-view-button[attention], .webextension-browser-action[attention="true"] { background-position-y: bottom 2px !important; } + +/* No rounded corners on tabs that are not selected */ +.tabbrowser-tab:not([selected="true"], [multiselected="true"]) .tab-background { border-radius: 0 !important; } + +/* Inactive tabs: Separator line style */ +.tabbrowser-tab:not([selected="true"], [multiselected="true"], [beforeselected-visible="true"]) .tab-background { border-right: 1px solid var(--lwt-background-tab-separator-color, rgb(0 0 0 / 20%)) !important; } + +/* Adjust colors for dark backgrounds */ +[brighttext="true"] .tab-background:is([selected], [multiselected]):-moz-lwtheme { --lwt-tabs-border-color: rgb(255 255 255 / 50%) !important; border-bottom-color: transparent !important; } +[brighttext="true"] .tabbrowser-tab:not([selected="true"], [multiselected="true"], [beforeselected-visible="true"]) .tab-background { border-right: 1px solid var(--lwt-background-tab-separator-color, var(--lwt-selected-tab-background-color, rgb(255 255 255 / 20%))) !important; } + +/* Remove padding between tabs, override font-size and -weight */ +.tabbrowser-tab { padding-left: 0 !important; padding-right: 0 !important; font-size: 12px !important; font-weight: 400 !important; } + +/* Move the mute/unmute button to the right and enlarge it */ +.tab-icon-overlay:not([pinned], [sharing], [crashed]):is([soundplaying], [muted]) { width: var(--user-mute-button-height) !important; height: var(--user-mute-button-height) !important; margin-left: calc(var(--user-mute-button-height) / 2 + 2px) !important; /* pushes icon to the right */ margin-right: 2px !important; /* closes up some space before the text */ padding: 0 !important; /* allows icon to expand to full size */ } + +/* Move the site icon to the left a bit and adjust position */ +.tab-icon-stack:not([pinned], [sharing], [crashed]):is([soundplaying], [muted]) > :not(.tab-icon-overlay) { margin-left: -4px !important; /* pushes icon to the left */ margin-top: calc((var(--user-mute-button-height) - 16px) / 2) !important; /* keep site icon reasonably positioned */ } + +/* Color the icon on hover for confirmation or avoidance */ +.tab-icon-overlay:not([pinned], [sharing], [crashed]):is([soundplaying], [muted]):hover { fill: green !important; } + +/* Tweaked Audio playing/Mute button rules for pinned tabs */ +.tab-icon-overlay:not([crashed]):is([pinned], [sharing]):is([soundplaying], [muted]) { width: var(--user-mute-button-height) !important; height: var(--user-mute-button-height) !important; margin-left: 2px !important; /* allow some overlap to reduce expanded width */ margin-right: -2px !important; /* reduce empty space on the right */ padding: 0 !important; /* allows icon to expand to full size */ top: 0 !important; /* align button with site icon */ } + +.tab-icon-overlay:not([crashed]):is([pinned], [sharing]):is([soundplaying], [muted]):hover { fill: green !important; } + +/* for mute button */ .tabbrowser-tab:not(:hover) .tab-icon-overlay:not([pinned], [sharing], [crashed]):is([soundplaying], [muted]), /* for site icon */ .tabbrowser-tab:hover .tab-icon-stack:not([pinned], [sharing], [crashed]):is([soundplaying], [muted]) > :not(.tab-icon-overlay), /* for site icon with Compact density */ :root[uidensity="compact"] .tab-icon-stack:not([pinned], [sharing], [crashed]):is([soundplaying], [muted]) > :not(.tab-icon-overlay) { opacity: 1 !important; /* overrides full transparency with full opacity */ } + +[lwthemetextcolor="bright"] .tab-icon-overlay:not([pinned], [sharing], [crashed]):is([soundplaying], [muted]):hover { fill: lightgreen !important; /* for dark themes */ } + +.tab-icon-stack:not([crashed]):is([pinned], [sharing]):is([soundplaying], [muted]) > :not(.tab-icon-overlay) { margin-left: -6px !important; /* reduce empty space on the left */ margin-top: calc((var(--user-mute-button-height) - 16px) / 2) !important; /* keep site icon reasonably positioned */ } + +.tabbrowser-tab:not(:hover) .tab-icon-overlay:not([crashed]):is([pinned], [sharing]):is([soundplaying], [muted]), /* for site icon */ .tabbrowser-tab:hover .tab-icon-stack:not([crashed]):is([pinned], [sharing]):is([soundplaying], [muted]) > :not(.tab-icon-overlay), /* for site icon with Compact density */ :root[uidensity="compact"] .tab-icon-stack:not([crashed]):is([pinned], [sharing]):is([soundplaying], [muted]) > :not(.tab-icon-overlay) { opacity: 1 !important; /* overrides full transparency with full opacity */ } + +[lwthemetextcolor="bright"] .tab-icon-overlay:not([crashed]):is([pinned], [sharing]):is([soundplaying], [muted]):hover { fill: lightgreen !important; /* for dark themes */ } diff --git a/doc/screenshot.png b/doc/screenshot.png new file mode 100644 index 0000000..90dde80 Binary files /dev/null and b/doc/screenshot.png differ