Search code examples
htmlcsscss-gridnwjs

display:grid not working on a button element in chromium and nwjs, works fine in firefox


I'm building an application with nwjs. I had a div displaying some formatted information, and I wanted to have an action performed when I clicked on it. Then, I wanted to add the ability to tab to it and hit space or enter to select it. When I was looking up how to do that, I discovered that the approach I was doing was wrong, and it was better to use either <input type='button'> or <button type='button'> instead because it makes the code more readable, makes accessibility features work better, and already has the keyboard behavior that I want built in.

Out of those two, I discovered that supposedly, <input type='button'> is a void element, meaning that it cannot contain more elements itself (which seems to be correct from my testing), while <button type='button'> can contain elements. Because I'm using it to replace a div that contained more nested elements, I chose <button type='button'>. The type='button' is there because I don't have a form and don't want any submitting to be attempted. event.preventdefault() is supposed to prevent submitting, but I'd rather do it the right way.

Switching the <div>s with <button type='button'> also needs two additional css rules to maintin the same appearance: border: transparent; and width: 100%;. However, it for some strange reason breaks the horizontal arrangement I had before with CSS grid, reverting to the default vertical stacking as if I did not have display:grid. I cannot figure out why that is. Someone told me to try inline-grid, and that doesn't work either. I opened the layouts in a chromium browser, and confirmed that the one with divs also works there, and the one with buttons is also broken there. However, the layout works 100% as expected in Firefox.

What follows is simplified code that still displays the issue, based on the code present in my application. The working code that uses divs is:

<!DOCTYPE html>
<html>

<head>
    <title>working, with divs</title>
    <style>
        .outer {
            display: grid;
            grid-template-columns: 10em auto 10em;
            background-color: lightgray;
            padding: 1em 0;
            border-radius: 1em;
            margin-bottom: 0.25em;
        }

        .inner {
            display: flex;
            align-items: center;
            justify-content: center;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <div class='outer'>
        <div class='inner'>
            aaa
        </div>
        <div class='inner'>
            bbb
        </div>
        <div class='inner'>
            ccc
        </div>
    </div>
    <div class='outer'>
        <div class='inner'>
            aaa
        </div>
        <div class='inner'>
            bbb
        </div>
        <div class='inner'>
            ccc
        </div>
    </div>
    <div class='outer'>
        <div class='inner'>
            aaa
        </div>
        <div class='inner'>
            bbb
        </div>
        <div class='inner'>
            ccc
        </div>
    </div>
</body>

</html>

and the code that uses <button type='button'> that works in firefox but not Chromium or nwjs is:

<!DOCTYPE html>
<html>

<head>
    <title>broken, with buttons</title>
    <style>
        .outer {
            display: grid;
            grid-template-columns: 10em auto 10em;
            background-color: lightgray;
            padding: 1em 0;
            border-radius: 1em;
            margin-bottom: 0.25em;
            border: transparent;
            width: 100%;
        }

        .inner {
            display: flex;
            align-items: center;
            justify-content: center;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <button type='button' class='outer'>
        <div class='inner'>
            aaa
        </div>
        <div class='inner'>
            bbb
        </div>
        <div class='inner'>
            ccc
        </div>
    </button>
    <button type='button' class='outer'>
        <div class='inner'>
            aaa
        </div>
        <div class='inner'>
            bbb
        </div>
        <div class='inner'>
            ccc
        </div>
    </button>
    <button type='button' class='outer'>
        <div class='inner'>
            aaa
        </div>
        <div class='inner'>
            bbb
        </div>
        <div class='inner'>
            ccc
        </div>
    </button>
</body>

</html>

Solution

  • Apparently, because <button> tags cannot be implemented with pure CSS, only some CSS rules work on them on certain browsers, and most display: settings are among the CSS rules that do not work. Chromium was one of the browsers that this doesn't work on, until Chromium 83 which was released less then a month ago as of writing this, and Firefox was not. In fact, now that I've restarted my Chromium, my broken layout now works correctly. However, nwjs did not seem to be updated to chromium 83 when I started troubleshooting this. However, as of earlier this week, it should be fixed on nwjs too.

    I actually fixed my code with a workaround before discovering that chromium and nwjs no longer need said workaround and I just had to update. Just in case you need to support an older version of Chromium than 83, the workaround is to have a span tag inside the button which you apply the grid layout to. Code:

    <!DOCTYPE html>
    <html>
    
    <head>
        <title>problem fixed</title>
        <style>
            .outer-btn {
                background-color: lightgray;
                padding: 1em 0;
                border-radius: 1em;
                margin-bottom: 0.25em;
                border: transparent;
                width: 100%;
                border: 0;
            }
    
            .outer-layout {
                display: grid;
                grid-template-columns: 10em auto 10em;
                width: 100%;
                margin: 0;
                border: 0;
                padding: 0;
            }
    
            .inner {
                display: flex;
                align-items: center;
                justify-content: center;
                overflow: hidden;
            }
        </style>
    </head>
    
    <body>
        <button type='button' class='outer-btn'>
            <span class='outer-layout'>
                <div class='inner'>
                    aaa
                </div>
                <div class='inner'>
                    bbb
                </div>
                <div class='inner'>
                    ccc
                </div>
            </span>
        </button>
        <button type='button' class='outer-btn'>
            <span class='outer-layout'>
                <div class='inner'>
                    aaa
                </div>
                <div class='inner'>
                    bbb
                </div>
                <div class='inner'>
                    ccc
                </div>
            </span>
        </button>
        <button type='button' class='outer-btn'>
            <span class='outer-layout'>
                <div class='inner'>
                    aaa
                </div>
                <div class='inner'>
                    bbb
                </div>
                <div class='inner'>
                    ccc
                </div>
            </span>
        </button>
    </body>
    
    </html>