Aris-t2 / CustomCSSforFx

Custom CSS tweaks for Firefox
GNU General Public License v3.0
1.84k stars 180 forks source link

[MULTIROW TABS SUPPORT THREAD] - multiple tab lines #39

Closed nykoo closed 2 years ago

nykoo commented 6 years ago

First of all, Thank you for this FF57 life saver repo 👍

Maybe you can save my live by finding a solution to had multiple lines tabs possible (was possible via Tab Mix Plus prior to FF57). This will be great as i downgrade back to FF56 for this, session manager and passifox.

I'm not so confindent asking this as even chrome don't have this function :/

I really need this.

Aris-t2 commented 5 years ago

@Crybal @albino1 You could try these scripts https://github.com/ardiman/userChrome.js/tree/master/multirowtab https://github.com/ardiman/userChrome.js/tree/master/multirowtablite

I have not tested them, but they might offer a better solution than the CSS code.

albino1 commented 5 years ago

Funny, I was just looking at some versions of that code, which I found from a Stack Overflow post and some user's Dark Theme on Github. I couldn't find the original code though (just some Japanese GeoCities page that's listed). Both of the ones you linked to haven't been updated since before Quantum existed, however this one was updated in August:

https://github.com/Izheil/Quantum-Nox-Firefox-Dark-Full-Theme/blob/master/Scrollbars%20%26%20tooltips%20dark%20theme/Chrome/MultiRowTabLiteforFx.uc.js

He details some information on his overall theme page about what he did:

While we only needed to use CSS to enable multi-row tabs, this broke tabs draggability, making reordering tabs when it was enabled a bit erratic, so to fix this, I decided to put all multi-row tabs code inside the MultiRowTabLiteforFx.uc.js file. This means that now Multi-row tabs can be enabled following the method described in the "Scrollbars & tooltips dark theme" folder (to be able to use external javascript files), and then placing the file MultiRowTabLiteforFx.uc.js inside your chrome folder.

https://github.com/Izheil/Quantum-Nox-Firefox-Dark-Full-Theme

I'm not good with CSS, but it's very readable and you can kind of work out if it's safe to run. Javascript on the other hand.. I have no idea if that code is safe or not. Sure does sound promising though!

albino1 commented 5 years ago

Gave in and messed around with it a bit and it actually works really well. Dragging tabs is no problem, though you still can't open new links in the last tab.

The only weird thing is all of the tabs have the bottoms cutoff except the active tab. It looks intentional, but I don't know enough about CSS to figure out where in that JS file it's making that decision so I can turn it off. To be honest, I'm not even sure I dislike it, it's kind of interesting and the rows look a bit less crowded and more delineated, but I would probably turn it off if I could.

Here's a screenshot where I've made some arrows to point out the cut off tabs and active full tab:

al-multirow-js-example

Aris-t2 commented 5 years ago

Inside js code replace the line .tabbrowser-tab, .tab-background {height:var(--tab-min-height) !important} with .tabbrowser-tab, .tab-background {min-height: 26px !important}. Set own value instead 26px, if you want.

Crybal commented 5 years ago

So,tabs dragging is fixed or for some reason I am doing it right?

Aris-t2 commented 5 years ago

It works, if you are using the JavaScript code. The available CSS options here still do not offer proper tab dragging.

Crybal commented 5 years ago

...yep...I am using css and a small js of 6kb (I don't remember where I got it from!)

Aris-t2 commented 5 years ago

@Crybal I was referring to the version linked by albino1. It works like this projects "multilined tabs v1" and includes tab dragging.

Crybal commented 5 years ago

I tried it and it doesnt work with ESR 60.3...maybe I am doing something wrong.Howeve I OK as I am now so I will not try any more....I think!

albino1 commented 5 years ago

Inside js code replace the line .tabbrowser-tab, .tab-background {height:var(--tab-min-height) !important} with .tabbrowser-tab, .tab-background {min-height: 26px !important}. Set an own values instead 26px, if you want.

Worked perfect, thanks Aris-t2!

John0877 commented 5 years ago

Odd, I put that .js into Tampermonkey and it doesnt work. No multiple lines. I disabled the multiline css file from the CustomCSS pack too.

albino1 commented 5 years ago

@John0877, it's not a userscript, it's an actual javascript file that goes in your chrome folder. There's a few steps to get it to work. First, grab this zip file:

Firefox Multirow Javascript.zip

Then put the XML file in your chrome folder along with the JS file linked above. Here it is again:

https://github.com/Izheil/Quantum-Nox-Firefox-Dark-Full-Theme/blob/master/Scrollbars%20%26%20tooltips%20dark%20theme/Chrome/MultiRowTabLiteforFx.uc.js

Finally, add the code contained in the userChrome.css in the zip to your actual userChrome.css file.

And yeah, the Multirow support from CustomCSSforFx needs to be disabled (I assume).

John0877 commented 5 years ago

So if I understand this correctly it should be something like this: \PROFILE FOLDER\Chrome\userChrome.css (with added code from the .zip files userChrome.css file) \PROFILE FOLDER\Chrome\userChrome.xml \PROFILE FOLDER\Chrome\MultiRowTabLiteForFxEdited.uc.js (Edited cause added the line change above)

the userChrome.css file mentions another .css file that I dont have and is in no folder in the QuantumNox file structure anywhere. @import ("userChrome-separate-style-example.css");

Also, I thought all @Namespace lines break code now in FxQuantum?

albino1 commented 5 years ago

If you're not sure where to put it, just go to about:support and click the button for opening your profile folder. If you don't have a folder called chrome then create one and put that stuff in there.

userChrome-separate-style-example.css doesn't exist, I'm not sure why it references that either. I haven't tried removing it. Might a remnant from the larger overall theme.

John0877 commented 5 years ago

OK, I got it working now and adjusted the tab widths in the .js file and commented out any other places I can find it mentioned in any css file. However now I got this weird thing where tabs with smaller titles are smaller with gaps between the tabs. Except when I mouseover the gap it highlights the smaller tab. I also had another issue where the first row of tabs was how I want them but the second row tabs were wider. So I commented out the flex grow line in the .js file and that seemed to fix it.

albino1 commented 5 years ago

The gaps is the problem (or feature depending on your perspective?) that I mentioned above and illustrated with the screenshot. See this post by @Aris-t2 for the fix.

Thanks for the tip on commenting out the flex grow line, I wasn't that into it, so it's nice to remove it :)

John0877 commented 5 years ago

I had already replaced that line in the .js file. I'm talking about width though not height.

https://i.imgur.com/7WlcZSO.png

Oh, another thing Id like is to put all the files related to this MultiRow script in its own folder and call it from the root userChrome.css file. How would I do that or does the .js file HAVE to be in the root of the Chrome folder?

albino1 commented 5 years ago

Ah, I see, I don't have that horizontal gap problem, but I didn't mess with any of the tab sizes. The only things I changed were the original fix Aris posted to remove the vertical gaps and the flex line to change the variable width that you mentioned.

Not sure about how to put everything in a specific folder. Looks like it searches in Line 24 of the userChrome.xml file:

if(file.isFile()) {
    if(/(^userChrome|\.uc)\.js$/i.test(file.leafName)) {
John0877 commented 5 years ago

sigh, and I dont know enough about regex to change that to add a folder in there or if it could just all be called from a .css file in a subfolder.

Maybe @Aris-t2 has some idea why the horizontal gap exists :)

Aris-t2 commented 5 years ago

The gaps is the problem (or feature depending on your perspective?) that I mentioned above and illustrated with the screenshot. See this post by @Aris-t2 for the fix.

I would consider the tab height gaps being an incompatibility, because they neither exists without the js code nor without this projects files. ;-)

No horizontal gaps occurred during my tests. Not sure how to help, but try this:

John0877 commented 5 years ago

I swear its got something to do with this section of the .js file.

#tabbrowser-tabs .scrollbox-innerbox {
    display: flex;
    flex-wrap: wrap; }

