Class Name Buttons

  • What?
    After the change when the name of the button is no longer in the class from version 2.4, many mods are corrupted and cannot be edited.
    This is a mod that adds class names that have been removed in version 2.4.


    • The names that this mod adds may not be the same as in previous versions
    • Currently only the names for the buttons on the address bar and status bar can be added


    Class Name Buttons

    You can learn how to install here


     * Class Name Buttons
     * Written by Tam710562
    window.gnoh = Object.assign(window.gnoh || {}, {
      override: function (obj, functionName, callback, conditon, runbefore) {
        this._overrides = this._overrides || {};
        let subKey = '';
        try {
          if (obj.ownerDocument === document) {
            this._overrides._elements = this._overrides._elements || [];
            const element = this._overrides._elements.find(function (item) {
              return item.element === obj;
            let id;
            if (element) {
              id =;
            } else {
              id = this.generateUUID( (item) {
                element: obj,
                id: id
            subKey = '_' + id;
        } catch (e) { }
        const key = functionName + '_' + + subKey;
        if (!this._overrides[key]) {
          this._overrides[key] = [];
          obj[functionName] = (function (_super) {
            return function () {
              let result;
              let conditon = true;
              for (let i = 0; i < gnoh._overrides[key].length; i++) {
                conditon = conditon && (typeof gnoh._overrides[key][i].conditon !== 'function' && gnoh._overrides[key][i].conditon !== false || typeof gnoh._overrides[key][i].conditon === 'function' && !!gnoh._overrides[key][i].conditon.apply(this, arguments));
                if (conditon === false) {
                if (gnoh._overrides[key][i].runbefore === true) {
                  gnoh._overrides[key][i].callback.apply(this, arguments);
              if (conditon) {
                result = _super.apply(this, arguments);
              for (let i = 0; i < gnoh._overrides[key].length; i++) {
                if (gnoh._overrides[key][i].runbefore !== true) {
                  gnoh._overrides[key][i].callback.apply(this, arguments);
              return result;
          callback: callback,
          conditon: conditon,
          runbefore: runbefore
        return key;
      getReactEventHandlersKey: function (element) {
        if (!this.reactEventHandlersKey) {
          if (!element) {
            element = document.getElementById('browser');
          } else if (typeof element === 'string') {
            element = document.querySelector(element);
          if (!element || element.ownerDocument !== document) {
          this.reactEventHandlersKey = Object.keys(element).find(function (key) {
            return key.startsWith('__reactEventHandlers');
        return this.reactEventHandlersKey;
      timeOut: function (callback, conditon, timeout) {
        setTimeout(function wait() {
          let result;
          if (!conditon) {
            result = document.getElementById('browser');
          } else if (typeof conditon === 'string') {
            result = document.querySelector(conditon);
          } else if (typeof conditon === 'function') {
            result = conditon();
          } else {
          if (result) {
          } else {
            setTimeout(wait, timeout || 300);
        }, timeout || 300);
    (function () {
      const langs = {
        stop: chrome.i18n.getMessage('verb_4__83_top0')
      function changeLoading(buttonReload) {
        gnoh.override(buttonReload.firstChild, 'setAttribute', function (name, value) {
          if (name === 'title') {
            if (value === langs.stop) {
            } else {
      function classNameButtons(browser) {
        var reactEventHandlersKey = gnoh.getReactEventHandlersKey(browser);
        if (reactEventHandlersKey) {
          var skipVersionInfo = !browser.classList.contains('biscuit-mode');
          document.querySelectorAll('.toolbar-droptarget').forEach(function (toolbar) {
            var skipTaskList = false;
            var buttonToolbars = [], function (el) {
              return typeof el[reactEventHandlersKey] !== 'undefined';
            var buttonNameToolbars = toolbar[reactEventHandlersKey] (el) {
            if (skipVersionInfo === false && buttonNameToolbars.length - buttonToolbars.length === 1 || skipVersionInfo === true && buttonNameToolbars.length - buttonToolbars.length === 2) {
              skipTaskList = true;
            buttonNameToolbars = buttonNameToolbars.filter(function (name) {
              return !(skipVersionInfo && name === 'VersionInfo' || skipTaskList && name === 'TaskList');
            for (var i = 0; i < buttonToolbars.length; i++) {
              var button = buttonToolbars[i];
              var className = buttonNameToolbars[i].replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase();
              if (className) {
                if (className === 'reload') {
        browser.dataset.classNameButtons = true;
      gnoh.timeOut(classNameButtons, '#browser');

  • @tam710562 Truly amazing. Thanks a lot.

  • Great job @tam710562 ! Thank you for this.

  • Cool, so maybe I can keep the customized buttons after all ^^,

  • Nice project, could come in handy in future!

  • @raed I think .reload.loading is not covered yet by the mod.

    This mod really saved the round buttons 0_1554156273177_16573c47-a477-4606-bac3-b908a7dc0894.png

    //edit: Add reload-loading[=stop button] (with workaround)

    .button-toolbar.back > button > svg path {
      d: path('M293.004,78.525C249.64,3.436,153.62-22.295,78.531,21.061C3.436,64.411-22.296,160.443,21.068,235.542     c43.35,75.087,139.375,100.822,214.465,57.467C310.629,249.648,336.365,153.621,293.004,78.525z M219.836,265.802     c-60.075,34.685-136.894,14.114-171.576-45.969C13.57,159.762,34.155,82.936,94.232,48.253     c60.071-34.683,136.894-14.099,171.578,45.979C300.495,154.308,279.908,231.118,219.836,265.802z M211.986,141.328h-65.491     l17.599-17.603c6.124-6.129,6.124-16.076,0-22.197c-6.129-6.133-16.078-6.133-22.207,0l-44.402,44.4     c-6.129,6.131-6.129,16.078,0,22.213l44.402,44.402c6.129,6.128,16.078,6.128,22.207,0c6.124-6.131,6.124-16.077,0-22.201     l-17.606-17.601h65.499c8.669,0,15.697-7.041,15.697-15.701v-0.008C227.683,148.353,220.655,141.328,211.986,141.328z');
      transform: scale(.08); /*backbutton*/
    .button-toolbar.forward > button > svg path {
      d: path('M216.545,145.893l-44.374-44.368c-6.131-6.133-16.076-6.133-22.205,0h0.008c-6.129,6.121-6.129,16.068,0,22.197     l17.589,17.603h-65.485c-8.666,0-15.701,7.033-15.701,15.701v0.008c0,8.668,7.035,15.701,15.701,15.701h65.493l-17.597,17.601     c-6.129,6.132-6.129,16.069,0,22.201c6.122,6.136,16.066,6.136,22.197,0l44.41-44.402c6.128-6.127,6.128-16.078,0-22.209     C216.57,145.909,216.554,145.9,216.545,145.893z M235.533,21.057C160.438-22.291,64.414,3.433,21.063,78.521     c-43.356,75.096-17.633,171.119,57.464,214.483c75.087,43.353,171.119,17.625,214.476-57.47     C336.364,160.443,310.62,64.408,235.533,21.057z M265.801,219.83c-34.688,60.079-111.503,80.657-171.574,45.973     C34.158,231.118,13.565,154.304,48.25,94.229C82.932,34.151,159.756,13.567,219.828,48.25     C279.899,82.934,300.485,159.763,265.801,219.83z');
      transform: scale(.08); /*forwardbutton*/
    .button-toolbar.reload > button > svg path {
      d: path('M92.779,129.86c-6.431,2.594-13.446,4.038-20.807,4.038c-14.974,0-28.517-5.924-38.572-15.492l4.604-2.73     c3.234-1.913,3.204-4.962-0.066-6.807L15.48,96.183c-3.27-1.848-5.982-0.267-6.059,3.532l-0.534,26.412     c-0.074,3.802,2.481,5.332,5.711,3.415l6.369-3.768c12.777,13.596,30.865,22.145,51,22.145c7.313,0,14.349-1.153,20.961-3.254     C107.014,140.91,100.006,126.894,92.779,129.86z M16.408,70.271c3.066-22.703,19.748-41.049,41.547-46.672V9.154     C30.509,14.725,8.914,36.336,3.327,63.775C-1.619,81.338,15.903,77.833,16.408,70.271z M64.144,35.707L86.96,22.045     c3.316-1.988,3.323-5.226,0.014-7.228L63.95,0.883c-3.311-1.999-5.985-0.49-5.966,3.381l0.121,28.034     C58.121,36.168,60.826,37.695,64.144,35.707z M143.078,102.952l-11.95-7.074l7.265,4.196c2.345-6.995,3.665-14.459,3.665-22.248     c0-21.245-9.465-40.278-24.403-53.129c-7.135-6.437-17.647,0.572-10.916,9.154C119.711,44.122,128.041,60,128.041,77.83     c0,5.198-0.767,10.212-2.088,14.985l-6.167-3.648c-3.213-1.902-5.77-0.335-5.715,3.498l0.407,26.34     c0.059,3.84,2.738,5.448,5.982,3.598l22.562-12.857C146.267,107.897,146.291,104.854,143.078,102.952z');
      transform: scale(.17); /*reload*/
    .button-toolbar.reload[title="Stop"] > button > svg path { /*use your lang title*/
      d: path('M255,0C114.75,0,0,114.75,0,255s114.75,255,255,255s255-114.75,255-255S395.25,0,255,0z M382.5,346.8l-35.7,35.7 	L255,290.7l-91.8,91.8l-35.7-35.7l91.8-91.8l-91.8-91.8l35.7-35.7l91.8,91.8l91.8-91.8l35.7,35.7L290.7,255L382.5,346.8z');
      transform: scale(.044); 
      transform-origin: 1px 1px; /*stop*/

  • @raed This mod currently does not support .reload.loading
    If you use English you can use

    old: button.button-toolbar.reload.loading
    new: .button-toolbar > button[title="Stop"]

  • @raed The title attribute has moved to the enclosing div in the latest versions.

  • Moderator

    @tam710562 Job well done. Congrats.

    There are two shots:

    1. My CSS after installing daily builds. I tried some tweaks, as it's beyond my knowledge


    1. After talking to @raed, he suggested your JS. As you can see, it's perfect


    The Mail tab erases all your work. That's just a report, I am not demanding any fix.


    Edited: The post I submitted:

  • A new update to fix a bug in vivaldi version 2.6

  • Moderator

    Thank you.

  • @tam710562

    seems to be broken on the latest snapshot - then again it might be me but i dont think so

  • Moderator

    I can not confirm.

  • @lamarca said in Class Name Buttons:

    I can not confirm.

    odd - as i said it could be me but if i keep this mod the snapshop will not load just locks up at a grey screen with the logo in the centre - remove the js and it works but the custom navigation items dont show [obviously]

    will try again with other snapshots - not used one for a while

    go back to a general release with the same code and all works - as i say odd

  • @adacom Are you sure it's right this mod? I don't see any reason why it should break anything.

  • @potmeklecbohdan

    am i sure - no i am not - at this moment all i know is that all my css and js mods work and do whats expected in a standard version - if i add a snapshot version things go wrong - removing this js solves the problem BUT not every time - even with this mod removed i still see a grey screen on bootup sometimes

    but to state again all the mods i have work 100% with a standard version

    i came here to ask if anyone had seen the same as me - i asked thinking it could be me as no one had asked the same question and the latest snapshot has been around a few days

    i have also gone back one version of the snapshot and get the same problem so am inclined to point the finger at something i have done but am confused as the problem only occurs with snapshots not standard versions

  • @adacom Ah, I was too inconcrete: does Vivaldi work when you disable all other mods (both JS and CSS) and keep only this one?

    And the gray screen at startup is not a problem itself, but it should disappear after some moments.

  • @potmeklecbohdan said in Class Name Buttons:

    @adacom Ah, I was too inconcrete: does Vivaldi work when you disable all other mods (both JS and CSS) and keep only this one?

    And the gray screen at startup is not a problem itself, but it should disappear after some moments.

    a snapshot works perfectly with all my css mods - some are linked to js so dont do anything if the js mods are disabled

    if i add the js mods one at a time all works fine until i add this one - when i add this mod it seems random if vivaldi opens - if it does the navigation icons that this links to do not show they are default

    on other bootups i get a grey screen - if i leave it it has never gone away

    and as said this does not happen with a standard version

    when i install the snapshot i am using a copy of my user data from the standard install - could that be the problem are they not compatible

    thats not strictly answered your question - i have not tried it like that - will do later

  • well i have it working - standard version of Vivaldi worked perfectly - install latest snapshot and all i got was a grey screen that would not go away - both using common user data

    so start from clean install on standard build and build user data adding all css and js mods and all worked as expected

    port that user data file dir to a snapshot install and all is good

    conclusion - i have no idea - the old user data was good i thought but obviously something was wrong

  • @tam710562
    How do you get interface elements to be displayed in the Devtools? I can see only content in there.

Log in to reply

Looks like your connection to Vivaldi Forum was lost, please wait while we try to reconnect.