Search code examples
flexboxbootstrap-4fontello

Bootstrap 4 - showing a list of items with texts and icons correctly


Using Bootstrap 4 I can create a list of list-items. Each list-item contains a text and a button with an icon. The icon is taken from Fontello.

On mobile screens (XS media) sometimes the button does not take the icon as button-content. The result is a very small button that does not contain the icon. This looks like on a mobile device:

enter image description here

On Chrome on my Desktop (F12, XS device) the result is as expected.

A diagnosis is: When I add a number of rows, then vertical size of the list-item gets smaller. Adding 10 items, and the list-item is just a few mm high! So, the size of the list-item gets less high, the button gets less high. Has this to do with 'flexbox'?

Why is this so? I know that when you omit to put anything (or any text) in the button, the button will remain very small. How to repair this?

The code for the button (inside Angular 6)

<ul class="list-group" id="cachesOnHikeList">
    <li class="list-group-item d-flex flex-row" *ngFor="let cacheonhike of cachesonhike">
        <div class="flex-grow-1">{{ cacheonhike.name| slice:0:22 }}</div>
        <button type="button" class="btn btn-warning btn-sm" (click)="removeGeocache( cacheonhike.gcid)"><i class="icon-cancel-circled"></i></button>
    </li>
</ul>

The 'cachesOnHikeList' CSS class is:

#cachesOnHikeList {
  /*max-height: 250px;*/
  max-height:35vh;
  overflow:auto;
  overflow-y:scroll;
}

Plan-B does not work either. This code (with 2 characters added as button text) produces the same results:

<button type="button" class="btn btn-warning btn-sm px-1" 
(click)="removeGeocache( cacheonhike.gcid)">&nbsp;<i class="icon-cancel-circled"></i>&nbsp;</button>

Plan-C: Adding a 'real' character as button text does not help. The 'X' is shown below the small button. The button is similar to the ones on the screenshot.

<button type="button" class="btn btn-warning btn-sm px-1 font-weight-bold" 
(click)="removeGeocache( cacheonhike.gcid)">X</button>

Solution

  • The problem of the small buttons may be caused by (my/the) use of flexbox in combination with a scrollable list-groups

    Solution 1:

    Replace the flexbox solution with the BS4 grid.

    <ul class="list-group" id="cachesOnHikeList">
        <li class="list-group-item" *ngFor="let cacheonhike of cachesonhike">
            <div class="row">
                <div class="mr-auto">{{ cacheonhike.naam | slice:0:22 }}</div>
                <button type="button" class="btn btn-warning btn-sm font-weight-bold col-2 col-sm-1 px-1" (click)="removeGeocache( cacheonhike.gcid)">X</button>
            </div>
        </li>
    </ul>
    

    Solution 2: responsive BS4 table

    Using a Bootstrap 4 table that is Responsive. In this case the width of the columns is determine automatically by Bootstrap.

    <div class="row mt-2">
        <div class="listMaxEntries">
            <div class="table-responsive">
                <table class="table table-bordered">
                    <thead>
                    <tr>
                        <th>GcId</th>
                        <th>Naam</th>
                        <th class="d-none d-sm-table-cell">Type</th>
                        <th class="d-none d-md-table-cell">Actief</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr *ngFor="let geocache of geocachesPage.geocaches"
                        (click)="saveGeocacheInApplicationDataAndEditIt( geocache)">
                        <td>{{ geocache.gcid | slice:0:9 }}</td>
                        <td>{{ geocache.naam }}</td>
                        <td class="d-none d-sm-table-cell">{{ geocache.type }}</td>
                        <td class="d-none d-md-table-cell">{{ geocache.actief }}</td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
    

    Solution 3: BS4 table with Flexbox.

    Using this solution you can specify the column widths. In this case the row height is good!

    <div class="row mt-2">
        <div class="listMaxEntries">
            <table id="productSizes" class="table">
                <thead>
                <tr class="d-flex">
                    <th class="col-3 col-md-2">GcId</th>
                    <th class="col-9 col-sm-7 col-md-5">Name</th>
                    <th class="col-sm-3 d-none d-sm-table-cell">Type</th>
                    <th class="col-md-2 d-none d-md-table-cell">Actief</th>
                </tr>
                </thead>
                <tbody>
                <tr *ngFor="let geocache of geocachesPage.geocaches" class="d-flex"
                    (click)="saveGeocacheInApplicationDataAndEditIt( geocache)">
                    <td class="col-3 col-md-2">{{ geocache.gcid | slice:0:9 }}</td>
                    <td class="col-9 col-sm-7 col-md-5">{{ geocache.naam }}</td>
                    <td class="col-sm-3 d-none d-sm-table-cell">{{ geocache.type }}</td>
                    <td class="col-md-2 d-none d-md-table-cell">{{ geocache.actief }}</td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>
    

    Enjoy Bootstrap 4 -- what a very nice package!