#tabbrowser-tabs .arrowscrollbox-scrollbox {
    overflow: visible;
    display: block}

Ive tried commenting out display: flex and then multiple rows doesnt work. tried commenting flex-wrap: wrap, no multirow, tried commenting #tabbrowser-tabs, same, tried commenting .scrollbox-innerbox, same. Commented overflow: visible and same thing. changed visible to wrap, no multi. If I get multirow to work, the tabs have those gaps, if I can get the gaps to go away, multirow no longer works.

In the userchrome.css file, @import ("userChrome-separate-style-example.css");/**/ @namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul); toolbarbutton#forward-button { -moz-binding: url("userChrome.xml#js"); }

I tried commenting each line or the code fragment and no multirow.

Oh, and with every shutdown n restart of Firefox, I cleared the startup cache folder.

albino1 commented 5 years ago

The only line I commented out was Line 21:

flex-grow:1;

Aris-t2 commented 5 years ago

Looks like Github has eaten my last respond again.

Try this code, if you are using squared tabs from CustomCSSforFx:

// ==UserScript==
// @name           zzzz-MultiRowTabLiteforFx.uc.js
// @namespace      http://space.geocities.yahoo.co.jp/gl/alice0775
// @description    Multi-row tabs draggability fix, Experimental CSS version
// @include        main
// @compatibility  Firefox 61
// @author         Alice0775, Endor8, TroudhuK, Izheil
// @version        2018/20/08 03:05 Fixed some issue with min-width
// @version        2018/11/05 15:05 Firefox 60
// @version        2016/08/05 00:00 Firefox 48
// @version        2016/05/01 00:01 hide favicon if busy
// @version        2016/03/09 00:01 Bug 1222490 - Actually remove panorama for Fx45+
// @version        2016/02/09 00:01 workaround css for lwt
// @version        2016/02/09 00:00
// ==/UserScript==
    zzzz_MultiRowTabLite();
