最近在工作中遇到了一些不常用的布局,很多使用 CSS table 屬性,並結合 ::before,::after 偽元素完成了,使得 HTML 的結構相對更簡單,更具有語義性。當 HTML 結構越清晰,越有規律時,便於閱讀,循環套數據時也可以少很多的判斷。
一、有下面這樣一個設計,上面是標題,中間是流程圖,下面是電話。

很明顯:
1. 這個設計圖中的所有內容都是居中顯示的;
2. 標題部分,分為了中文和英文,下面有兩條線,還有一個菱形;
3. 中間部分,流程的每一項,除了最后一項外,每一項下面都有一個箭頭指向;
4. 電話部分,左右兩邊各有一條線,且各有一個菱形;
這個設計圖的實現中,現在我們不使用圖片,依靠 CSS 中 table,定位,偽元素來完成。
- 首先,根據效果圖寫出沒有多余的標簽的 HTML 結構:

注:其它 li 標簽和第一個 li 標簽的結構一致,只是 icon 類名和文本不同。
- 思考:
.heading 的布局
1. 寬度不能固定,得根據文本內容來適應;2. 在父容器中需要水平居中; 3. 線的寬度可以根據內容的寬度來確定; 4. 菱形可以通過正方形順時針或者逆時針旋轉 45° 獲得。
.heading { position: relative; display: table; margin: 0 auto 40px; padding: 0 80px 18px; color: #333; &::before, &::after { content: ""; position: absolute; bottom: 0; width: calc(50% - 20px); height: 1px; background-color: #999; } &::before { left: 0; } &::after { right: 0; } strong { display: block; text-align: center; } .cn { color: #333; line-height: .9; font-family: "webfont", Arial, sans-serif; // 這里使用的網絡安全字體 font-weight: normal; font-size: 20px; margin-bottom: 10px; } .en { color: #666; font-family: "webfont", Arial, sans-serif; font-weight: lighter; text-transform: capitalize; font-size: 14px; line-height: 1; &::after { content: ""; position: absolute; // 這里的布局定位已祖先元素含有非 static 定位的元素進行絕對定位 bottom: -2px; left: 50%; width: 5px; height: 5px; background-color: #999; transform: translateX(-50%) rotate(45deg); } } }
注:
1. .heading 使用 table 顯示,不同於 block 顯示的元素寬度跟隨父元素默認 100%。也不同於 inline-block 顯示不能通過設置 margin 實現水平居中。
2. .heading 的 padding-right 和 padding-left 使用 80px,這個 。heading 的寬度就會比內容寬度多出 160px,左右兩條線通過定位 left: 0 和 right: 0 不必計算。
3. 左右的兩條線寬度使用 (50% - 20px) 留出了 40px 的空白,菱形需要占位。
4. strong 設置為 block 顯示,它的寬度就與父元素 .heading 一樣,父元素和其兩個子元素中寬度較大的那個一樣。
5. 在第二個 strong 的偽元素 ::after 中設置了絕對定位,它會相對於祖先元素中(從父元素一層一層往上找)非 static 定位的元素進行定位,這里是相對於 .heading 進行定位。並且設置 left: 50%, transform:translateX(-50%) rotate(46deg) 讓其在水平位置上居中,並且旋轉 45°。
2. .body 的布局
1. 流程圖每一項寬度不能固定,得根據文本內容來適應;2. 在父容器中需要水平居中; 3. 箭頭可以根據一條豎線加上一個箭頭來合成。
li { position: relative; display: table; margin-right: auto; margin-left: auto; height: 40px; line-height: 38px; padding-right: 35px; padding-left: 35px; background-color: #fff; border: 1px solid #ccc; border-radius: 20px; font-size: 14px; color: #333; &:not(:last-of-type) { margin-bottom: 32px; &::before { // 箭頭的豎線 content: ""; position: absolute; bottom: -26px; left: 50%; transform: translateX(-50%); width: 1px; height: 20px; background-color: #999; } &::after { // 箭頭 content: ""; position: absolute; bottom: -26px; left: 50%; transform: rotate(-45deg); transform-origin: left bottom; width: 7px; height: 7px; border-bottom: 1px solid #999; border-left: 1px solid #999; } } i { font-size: 1.3em; color: #a57e60; margin-right: 10px; } }
3. .join-us 的布局同 .heading 相似。
拓展:
table 屬性的用法遠不止這些
我們最常用到水平垂直布局也可以通過設置元素為單元格樣式來實現:
<div class="parent"> <div class="child">我在父元素中水平垂直居中</div> </div>
.parent { width: 400px; height: 200px; border: 1px solid #f00; display: table-cell; text-align: center; vertical-align: middle; }

