Search code examples
javascripthtmlcssrazorbootstrap-5

How to stop bootstrap 5 button group from centering after click


I have a bootstrap 5 button group inside a modal. I have set height style="overflow-y: auto; max-height: 290px; min-height: 290px;"

When I click on a button inside this modal div the scroll centers to the middle button. I'm trying to get this to stop and just remain where you clicked.

<div id="SelectLMSPlayer" class="modal fade" role="dialog">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">
            <div class="modal-body">
                <div class="row">
                    <label class="mx-auto d-block" style="font-weight: bold; font-size: medium;">Select this weeks player</label>
                    <label class="mt-1"><label class="box lightgray me-1 align-bottom"></label>- Player has been used</label>
                </div>
                <br />

                <div class="form-group mb-4" style="overflow-y: auto; max-height: 290px; min-height: 290px;">
                    <label for="ddlPlayers">WGR - Player</label>
                 
                        <div id="playergroup" class="btn-group-vertical gap-1 btn-group d-flex m-1" role="group">
                                <input type="radio" class="btn-check" name="available" data-wgr="1" id="46046" alt="0" autocomplete="off" value="Scottie Scheffler"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="46046" for="46046"><column>1</column> - <column>Scottie Scheffler</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="2" id="28237" alt="0" autocomplete="off" value="Rory McIlroy"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="28237" for="28237"><column>2</column> - <column>Rory McIlroy</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="3" id="46970" alt="0" autocomplete="off" value="Jon Rahm"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="46970" for="46970"><column>3</column> - <column>Jon Rahm</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="4" id="35450" alt="0" autocomplete="off" value="Patrick Cantlay"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="35450" for="35450"><column>4</column> - <column>Patrick Cantlay</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="5" id="46717" alt="0" autocomplete="off" value="Viktor Hovland"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="46717" for="46717"><column>5</column> - <column>Viktor Hovland</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="6" id="48081" alt="0" autocomplete="off" value="Xander Schauffele"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="48081" for="48081"><column>6</column> - <column>Xander Schauffele</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="7" id="39977" alt="0" autocomplete="off" value="Max Homa"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="39977" for="39977"><column>7</column> - <column>Max Homa</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="9" id="27644" alt="0" autocomplete="off" value="Brian Harman"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="27644" for="27644"><column>9</column> - <column>Brian Harman</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="11" id="51766" alt="0" autocomplete="off" value="Wyndham Clark"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="51766" for="51766"><column>11</column> - <column>Wyndham Clark</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="12" id="34046" alt="0" autocomplete="off" value="Jordan Spieth"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="34046" for="34046"><column>12</column> - <column>Jordan Spieth</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="14" id="34363" alt="0" autocomplete="off" value="Tyrrell Hatton"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="34363" for="34363"><column>14</column> - <column>Tyrrell Hatton</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="15" id="33141" alt="0" autocomplete="off" value="Keegan Bradley"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="33141" for="33141"><column>15</column> - <column>Keegan Bradley</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="17" id="29725" alt="0" autocomplete="off" value="Tony Finau"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="29725" for="29725"><column>17</column> - <column>Tony Finau</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="18" id="55182" alt="0" autocomplete="off" value="Tom Kim"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="55182" for="55182"><column>18</column> - <column>Tom Kim</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="20" id="28089" alt="0" autocomplete="off" value="Jason Day"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="28089" for="28089"><column>20</column> - <column>Jason Day</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="21" id="47504" alt="0" autocomplete="off" value="Sam Burns"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="47504" for="47504"><column>21</column> - <column>Sam Burns</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="22" id="50525" alt="0" autocomplete="off" value="Collin Morikawa"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="50525" for="50525"><column>22</column> - <column>Collin Morikawa</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="23" id="30911" alt="0" autocomplete="off" value="Tommy Fleetwood"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="30911" for="30911"><column>23</column> - <column>Tommy Fleetwood</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="24" id="49960" alt="0" autocomplete="off" value="Sepp Straka"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="49960" for="49960"><column>24</column> - <column>Sepp Straka</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="26" id="32102" alt="0" autocomplete="off" value="Rickie Fowler"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="32102" for="32102"><column>26</column> - <column>Rickie Fowler</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="27" id="39971" alt="0" autocomplete="off" value="Sungjae Im"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="39971" for="39971"><column>27</column> - <column>Sungjae Im</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="29" id="34098" alt="0" autocomplete="off" value="Russell Henley"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="34098" for="34098"><column>29</column> - <column>Russell Henley</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="31" id="39997" alt="0" autocomplete="off" value="Corey Conners"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="39997" for="39997"><column>31</column> - <column>Corey Conners</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="35" id="31646" alt="0" autocomplete="off" value="Emiliano Grillo"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="31646" for="31646"><column>35</column> - <column>Emiliano Grillo</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="37" id="37455" alt="0" autocomplete="off" value="Si Woo Kim"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="37455" for="37455"><column>37</column> - <column>Si Woo Kim</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="44" id="30926" alt="0" autocomplete="off" value="Chris Kirk"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="30926" for="30926"><column>44</column> - <column>Chris Kirk</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="45" id="25493" alt="0" autocomplete="off" value="Nick Taylor"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="25493" for="25493"><column>45</column> - <column>Nick Taylor</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="48" id="47347" alt="0" autocomplete="off" value="Adam Schenk"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="47347" for="47347"><column>48</column> - <column>Adam Schenk</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="51" id="49947" alt="0" autocomplete="off" value="Taylor Moore"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="49947" for="49947"><column>51</column> - <column>Taylor Moore</column></label>
                                <input type="radio" class="btn-check" name="available" data-wgr="53" id="25900" alt="0" autocomplete="off" value="Lucas Glover"/>
                                <label class="btn btn-sm btn-outline-secondary rounded" id="25900" for="25900"><column>53</column> - <column>Lucas Glover</column></label>
                    </div>
                   
                </div>



                <div id="divSelectPlayer">
                    <div class="d-grid gap-2 mt-auto">
                        <button id="btnSelectPlayer" value="" name="" class="btn btn-success">Make Selection</button>
                    </div>
                </div>

            </div>
        </div>
    </div>
</div>

This is how it looks before clicking

Before button group click

And this is what happens no matter which button you click

After button group click

You can see it scrolls to the vertical center of the button group. How can I get this centering action to stop? I've googled my brains out but must not be explaining my problem correctly.

Setting the buttons horizontally doesn't seem to have this effect but I may not be coding it the same. I'm generating the code on .net core 6 and Razor pages.

EDIT: I've copied my button group to the w3schools.com bootstrap button group tester to make sure it wasn't some backend JS code in my app messing with me and the same thing happened there.


Solution

  • The issue appears to be caused by the absolute positioning of the radio buttons. Since they are not relative to the labels, they all stick to the top - making the container scroll to the top, when the label is clicked (because that still puts the focus on the radio buttons, even if they are visually "hidden".)

    Use a different way to hide them, that doesn't involve absolute positioning. You have to be a bit careful with that, so as to not make them unusable for screen-reader users - https://webaim.org/techniques/css/invisiblecontent/ has more details.

    The following, slightly adapted regarding the margins suggested, appears to work fine:

    .btn-check {
      clip: rect(1px, 1px, 1px, 1px);
      clip-path: inset(50%);
      height: 1px;
      width: 1px;
      margin: -3px 0 -2px 0;
      overflow: hidden;
      padding: 0;
      position: relative;
    }
    

    https://jsfiddle.net/o3nsjywx/