function zzzz_MultiRowTabLite() {
    var css =`
    /* MULTIROW TABS CSS */
    .tabbrowser-tab:not([pinned]) {
        flex-grow:1;
        min-width:100px !important;}

   /*.tabbrowser-tab, .tab-background {height:var(--tab-min-height) !important}*/
    /*#TabsToolbar, #tabbrowser-tabs, .tabbrowser-tab, .tab-background {min-height: unset !important; height: unset !important;};*/

    #TabsToolbar, #tabbrowser-tabs, /*.tabbrowser-tab,*/ .tab-background {
      min-height: 26px !important;
      height: unset !important;
    }
    .tabbrowser-tab {
      min-height: 26px !important;
      height: unset !important;
    }

    .tab-stack {width: 100%}

    #tabbrowser-tabs .scrollbox-innerbox {
        display: flex;
        flex-wrap: wrap;}

    #tabbrowser-tabs .arrowscrollbox-scrollbox {
        overflow: visible;
        display: block;}

    @media (-moz-os-version: windows-win10) {
    #titlebar-buttonbox {height:var(--tab-min-height) !important}}

    #titlebar {height:var(--tab-min-height) !important}

    #titlebar {margin-bottom:calc(1px + var(--tab-min-height)*-1) !important}

    #main-window[sizemode="maximized"] #titlebar
    {margin-bottom: calc(8px + var(--tab-min-height)*-1)!important}

    #main-window[sizemode="maximized"][uidensity=compact] #titlebar
    {margin-bottom: calc(6px + var(--tab-min-height)*-1)!important}

    .tab-line {height: 2px !important}

    #main-window[sizemode="maximized"] .tab-line {height: 2px !important}

    #titlebar:active {margin-bottom: 0 !important}

    #titlebar:active #titlebar-content {margin-bottom:var(--tab-min-height) !important}

    #tabbrowser-tabs .scrollbutton-up, #tabbrowser-tabs .scrollbutton-down, #alltabs-button, .tabbrowser-tab:not([fadein])
    {display: none}
    `;
    var sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
    var uri = makeURI('data:text/css;charset=UTF=8,' + encodeURIComponent(css));
    sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
    gBrowser.tabContainer._getDropIndex = function(event, isLink) {
        var tabs = this.childNodes;
        var tab = this._getDragTargetTab(event, isLink);
        if (window.getComputedStyle(this).direction == "ltr") {
            for (let i = tab ? tab._tPos : 0; i < tabs.length; i++) {
                let boxObject = tabs[i].boxObject;
                if (event.screenX < boxObject.screenX + boxObject.width / 2
                 && event.screenY < boxObject.screenY + boxObject.height) // multirow fix
                    return i;
            }
        } else {
            for (let i = tab ? tab._tPos : 0; i < tabs.length; i++) {
                let boxObject = tabs[i].boxObject;
                if (event.screenX > boxObject.screenX + boxObject.width / 2
                 && event.screenY < boxObject.screenY + boxObject.height) // multirow fix
                    return i;
            }
        }
        return tabs.length;
    };
    // This sets when to apply the fix (by default a new row starts after the 23th open tab, unless you changed the min-size of tabs)
    gBrowser.tabContainer.ondragstart = function(){if(gBrowser.tabContainer.childNodes.length >= (window.innerWidth - 200) / 75) {

    gBrowser.tabContainer._getDropEffectForTabDrag = function(event){return "";}; // multirow fix: to make the default "dragover" handler does nothing
    gBrowser.tabContainer._onDragOver = function(event) {
        event.preventDefault();
        event.stopPropagation();

        var ind = this._tabDropIndicator;

        var effects = orig_getDropEffectForTabDrag(event);
        if (effects == "link") {
            let tab = this._getDragTargetTab(event, true);
            if (tab) {
                if (!this._dragTime)
                    this._dragTime = Date.now();
                if (!tab.hasAttribute("pending") && // annoying fix
                    Date.now() >= this._dragTime + this._dragOverDelay)
                    this.selectedItem = tab;
                ind.collapsed = true;
                return;
            }
        }

        var newIndex = this._getDropIndex(event, effects == "link");
        if (newIndex == null)
            return;

        var ltr = (window.getComputedStyle(this).direction == "ltr");
        var rect = this.arrowScrollbox.getBoundingClientRect();
        var newMarginX, newMarginY;
        if (newIndex == this.childNodes.length) {
            let tabRect = this.childNodes[newIndex - 1].getBoundingClientRect();
            if (ltr)
                newMarginX = tabRect.right - rect.left;
            else
                newMarginX = rect.right - tabRect.left;
            newMarginY = tabRect.top + tabRect.height - rect.top - rect.height; // multirow fix
        } else {
            let tabRect = this.childNodes[newIndex].getBoundingClientRect();
            if (ltr)
                newMarginX = tabRect.left - rect.left;
            else
                newMarginX = rect.right - tabRect.right;
            newMarginY = tabRect.top + tabRect.height - rect.top - rect.height; // multirow fix
        }

        ind.collapsed = false;

        newMarginX += ind.clientWidth / 2;
        if (!ltr)
            newMarginX *= -1;

        ind.style.transform = "translate(" + Math.round(newMarginX) + "px," + Math.round(newMarginY) + "px)"; // multirow fix
        ind.style.marginInlineStart = (-ind.clientWidth) + "px";
    };
    gBrowser.tabContainer.addEventListener("dragover", gBrowser.tabContainer._onDragOver, true);

    gBrowser.tabContainer.onDrop = function(event) {
        var newIndex;
        var dt = event.dataTransfer;
        var draggedTab;
        if (dt.mozTypesAt(0)[0] == TAB_DROP_TYPE) {
            draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
            if (!draggedTab)
                return;
        }
        var dropEffect = dt.dropEffect;
        if (draggedTab && dropEffect == "copy") {}
        else if (draggedTab && draggedTab.parentNode == this) {
            newIndex = this._getDropIndex(event, false);
            if (newIndex > draggedTab._tPos)
                newIndex--;
            gBrowser.moveTabTo(draggedTab, newIndex);
        }
    };
    gBrowser.tabContainer.addEventListener("drop", function(event){this.onDrop(event);}, true);
}}}

// copy of the original and overrided _getDropEffectForTabDrag method
function orig_getDropEffectForTabDrag(event) {
    var dt = event.dataTransfer;
    if (dt.mozItemCount == 1) {
        var types = dt.mozTypesAt(0);
        // tabs are always added as the first type
        if (types[0] == TAB_DROP_TYPE) {
            let sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
            if (sourceNode instanceof XULElement &&
                sourceNode.localName == "tab" &&
                sourceNode.ownerGlobal.isChromeWindow &&
                sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser" &&
                sourceNode.ownerGlobal.gBrowser.tabContainer == sourceNode.parentNode) {
                // Do not allow transfering a private tab to a non-private window
                // and vice versa.
                if (PrivateBrowsingUtils.isWindowPrivate(window) !=
                    PrivateBrowsingUtils.isWindowPrivate(sourceNode.ownerGlobal))
                    return "none";

                if (window.gMultiProcessBrowser !=
                    sourceNode.ownerGlobal.gMultiProcessBrowser)
                    return "none";

                return dt.dropEffect == "copy" ? "copy" : "move";
            }
        }
    }

    if (browserDragAndDrop.canDropLink(event)) {
        return "link";
    }
    return "none";
}
John0877 commented 5 years ago

That fixes the top row but the second row is much wider. https://i.imgur.com/njrWZM7.png

What did you change? They work great now, no gaps.

I commented out the flex-grow line again and the tab size is perfect now. They adhere to the min-width of 75 and subsequent rows also adhere to it without getting like 2-3 times as big cause of the flex-grow.

albino1 commented 5 years ago

Thanks for the updated code @Aris-t2! As it currently stands this is a significantly better solution than either tabs_multiple_lines.css or tabs_multiple_lines_v2.css. Any chance this gets officially included into CustomCSSforFx or is JS outside the scope?

John0877 commented 5 years ago

Well, Aris has his own CustomJSforFx pack but it would also be appropriate for him to maybe ask the original author of the js to use it.

Aris-t2 commented 5 years ago

We linked the script in and to this discussion and I think we can share modified versions with CustomCSSforFx compatibility of it here too, but I have no plans to include it neither into CustomJSforFx nor into CustomCSSforFx (where it would be wrong anyway), because it is definitively not made by me and there is also no official support by me for it. Keep in mind the script will only do its job on Firefox 60-64, it does not work on Firefox 65+.

@John0877 The "big" tab width is actually what Firefox does by default. The width only changes once a large amount of tabs hits overflow mode. The script keeps that feature in its default state.

albino1 commented 5 years ago

Keep in mind the script will only do its job on Firefox 60-64, it does not work on Firefox 65+.

Oh man, I did not know that... I really don't want to get attached to something so important only to have it disappear in a month. What are the odds that a new fix gets released that will support 65+? Or that someone will be able to make a CSS-only fix for the tab dragging issue?

Aris-t2 commented 5 years ago

I guess the js code will be updated by its original author/modder once Fx65 hits release channel.

Aris-t2 commented 5 years ago

