Bootstrap 4讓按鈕在行動裝置時期才轉換成btn-block模式

Bootstrap 4的Grid系統中,有關於按鈕的配置讓我很困擾,就是當系統在同一列div(col-12)內提供的多數量的按鈕並且讓其自適性化大小RWD流動排列,但又想要讓它在行動裝置上變成btn-block方式的排列,以目前的Bootstrap Class提供的類別來說不太可能辦的到。

需求:讓按鈕群能夠流動性的排列

前端UI布局目標就是要讓為數眾多的按鈕,可以在桌上型電腦模式下,依照按鈕的字面長度自適性化的延伸或縮短,但當至手機裝置時,就將其轉換成btn-block模式,讓其可以在手機模式下每個按鈕一行行的條列顯示。

<div class="text-center col-12 mt-4">
  <a href="#" class="mt-1 btn btn-lg btn-primary"><i class="fab fa-apple fa-fw"></i> 按鈕A</a>
  <a href="#" class="mt-1 btn btn-lg btn-danger"><i class="fab fa-aws fa-fw"></i> 按鈕B</a>
  <a href="#" class="mt-1 btn btn-lg btn-dark"><i class="fab fa-microsoft fa-fw"></i> 按鈕C</a>
  <a href="#" class="mt-1 btn btn-lg btn-warning"><i class="fab fa-docker fa-fw"></i> 按鈕D</a>
  <a href="#" class="mt-1 btn btn-lg btn-success"><i class="fab fa-github fa-fw"></i> 按鈕E</a>
</div>

這樣做的好處是在一般寬度夠的情況,可以如同下圖這樣排列:

但在按鈕數量暴增時,按鈕會自動被擠下去(圖片中用寬度來模擬按鈕變多的情況),這對一個工程師來說是很重要的,美醜一回事,但系統功能按鈕不可消失啊!

好了,但在手機這麼小的寬度下,這樣的流動布局已經無意義了。這時候我們會需要每一列一個按鈕的布局,當你去查詢Bootstrap 4的文件時,它會叫你使用btn-block類別,但「一次btn-block,終身btn-block」啊!內建類別沒有因應螢幕的寬度才btn-block的解法。

經過搜尋,Bootstrap作者群已經明確的表示(btn-block class for different breakpoints #13647)那是你家的事情,最後一句話還給你放話挑釁哩!大家也可以從討論串中看出,到2014年就Closed掉的Issues到2019年還有人在那邊+1,表示大家都很需要這個需求啊!

mdo commented on 23 May 2014
@cvrebert We make one, folks will want all the rest of them. Plus it's a class that can be mixin-ed for folks who want it responsive. That doesn't account for every use case, but I don't think that's our goal anyway.

Make sense or am I being a stickler?

生命總會自己找到出口

如果你的HTML裡面的按鈕是A標籤,那恭喜可以使用下列的類別套入解決,答案如下:

d-block d-md-inline-block

套入後的結果,果然利用BS4 CSS的inline-block類別巧妙地解決掉了。在低於md寬度下的按鈕一律都被d-block化了。

但是如果你的HTML裡面的按鈕是傳統的button標籤,帶有不同的type(button、submit),這下問題又出現了。

<div class="text-center col-12 mt-4">
  <button type="submit" class="mt-1 btn btn-lg btn-primary d-block d-md-inline-block"><i class="fab fa-apple fa-fw"></i> 按鈕A</button>
  <button type="button" class="mt-1 btn btn-lg btn-danger d-block d-md-inline-block"><i class="fab fa-aws fa-fw"></i> 按鈕B</button>
  <button type="submit" class="mt-1 btn btn-lg btn-dark d-block d-md-inline-block"><i class="fab fa-microsoft fa-fw"></i> 按鈕C</button>
  <button type="button" class="mt-1 btn btn-lg btn-warning d-block d-md-inline-block"><i class="fab fa-docker fa-fw"></i> 按鈕D</button>
  <button type="submit" class="mt-1 btn btn-lg btn-success d-block d-md-inline-block"><i class="fab fa-github fa-fw"></i> 按鈕E</button>
</div>

button標籤沒有辦法因為d-block類別的引入而產生寬度的變化,從下圖中可以發現是block化了沒錯,但是寬度還是依照文字的長度適性化了。

祭出大招:依照media加入新的CSS類別

在Medium裝置(≥768px)之後,讓自訂的「btn-block-sm」CSS類別生效,並將套用該類別的HTML元素一律進行block設定與寬度的變更,也就是SM(Small)、XS(Extra small)兩種模式都會中獎。

<style>
  @media (max-width: 767px)
  {
    .btn-block-sm {
      display: block;
      width: 100%;
    }
  }
</style>

完工後,button們已經乖乖地聽我們的話,在sm、xs模式下,乖乖地把寬度擴展到100%了。

瞧瞧HTML、CSS、JS發展迄今的這場鬧劇,可憐哪~

Boostrap BS3 BS4 BS5 Button btn-block btn-block-xs btn-block-sm CssHack