如何使用 Bootstrap 搭建更合理的 HTML 結構
前言
Bootstrap 的成功不僅在於其簡單易用,更在於其樣式的規範性以及 HTML 結構的合理性。但是很多人在使用 Bootstrap 時只是依照文檔盲目的復制黏貼,並沒有仔細考慮每個類的用處,也沒有考慮 HTML 結構搭建的是否合理。在平時的工作中,我一直和同事強調,一定要挖掘框架的精髓,盡可能的使用框架本身具有的類實現布局,幾乎所有的 UI 布局都可以使用框架本身完成而不需要編寫額外的冗余的樣式。本文的目的就是介紹如何使用 Bootstrap 搭建常用的布局,並保證布局具有合理的 HTML 結構。不管是傳統開發,還是使用框架,搭建布局的思想是不會變的。本文所有案例均以 Bootstrap 3 為例, Bootstrap 4 變化較大,但也基本適用,需要讀者仔細比對,不可盲目照抄。
合理利用柵格
保證合理嵌套
Bootstrap 柵格類的隨意嵌套是造成 HTML 結構混亂的主要原因,雖然 Bootstrap 的柵格類在隨意嵌套時並不會出現嚴重問題,但會引發潛在的問題,對於細節控是無法容忍的。比如下面的這種常見錯誤嵌套:
<div class="row"> <div class="col-md-6"> <div class="col-md-8">.col-md-8</div> <div class="col-md-4">.col-md-4</div> </div> <div class="col-md-6">.col-md-6</div> </div>
表面看並沒有大問題,但是如果將柵格描邊,就會看出不同,見下面的 CodePen:
See the Pen Bootstrap-demo by Zongbin (@nzbin) on CodePen.
我們必須明白每個 Bootstrap 柵格類的作用。其中 .row
和 .col-*
必須要搭配使用,缺一不可,因為 .row
是為了抵消 .col-*
的 margin 負值,所以並不是可有可無的類。所以,上面例子的正確結構如下:
<divclass="row"> <div class="col-md-6"> <div class="row"> <div class="col-md-8">.col-md-8</div> <div class="col-md-4">.col-md-4</div> </div> </div> <div class="col-md-6">.col-md-6</div> </div>
這是我工作過程中見過的最多的一種錯誤,必須格外註意。
靈活利用柵格偏移
柵格的列偏移 .col-md-offset-*
應該也算是比較常用的布局類,但是我們往往忽視它在大塊版面布局的作用。舉個例子,比如一個登錄框在右側的登錄頁面:
對於表單在右側的布局,實現方式有很多,比如單獨使用 float
類實現偏移,或者使用絕對/相對定位實現。但是更好的方式應該是使用柵格的列偏移實現,因為柵格支持響應式布局。
以下是響應式登錄頁的例子:
See the Pen Bootstrap-demo by Zongbin (@nzbin) on CodePen.
建議在 CodePen 中打開查看效果,因為我的博客內容區較窄,所以只能看到響應式布局的小屏斷點。
雖然柵格布局很好,但在工作中一定要謹慎使用,因為很多不懂前端的設計師或產品會對前端人員吹毛求疵,這樣的話也只能根據具體要求做一些調整了。
水平表單排列
表單中的橫向柵格布局非常常見,Bootstrap 官網也給出了案例,但是對於多列的橫向表單布局會稍顯復雜,過多的柵格嵌套讓人抓狂。但是只要記住一點,布局就會遊刃有余。
通過添加 .form-horizontal
類,表單就可以橫向排布,此時的 .form-group
類就相當於 .row
類,兩者的行為是一樣的,所以此時無需再添加 .row
類。
<form class="form-horizontal"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">Email</label> <div class="col-sm-10"> <input type="email" class="form-control" id="inputEmail3" placeholder="Email"> </div> </div> ... </form>
註意,在 Bootstrap 4 中, .row
類不能省略,需要寫成這樣 .form-group row
才行。其實也沒有什麽區別,都是為了形成 .row > .col-* > .row > .col-* 這種結構。
<form> <div class="form-group row"> <label for="inputEmail3" class="col-sm-2 col-form-label">Email</label> <div class="col-sm-10"> <input type="email" class="form-control" id="inputEmail3" placeholder="Email"> </div> </div> ... </form>
以下是 Bootstrap 3 橫向表單布局的例子:
See the Pen Bootstrap-demo by Zongbin (@nzbin) on CodePen.
上面的例子比官網多了一層柵格,只有在大屏中才能看到效果,這種柵格內的表單嵌套在不熟悉 Bootstrap 的情況下很容易寫亂,但只要記住了上面提到的規則,就可以輕而易舉的寫出來。
靜態表單排列
很多人在看到上面的結構時,幾乎二話不說,就寫出 ul>li 這樣的布局,而且添加諸如 .list
.item
這些無意義的類。依然是開篇提到的,我們必須始終堅持一個原則,盡可能不要隨意添加樣式,探索框架本身具有的類,幾乎都可以找到解決方法。
仔細想想,上面的例子中的布局方式無非就是柵格內的行內表單。所以實現方法非常簡單,完全不用自己編寫樣式。
以下是實時演示,建議在大屏查看效果:
See the Pen Bootstrap-demo by Zongbin (@nzbin) on CodePen.
表格結構
關於表格可以說的並不多,只是建議全部采用響應式表格結構,也就是添加 .table-responsive
元素。因為在實際工作中,表格的列數一般比較多,響應式表格應該是更通用的方案。
<div class="table-responsive"> <table class="table"> ... </table> </div>
先排列,再排行
這條規則只是建議,因為 HTML 的塊級元素默認是占一行,所以先排列可以減少 HTML 的結構,使結構更簡潔。另一方面,對於高度不同的元素,哪怕是很小的差距,都會出現布局的錯位,見下面的 CodePen:
See the Pen Bootstrap-demo by Zongbin (@nzbin) on CodePen.
為了解決這個問題,必須在每一行都添加 .row
。不過在某些時候,我們也不得不這樣寫。
<div class="row"> <div class="col-xs-6"> ... </div> <div class="col-xs-6"> ... </div> </div> <div class="row"> <div class="col-xs-6"> ... </div> <div class="col-xs-6"> ... </div> </div> ...
如果是先排列,就不用擔心上面的問題,這種排列方式有點像瀑布流。
<div class="row"> <div class="col-xs-6"> ... ... </div> <div class="col-xs-6"> ... ... </div> </div>
這條建議需要根據實際的需求調整,需要和設計師以及產品做好溝通,不然肯定面臨返工的危險。只能說從結構上而言,先排列會好一些。假如使用 Flex 布局的話,就可以很好地解決這個問題了。
總結
先說點題外話,我一直覺得優秀的網頁作品不是或者不全是設計師決定的,甚至不應該由設計師決定,因為國內的設計師真正懂前端的還是少數,而且設計風格難以緊跟潮流。設計師和產品經常將交互掛在嘴邊,但是他們提出的很多交互形式在我們前端人員看來都是網頁必備的基本要素,並不是一個亮點。反觀國外,設計師懂前端甚至很精通,前端開發者也是設計師或者交互設計師,每個人都是復合型人才,這是值得我們學習的方面。
言歸正傳,本文主要介紹了在使用 Bootstrap 時如何搭建更合理的結構,然而在實際工作中,不管我們用不用框架,都應該盡可能的精簡並規範化 HTML 結構,這是前端開發人員應該養成的良好習慣。另外說明一點,因為框架是很多問題的抽象,所以在通用性的前提下,不可避免的會有一些冗余的 HTML 結構。
我在開篇就強調盡量不要編寫冗余的樣式,但是如果真的不能滿足布局要求時,我們首先應該使用 helper 解決,Bootstrap 3 的 helper 並不豐富,而 Bootstrap 4 則添加了大量的 helper 輔助類。我在之前也寫了一篇關於 helper 的文章《如何編寫通用的 Helper Class》,感興趣的話可以看一看。
如何使用 Bootstrap 搭建更合理的 HTML 結構