The problem was the CSS code. Once you copy and paste the CSS from this project (v1 or v2) the code will work fine in Fx 60-65, meaning multiple tab lines will work like tabs_multiple_lines.css and tabs_multiple_lines_v2.css and keep tab drop functionality.

CustomCSSforFx tabs_multiple_lines.css + drag fix script:

// ==UserScript==
// @name           zzzz-MultiRowTabLiteforFx.uc.js
// @namespace      http://space.geocities.yahoo.co.jp/gl/alice0775
// @description    Multi-row tabs draggability fix, Experimental CSS version
// @include        main
// @compatibility  Firefox 60-65
// @author         Alice0775, Endor8, TroudhuK, Izheil, Aris
// @version        2018/20/08 03:05 Fixed some issue with min-width
// @version        2018/11/05 15:05 Firefox 60
// @version        2016/08/05 00:00 Firefox 48
// @version        2016/05/01 00:01 hide favicon if busy
// @version        2016/03/09 00:01 Bug 1222490 - Actually remove panorama for Fx45+
// @version        2016/02/09 00:01 workaround css for lwt
// @version        2016/02/09 00:00
// @version        2018/22/11 23:00 Firefox 60-65 compatibility
// ==/UserScript==
    zzzz_MultiRowTabLite();
function zzzz_MultiRowTabLite() {
    var css =`
:root {
  --tabs-end-position: 50px;
  --tab-min-height_mlt: var(--tab-min-height,32px); /* set own value here, if used without configuration files */
  --mltabs-newtab-height: var(--tab-min-height,32px); /* set own value here, if used without configuration files */
  --tab_min_width_mlt: 60px;
  --tab_max_width_mlt: 100px;
}

/* titlebar buttons */
#titlebar-buttonbox {
  vertical-align: top !important;
  display: block !important;
}

.tabbrowser-arrowscrollbox scrollbox {
  overflow: visible !important;
}

.tabbrowser-arrowscrollbox scrollbox > box {
  display: block !important;
}

/* additional space after tabs */
/*
.tabbrowser-tabs {
  -moz-margin-end: var(--tabs-end-position) !important;
}
*/

/* tab size */
.tabbrowser-tab {
  min-height: var(--tab-min-height_mlt) !important;
  max-height: var(--tab-min-height_mlt) !important;
  vertical-align: top !important;
  -moz-box-sizing: border-box !important;
}

.tabbrowser-tab[fadein]:not([pinned]) {
  min-width: var(--tab_min_width_mlt) !important;
  max-width: var(--tab_max_width_mlt) !important;
}

/* 'new tab' tab size */
.tabs-newtab-button {
  vertical-align: bottom !important;
  height: var(--mltabs-newtab-height) !important;
  margin-bottom: -1px !important;
}

@media (-moz-windows-classic) {
    #TabsToolbar #tabbrowser-tabs .tabs-newtab-button {
      margin-bottom: 1px !important;
      height: calc(var(--mltabs-newtab-height) - 2px) !important;
    }
}

/* hide unneeded buttons */
.scrollbutton-up ,
.scrollbutton-down,
#TabsToolbar #alltabs-button{
  display: none;
}

.tabbrowser-arrowscrollbox > .arrowscrollbox-overflow-start-indicator:not([collapsed]),
.tabbrowser-arrowscrollbox > .arrowscrollbox-overflow-end-indicator:not([collapsed]) {
  opacity: 0 !important;
}

#tabbrowser-tabs * {
  overflow-x: none !important;
}

#main-window[customizing] #tabbrowser-tabs .scrollbox-innerbox {
  display: block !important;
}

#tabbrowser-tabs .scrollbox-innerbox {
  -moz-padding-end: 4px !important;
}

#TabsToolbar[currentset^="tabbrowser-tabs,new-tab-button"] #tabbrowser-tabs .scrollbox-innerbox {
  -moz-padding-end: 0px !important;
}

/* remove crap set by Firefox 58+ */
.tabbrowser-tab::after,
.tabbrowser-tab::before {
  border-left: unset !important;
  border-image: unset !important;
  border-image-slice: unset !important;
  border: 0 !important;
}

#TabsToolbar .titlebar-placeholder[type="pre-tabs"],
#TabsToolbar .titlebar-placeholder[type="post-tabs"] {
  opacity: 0 !important;
}

#main-window[tabsintitlebar] #TabsToolbar .private-browsing-indicator,
#main-window[tabsintitlebar] #TabsToolbar #window-controls,
#main-window[tabsintitlebar] #TabsToolbar .titlebar-spacer[type="pre-tabs"],
#main-window[tabsintitlebar] #TabsToolbar .titlebar-spacer[type="post-tabs"] {
  display: none !important;
}
    `;
    var sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
    var uri = makeURI('data:text/css;charset=UTF=8,' + encodeURIComponent(css));
    sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
    gBrowser.tabContainer._getDropIndex = function(event, isLink) {
        var tabs = this.childNodes;
        var tab = this._getDragTargetTab(event, isLink);
        if (window.getComputedStyle(this).direction == "ltr") {
            for (let i = tab ? tab._tPos : 0; i < tabs.length; i++) {
                let boxObject = tabs[i].boxObject;
                if (event.screenX < boxObject.screenX + boxObject.width / 2
                 && event.screenY < boxObject.screenY + boxObject.height) // multirow fix
                    return i;
            }
        } else {
            for (let i = tab ? tab._tPos : 0; i < tabs.length; i++) {
                let boxObject = tabs[i].boxObject;
                if (event.screenX > boxObject.screenX + boxObject.width / 2
                 && event.screenY < boxObject.screenY + boxObject.height) // multirow fix
                    return i;
            }
        }
        return tabs.length;
    };
    // This sets when to apply the fix (by default a new row starts after the 23th open tab, unless you changed the min-size of tabs)
    gBrowser.tabContainer.ondragstart = function(){if(gBrowser.tabContainer.childNodes.length >= (window.innerWidth - 200) / 75) {

    gBrowser.tabContainer._getDropEffectForTabDrag = function(event){return "";}; // multirow fix: to make the default "dragover" handler does nothing
    gBrowser.tabContainer._onDragOver = function(event) {
        event.preventDefault();
        event.stopPropagation();

        var ind = this._tabDropIndicator;

        var effects = orig_getDropEffectForTabDrag(event);
        if (effects == "link") {
            let tab = this._getDragTargetTab(event, true);
            if (tab) {
                if (!this._dragTime)
                    this._dragTime = Date.now();
                if (!tab.hasAttribute("pending") && // annoying fix
                    Date.now() >= this._dragTime + this._dragOverDelay)
                    this.selectedItem = tab;
                ind.collapsed = true;
                return;
            }
        }

        var newIndex = this._getDropIndex(event, effects == "link");
        if (newIndex == null)
            return;

        var ltr = (window.getComputedStyle(this).direction == "ltr");
        var rect = this.arrowScrollbox.getBoundingClientRect();
        var newMarginX, newMarginY;
        if (newIndex == this.childNodes.length) {
            let tabRect = this.childNodes[newIndex - 1].getBoundingClientRect();
            if (ltr)
                newMarginX = tabRect.right - rect.left;
            else
                newMarginX = rect.right - tabRect.left;
            newMarginY = tabRect.top + tabRect.height - rect.top - rect.height; // multirow fix
        } else {
            let tabRect = this.childNodes[newIndex].getBoundingClientRect();
            if (ltr)
                newMarginX = tabRect.left - rect.left;
            else
                newMarginX = rect.right - tabRect.right;
            newMarginY = tabRect.top + tabRect.height - rect.top - rect.height; // multirow fix
        }

        ind.collapsed = false;

        newMarginX += ind.clientWidth / 2;
        if (!ltr)
            newMarginX *= -1;

        ind.style.transform = "translate(" + Math.round(newMarginX) + "px," + Math.round(newMarginY) + "px)"; // multirow fix
        ind.style.marginInlineStart = (-ind.clientWidth) + "px";
    };
    gBrowser.tabContainer.addEventListener("dragover", gBrowser.tabContainer._onDragOver, true);

    gBrowser.tabContainer.onDrop = function(event) {
        var newIndex;
        var dt = event.dataTransfer;
        var draggedTab;
        if (dt.mozTypesAt(0)[0] == TAB_DROP_TYPE) {
            draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
            if (!draggedTab)
                return;
        }
        var dropEffect = dt.dropEffect;
        if (draggedTab && dropEffect == "copy") {}
        else if (draggedTab && draggedTab.parentNode == this) {
            newIndex = this._getDropIndex(event, false);
            if (newIndex > draggedTab._tPos)
                newIndex--;
            gBrowser.moveTabTo(draggedTab, newIndex);
        }
    };
    gBrowser.tabContainer.addEventListener("drop", function(event){this.onDrop(event);}, true);
}}}

