Search code examples
cssflexboxcss-gridgrid-layout

How to set all css-grid (or flex) elements same size?


I'm trying to create a new rich text editor for my web application (student budget), and everything else works fine except the grid/flex layout when trying to set all the buttons to the same size.

Here is how to editor currently looks. Notice how the last icon is much larger than the others?

In addition to having that problem, the number of buttons in the row will be unknown, as the API I'm building allows to define which properties this editor will have

After searching from multiple places on the web all the results I've found have given me the same results as the current css I already have. This is the first external source I've tried. Trying the flexbox will yield similar results

If something is missing from the code below or you want to straight up try the cleaned markup, please visit jsfiddle

HTML output from javascript which the css markup will modify

<ttace data-empty="Type something to create a post" class="TTACEEditor">
  <div class="ttace controls">
    <div>
        <div>
            <button title="Bold"><span class="ttace icon bold"></span></button>
            <button title="Italic"><span class="ttace icon italic"></span></button>
            <button title="Strike through"><span class="ttace icon strike-through"></span></button>
            <button title="Underline"><span class="ttace icon underline"></span></button>
            <button title="Insert horizontal rule"><span class="ttace icon hr"></span></button></div>
        <div>
            <button title="Align left"><span class="ttace icon justify-left"></span></button>
            <button title="Align center"><span class="ttace icon justify-center"></span></button>
            <button title="Align right"><span class="ttace icon justify-right"></span></button>
            <button title="Align full"><span class="ttace icon justify-full"></span></button></div>
        <div>
            <button title="Ordered list"><span class="ttace icon ordered-list"></span></button>
            <button title="Unordered list"><span class="ttace icon unordered-list"></span></button>
            <button title="Outdent"><span class="ttace icon indent-left"></span></button>
            <button title="Indent"><span class="ttace icon indent-right"></span></button></div>
        <div>
            <button title="Clear formatting"><span class="ttace icon clear-formatting"></span></button>
        </div>
    </div>
  </div>
  <div class="ttace textarea" contenteditable="true" data-empty="Type something to create a post"></div>
</ttace>

This is the code which uses css-grid as the layout template

.TTACEEditor>.ttace.controls {
    margin: 0;
    padding: 0;
    display: flex;
}

.TTACEEditor>.ttace.controls>div {
    margin: 0 auto;
    padding: 0;
    display: inline-grid;
    grid-auto-flow: column;
    width: 100%;
}

.TTACEEditor>.ttace.controls>div>div {
    display: inline-grid;
    grid-template-rows: auto;
    grid-template-columns: auto;
    grid-auto-flow: column;
}

.TTACEEditor>.ttace.controls>div div button {
    margin: 0 auto;
    display: inline-block;
    height: 100%;
    width: 100%;
    text-align: center;
}

.icon {
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    display: inline-block;
    width: 1.2em;
    height: 1.2em;
}

This is using flex, but the output is very similar with the same problems as the above markup

.TTACEEditor>.ttace.controls {
    margin: 0;
    padding: 0;
    display: flex;
}

.TTACEEditor>.ttace.controls>div {
    margin: 0 auto;
    padding: 0;
    display: flex;
    flex-direction: row;
    width: 100%;
}

.TTACEEditor>.ttace.controls>div>div {
    display: inline-flex;
    flex-grow: 1;
    grid-auto-flow: column;
}

.TTACEEditor>.ttace.controls>div div button {
    color: black;
    margin: 0 auto;
    display: inline-block;
    flex-grow: 1;
    height: 100%;
    background-color: transparent;
    cursor: pointer;
    width: 100%;
    text-align: center;
}

.icon {
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    display: inline-block;
    width: 1.2em;
    height: 1.2em;
}

Solution

  • First of all, since currently no browser supports the proposed css subgrid specification, I would recommend against trying to have equal distribution of items in nested grids.

    Secondly, is the grouping of the icons into sections (creating a nested html structure), that results in a "grid containing multiple grids" a hard requirement? If not, I would highly recommend a flatter structure, because that way the layout can have access to all of the buttons and size them equally.

    Finally, from what I understand, your buttons will only be one row, so using a grid layout is not really suitable, as it was mostly targeted toward 2d layouts, and in your case a good ol flex will do just as well (and will have a better support for wider range of browsers).

    With all that in mind, I have modified your code, the changes can be found in this fiddle