// copy of the original and overrided _getDropEffectForTabDrag method
function orig_getDropEffectForTabDrag(event) {
    var dt = event.dataTransfer;
    if (dt.mozItemCount == 1) {
        var types = dt.mozTypesAt(0);
        // tabs are always added as the first type
        if (types[0] == TAB_DROP_TYPE) {
            let sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
            if (sourceNode instanceof XULElement &&
                sourceNode.localName == "tab" &&
                sourceNode.ownerGlobal.isChromeWindow &&
                sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser" &&
                sourceNode.ownerGlobal.gBrowser.tabContainer == sourceNode.parentNode) {
                // Do not allow transfering a private tab to a non-private window
                // and vice versa.
                if (PrivateBrowsingUtils.isWindowPrivate(window) !=
                    PrivateBrowsingUtils.isWindowPrivate(sourceNode.ownerGlobal))
                    return "none";

                if (window.gMultiProcessBrowser !=
                    sourceNode.ownerGlobal.gMultiProcessBrowser)
                    return "none";

                return dt.dropEffect == "copy" ? "copy" : "move";
            }
        }
    }

    if (browserDragAndDrop.canDropLink(event)) {
        return "link";
    }
    return "none";
}

CustomCSSforFx tabs_multiple_lines_v2.css + drag fix script:

// ==UserScript==
// @name           zzzz-MultiRowTabLiteforFx.uc.js
// @namespace      http://space.geocities.yahoo.co.jp/gl/alice0775
// @description    Multi-row tabs draggability fix, Experimental CSS version
// @include        main
// @compatibility  Firefox 60-65
// @author         Alice0775, Endor8, TroudhuK, Izheil, Aris
// @version        2018/20/08 03:05 Fixed some issue with min-width
// @version        2018/11/05 15:05 Firefox 60
// @version        2016/08/05 00:00 Firefox 48
// @version        2016/05/01 00:01 hide favicon if busy
// @version        2016/03/09 00:01 Bug 1222490 - Actually remove panorama for Fx45+
// @version        2016/02/09 00:01 workaround css for lwt
// @version        2016/02/09 00:00
// @version        2018/22/11 23:00 Firefox 60-65 compatibility
// ==/UserScript==
    zzzz_MultiRowTabLite();
function zzzz_MultiRowTabLite() {
    var css =`
:root {
  --tabs-lines: 3; /* 3 rows, increase for more */
  --tab_min_width_mlt: 80px;
  --tab_max_width_mlt: 200px;
  --tab-min-height_mlt: var(--tab-min-height,32px); /* set own value here, if used without configuration files */
}

.tabbrowser-tab[fadein]:not([pinned]) {
  flex-grow: 1;
  min-width: var(--tab_min_width_mlt) !important;
  max-width: var(--tab_max_width_mlt) !important;
}

.tabbrowser-tab,.tab-background {
  min-height: var(--tab-min-height_mlt);
}

.tabs-newtab-button {
  vertical-align: bottom !important;
  height: var(--tab-min-height_mlt);
  margin-bottom: -1px !important;
}

.tab-stack {
  width: 100%;
}

/* fix tab position */
#tabbrowser-tabs,
#tabbrowser-tabs > .tabbrowser-arrowscrollbox {
  min-height: var(--tab-min-height_mlt) !important;
}
:root[uidensity=touch] .tabbrowser-tab:not([pinned]) .tab-content .close-icon {
  padding-top: 0px !important;
  padding-bottom: 0px !important;
}
/**/

#tabbrowser-tabs .scrollbox-innerbox {
  display: flex;
  flex-wrap: wrap;
  overflow-x: collapse !important;
  overflow-y: auto !important;
  min-height: var(--tab-min-height_mlt);
  max-height: calc( var(--tabs-lines) * var(--tab-min-height_mlt) ) !important;
}

#tabbrowser-tabs .arrowscrollbox-scrollbox {
  overflow-x: collapse;
  overflow: visible; 
  display: block;
}

#tabbrowser-tabs .scrollbutton-up,
#tabbrowser-tabs .scrollbutton-down,
#TabsToolbar #alltabs-button,
.tabbrowser-tab:not([fadein]){
  display: none;
}

#main-window[tabsintitlebar] #tabbrowser-tabs {
  -moz-window-dragging: no-drag !important;
}

.tabbrowser-arrowscrollbox > .arrowscrollbox-overflow-start-indicator:not([collapsed]),
.tabbrowser-arrowscrollbox > .arrowscrollbox-overflow-end-indicator:not([collapsed]) {
  opacity: 0 !important;
}

#tabbrowser-tabs * {
  overflow-x: none !important;
}

#main-window[customizing] #tabbrowser-tabs .scrollbox-innerbox {
  display: block !important;
}

#tabbrowser-tabs .scrollbox-innerbox {
  -moz-padding-end: 4px !important;
}

#TabsToolbar[currentset^="tabbrowser-tabs,new-tab-button"] #tabbrowser-tabs .scrollbox-innerbox {
  -moz-padding-end: 0px !important;
}

/* remove crap set by Firefox 58+ */
.tabbrowser-tab::after,
.tabbrowser-tab::before {
  border-left: unset !important;
  border-image: unset !important;
  border-image-slice: unset !important;
  border: 0 !important;
}

#TabsToolbar .titlebar-placeholder[type="pre-tabs"],
#TabsToolbar .titlebar-placeholder[type="post-tabs"]{
  opacity: 0 !important;
}

#main-window[tabsintitlebar] #TabsToolbar .private-browsing-indicator,
#main-window[tabsintitlebar] #TabsToolbar #window-controls,
#main-window[tabsintitlebar] #TabsToolbar .titlebar-spacer[type="pre-tabs"],
#main-window[tabsintitlebar] #TabsToolbar .titlebar-spacer[type="post-tabs"] {
  display: none !important;
}
    `;
    var sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
    var uri = makeURI('data:text/css;charset=UTF=8,' + encodeURIComponent(css));
    sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
    gBrowser.tabContainer._getDropIndex = function(event, isLink) {
        var tabs = this.childNodes;
        var tab = this._getDragTargetTab(event, isLink);
        if (window.getComputedStyle(this).direction == "ltr") {
            for (let i = tab ? tab._tPos : 0; i < tabs.length; i++) {
                let boxObject = tabs[i].boxObject;
                if (event.screenX < boxObject.screenX + boxObject.width / 2
                 && event.screenY < boxObject.screenY + boxObject.height) // multirow fix
                    return i;
            }
        } else {
            for (let i = tab ? tab._tPos : 0; i < tabs.length; i++) {
                let boxObject = tabs[i].boxObject;
                if (event.screenX > boxObject.screenX + boxObject.width / 2
                 && event.screenY < boxObject.screenY + boxObject.height) // multirow fix
                    return i;
            }
        }
        return tabs.length;
    };
    // This sets when to apply the fix (by default a new row starts after the 23th open tab, unless you changed the min-size of tabs)
    gBrowser.tabContainer.ondragstart = function(){if(gBrowser.tabContainer.childNodes.length >= (window.innerWidth - 200) / 75) {

    gBrowser.tabContainer._getDropEffectForTabDrag = function(event){return "";}; // multirow fix: to make the default "dragover" handler does nothing
    gBrowser.tabContainer._onDragOver = function(event) {
        event.preventDefault();
        event.stopPropagation();

        var ind = this._tabDropIndicator;

        var effects = orig_getDropEffectForTabDrag(event);
        if (effects == "link") {
            let tab = this._getDragTargetTab(event, true);
            if (tab) {
                if (!this._dragTime)
                    this._dragTime = Date.now();
                if (!tab.hasAttribute("pending") && // annoying fix
                    Date.now() >= this._dragTime + this._dragOverDelay)
                    this.selectedItem = tab;
                ind.collapsed = true;
                return;
            }
        }

        var newIndex = this._getDropIndex(event, effects == "link");
        if (newIndex == null)
            return;

        var ltr = (window.getComputedStyle(this).direction == "ltr");
        var rect = this.arrowScrollbox.getBoundingClientRect();
        var newMarginX, newMarginY;
        if (newIndex == this.childNodes.length) {
            let tabRect = this.childNodes[newIndex - 1].getBoundingClientRect();
            if (ltr)
                newMarginX = tabRect.right - rect.left;
            else
                newMarginX = rect.right - tabRect.left;
            newMarginY = tabRect.top + tabRect.height - rect.top - rect.height; // multirow fix
        } else {
            let tabRect = this.childNodes[newIndex].getBoundingClientRect();
            if (ltr)
                newMarginX = tabRect.left - rect.left;
            else
                newMarginX = rect.right - tabRect.right;
            newMarginY = tabRect.top + tabRect.height - rect.top - rect.height; // multirow fix
        }

        ind.collapsed = false;

        newMarginX += ind.clientWidth / 2;
        if (!ltr)
            newMarginX *= -1;

        ind.style.transform = "translate(" + Math.round(newMarginX) + "px," + Math.round(newMarginY) + "px)"; // multirow fix
        ind.style.marginInlineStart = (-ind.clientWidth) + "px";
    };
    gBrowser.tabContainer.addEventListener("dragover", gBrowser.tabContainer._onDragOver, true);

    gBrowser.tabContainer.onDrop = function(event) {
        var newIndex;
        var dt = event.dataTransfer;
        var draggedTab;
        if (dt.mozTypesAt(0)[0] == TAB_DROP_TYPE) {
            draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
            if (!draggedTab)
                return;
        }
        var dropEffect = dt.dropEffect;
        if (draggedTab && dropEffect == "copy") {}
        else if (draggedTab && draggedTab.parentNode == this) {
            newIndex = this._getDropIndex(event, false);
            if (newIndex > draggedTab._tPos)
                newIndex--;
            gBrowser.moveTabTo(draggedTab, newIndex);
        }
    };
    gBrowser.tabContainer.addEventListener("drop", function(event){this.onDrop(event);}, true);
}}}

// copy of the original and overrided _getDropEffectForTabDrag method
function orig_getDropEffectForTabDrag(event) {
    var dt = event.dataTransfer;
    if (dt.mozItemCount == 1) {
        var types = dt.mozTypesAt(0);
        // tabs are always added as the first type
        if (types[0] == TAB_DROP_TYPE) {
            let sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
            if (sourceNode instanceof XULElement &&
                sourceNode.localName == "tab" &&
                sourceNode.ownerGlobal.isChromeWindow &&
                sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser" &&
                sourceNode.ownerGlobal.gBrowser.tabContainer == sourceNode.parentNode) {
                // Do not allow transfering a private tab to a non-private window
                // and vice versa.
                if (PrivateBrowsingUtils.isWindowPrivate(window) !=
                    PrivateBrowsingUtils.isWindowPrivate(sourceNode.ownerGlobal))
                    return "none";

                if (window.gMultiProcessBrowser !=
                    sourceNode.ownerGlobal.gMultiProcessBrowser)
                    return "none";

                return dt.dropEffect == "copy" ? "copy" : "move";
            }
        }
    }

    if (browserDragAndDrop.canDropLink(event)) {
        return "link";
    }
    return "none";
}
albino1 commented 5 years ago

I saw that the repository owner pushed some multirow updates today to "work with future versions of Firefox", specifically it seems for 65+. Is that what the code you posted is doing as well?

Here's a link to the big commit he made:

https://github.com/Izheil/Quantum-Nox-Firefox-Dark-Full-Theme/commit/a9c41c615871b05a850c2d7eaab2412b2ab09845

And to his main repository:

https://github.com/Izheil/Quantum-Nox-Firefox-Dark-Full-Theme

Aris-t2 commented 5 years ago

No, I did not use the CSS update pushed by "Izheil".

Like mentioned above I replaced the previous CSS part of the script with code used in this repository's tabs_multiple_lines.css and tabs_multiple_lines_v2.css files. Doing this not only offers two different "multilined" tabs options, but also works with Firefox 65 with default tabs and "classic squared tabs" offered here.

John0877 commented 5 years ago

So the code you posted above will work in 65+ presumably?

Aris-t2 commented 5 years ago

It works on Firefox 65 Nightly right now.

albino1 commented 5 years ago

@Aris-t2, I put the code you posted into tabs_multiple_lines.css and then re-enabled it in my userChrome.css and disabled the previous alternate MultiRow code in it.

I have MultiRowTabLiteforFx.uc.js in my root chrome folder and I removed userChrome.xml.

I get no MultiRow tabs when I do this. Am I missing something?

John0877 commented 5 years ago

Maybe the xml file? :P

Aris-t2 commented 5 years ago

@albino1 The code I posted is a Javascript and only belongs into a *.js file. The methods you apply Javascript on current Firefox can be found here: https://github.com/Aris-t2/CustomJSforFx It is very important to read every step of the instruction to apply everything correctly.

If something does not work, backup your chrome folder and start over. Always clean the script/startup cache folder after closing Firefox or new script changes won't have any effect.

albino1 commented 5 years ago

I apologize in advance, but I just can't seem to make it work. I created a new portable version of Firefox to test with and am using Method 2 for JS files. I've deleted the files inside of startupCache, and Method 2 clears it automatically anyway. It's possible it's related to using the portable version instead of the full install, but everything else I've tried with that has worked, including the method we originally talked about above with @John0877's dreaded XML file ;)

I'm testing in Windows. Here's my setup after attempting to use Method 2:

Firefox Portable Root Folder:

/App
/Data
/defaults
/Other
FirefoxPortable.exe
config.js

Firefox /chrome Folder:

/config
/css
/images
/userChrome
userChrome.css
userContent.css
userChrome.js

Inside of the userChrome folder is:

userChromeJS.js
userChromeJSutilities.js
zzzz-MultiRowTabLiteforFx.uc.js

Here's a gist of the zzzz-MultiRowTabLiteforFx.uc.js that I copy and pasted from your post above, it should be identical, I didn't change anything:

https://gist.github.com/albino1/699a480b03fffacd91b3e9ab9d9dbec2

Inside userChrome.js I've added this line:

userChrome.import("/userChrome/zzzz-MultiRowTabLiteforFx.uc.js", "UChrm");

In userChrome.css I originally disabled tabs_multiple_lines.css thinking it was now covered by the JS file, but I didn't get any multirow functionality with it disabled. If I enable it then the dragging and dropping between rows doesn't work and it acts weird with things moving around a bit wildly.

Sorry for such a long post, I just want to make sure I'm not missing anything obvious. Any ideas what I'm doing wrong?

Aris-t2 commented 5 years ago

From this projects \method 2\firefox\ folder copy defaults folder and config.js file to Firefox main directory (where the Firefox executable is).

You have to post the files where the "firefox.exe" is (\App\firefox\ and \App\firefox64) not the "FirefoxPortable.exe".

albino1 commented 5 years ago

You have to post the files where the "firefox.exe" is (\App\firefox\ and \App\firefox64) not the "FirefoxPortable.exe".

Okay, that was super dumb of me! It totally works now, thanks so much, I genuinely appreciate the help.

Crybal commented 5 years ago

So,up to now I ve managed to set custom colors to tabs (even the "unread" option!),I have multirow,tabs, dragging works,scrolling (mouse wheel) through multiple rows works.But I am wondering...I am on ESR 60.3...can I go on to nightly,developer or any other newer version without changing any of the above?

Aris-t2 commented 5 years ago

The "unread" state does not exist on Nightly, beta or current release channel and I have not tested mouse wheel scrolling, but scripts and CSS styles I posted above work fine on current Nightly builds.

sp00n commented 5 years ago

I'm having problems to get this to work under FF66 Developer. It seems the .scrollbox-innerbox element has been removed, the tabs are now directly within the .arrowscrollbox-scrollbox element. But when I apply the flex properties to it, the navigation bar doesn't move down when a new row of tabs appears, i.e. it stays on top of the second row.

Maybe somebody already found a solution for this?

// Edit Ok, it seems I forgot that I customized the CSS a bit with my previous CSS solution, which didn't have the drag'n'drop fix, so it was a bit of a mash-up. After more testing it seems that the first solution still works (_CustomCSSforFx tabs_multiplelines.css + drag fix script), but the second one is also affected by the problem (_CustomCSSforFx tabs_multiple_linesv2.css + drag fix script).

I'll post my code anyway, maybe it'll help somebody figure out a solution for their code. It uses an ugly negative margin hack though, for which I couldn't find an alternative as of yet.

:root {
    --tabs-end-position: 50px;
    --tab-min-height_mlt: var(--tab-min-height,32px); /* set own value here, if used without configuration files */
    --mltabs-newtab-height: var(--tab-min-height,32px); /* set own value here, if used without configuration files */
    --tab_min_width_mlt: 100px;
    --tab_max_width_mlt: 250px;
}

/* titlebar buttons */
#titlebar-buttonbox {
    vertical-align: top !important;
    display: block !important;
}

.tabbrowser-arrowscrollbox scrollbox {
    overflow: visible !important;
}

.tabbrowser-arrowscrollbox scrollbox > box {
    display: block !important;
}

/* tab size */
.tabbrowser-tab {
    flex-grow: 1;
    min-height: var(--tab-min-height_mlt) !important;
    max-height: var(--tab-min-height_mlt) !important;
    vertical-align: top !important;
    -moz-box-sizing: border-box !important;
}

.tabbrowser-tab[fadein]:not([pinned]) {
    min-width: var(--tab_min_width_mlt) !important;
    max-width: var(--tab_max_width_mlt) !important;
}

/* 'new tab' tab size */
.tabs-newtab-button {
    vertical-align: bottom !important;
    height: var(--mltabs-newtab-height) !important;
    margin-bottom: -1px !important;
}

@media (-moz-windows-classic) {
    #TabsToolbar #tabbrowser-tabs .tabs-newtab-button {
        margin-bottom: 1px !important;
        height: calc(var(--mltabs-newtab-height) - 2px) !important;
    }
}

/* hide unneeded buttons */
.scrollbutton-up ,
.scrollbutton-down,
#TabsToolbar #alltabs-button{
    display: none;
}

.tabbrowser-arrowscrollbox > .arrowscrollbox-overflow-start-indicator:not([collapsed]),
.tabbrowser-arrowscrollbox > .arrowscrollbox-overflow-end-indicator:not([collapsed]) {
    opacity: 0 !important;
}

#tabbrowser-tabs * {
    overflow-x: none !important;
}

#TabsToolbar[currentset^="tabbrowser-tabs,new-tab-button"] #tabbrowser-tabs .scrollbox-innerbox {
    -moz-padding-end: 0px !important;
}

/* remove crap set by Firefox 58+ */
.tabbrowser-tab::after,
.tabbrowser-tab::before {
    border-left: unset !important;
    border-image: unset !important;
    border-image-slice: unset !important;
    border: 0 !important;
}

#TabsToolbar .titlebar-placeholder[type="pre-tabs"],
#TabsToolbar .titlebar-placeholder[type="post-tabs"] {
    opacity: 0 !important;
}

#main-window[tabsintitlebar] #TabsToolbar .private-browsing-indicator,
#main-window[tabsintitlebar] #TabsToolbar #window-controls,
#main-window[tabsintitlebar] #TabsToolbar .titlebar-spacer[type="pre-tabs"],
#main-window[tabsintitlebar] #TabsToolbar .titlebar-spacer[type="post-tabs"] {
    display: none !important;
}

/* The #tabbrowser-tabs .scrollbox-innerbox element has been removed, the tabs are now directly under the .arrowscrollbox-scrollbox element */
#tabbrowser-tabs .arrowscrollbox-scrollbox {
    flex: 1;
    display: flex !important;
    flex-wrap: wrap;
    min-height: var(--tab-min-height);
    max-height: calc((5 * var(--tab-min-height)) + 1px) !important; /* up to 5 rows */

    /* Ugly hack to make the container the right size and to remove any spacing on the top and bottom of the tabs */
    margin-top: -17px;
    margin-bottom: -15px;
}

/* Needed so the nav bar moves to the bottom */
#tabbrowser-tabs .tabbrowser-arrowscrollbox {
    display: block;
}

.tab-stack {
    width: 100%;
}
Aris-t2 commented 5 years ago

Try 'multiple tab lines v2'. v1 is not compatible to Fx66+ atm.

harmonic77 commented 5 years ago

'css/tabs/tabs_multiple_lines_v2.css' overrides 'css/tabs/alltabs_button_always_visible.css'. When both are selected, the alltabs button is not visible. That's because 'css/tabs/tabs_multiple_lines_v2.css' includes the following:

#TabsToolbar #alltabs-button,
.tabbrowser-tab:not([fadein]){
  display: none;
}
Aris-t2 commented 5 years ago

Unfortunately this happens on purpose. There should be no toolbar buttons on tabs toolbar, if multiple tab lines are used.

harmonic77 commented 5 years ago

I find it handy to use the alltabs button with multiline tabs, but perhaps the majority of people prefer no buttons.

Aris-t2 commented 5 years ago

Remove the #alltabs-button from the above code.

bendover22 commented 5 years ago

Question on tabs_multiple_rows_v2.css and blank space(s) - between either:

Are the blank spaces between multiple tab rows necessary for them to work (using CSS)? Or is the sizing of tab rows vertical scrollbar causing the extra space between rows?

I found this code that eliminates blank space -only- between a single tab row & the navbar . When a 2nd tab row begins, the code stops working & blank spaces appear. `:root { --tab-toolbar-navbar-overlap: 0px !important;/ / fix for full screen mode */ --tab-min-height: 32px !important; } :root #tabbrowser-tabs { --tab-min-height: 32px !important; }

TabsToolbar {height: var(--tab-min-height) !important;} */`

When no "multiple tab rows" code is used, default Fx behavior has tabs touching the top of navbar. But "tabs_multiple_rows_v2.css" creates blank spaces between each row & between the last tab row & top of navbar. For me, the blank spaces between rows vary~ 18 to 20px high. Seems like wasted space. It will also increase browser fingerprint uniqueness, having odd screen height (for web content),

For now, if EVERY one using multiple tab rows had these spaces, with equal heights on same resolution monitors (e.g., 1920 x 1080), then for fingerprintability it'd be best to leave the spaces. But I doubt the blank spaces' heights on ALL1920 x 1080 monitors, etc., will be equal.

tabs-multiple-rows-v2-spaces between tab rows between navbar-2019-02-20

bendover22 commented 5 years ago

Also, with "tabs_multiple_rows_v2.css v2.4.2, is it possible to set the height of tabs toolbar, to set how many tab rows show (w/o scrolling), like either 1, 2 or 3 at a time?