以下 CSS 柵格布局除了用 table 以外,有什麼其他的方法嗎?


拋磚引玉。

這個題目看似是最簡單的二維布局,實際透露出整個 CSS 的發展方向。向前可以考察對兼容性的處理功底,向後可以考察對 CSS 新特性的洞察能力。可攻可受,攻守兼備。

需要注意的是:這是一個兩端對齊的布局,需要仔細考慮中間空隙的處理

1. 兼容方案 float

最容易想到的就是運用 float 的浮動特性,為了更好的處理間距,我們需要三層結構,利用 margin 負值來抵消間距,形成視覺上的兩段對齊效果。

&

&
&

a& &

b& &

c& &

d& &

e& & &

2. 漸進增強 flex

flex 的處理需要一個小技巧,需要把主軸方向旋轉90度,也就是 flex-direction: column。

  • 優點:

flex 可以較好的處理兩端對齊布局,中間的空隙可以通過 align-content: space-between,justify-content: space-between 來實現自適應(但超過兩行或兩列時會有問題)。

  • 缺點:

需要通過 order 屬性手動調節為正確的元素順序。

3. 面向未來 grid

如果說從 Flex 開始 CSS有了真正的二維布局特性,那麼 CSS Grid 將是二維布局的未來。

  • 優點:

1)可以把傳統的網頁柵格體系直接對應到 CSS 聲明,例如:

.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
}

這樣三句代碼就表明我定義了一個兩行三列的柵格,也就是題中的布局。

2)通過 grid-column/row 屬性里的 span 值可以方便的實現跨行或誇列,無需顯性指定寬高的改變,非常方便的實現了跨行或誇列。

.grid .a {
grid-row: span 2;
}

.grid .a:hover {
grid-row: auto;
grid-column: span 2;
}

  • 缺點:

從我粗淺的理解來看,Grid 處理之間的空隙還比較麻煩,需要把空隙當做單獨的柵格來看待,然後通過 grid-area 屬性來定位主要的非空隙區塊。類似這樣:

grid-template-columns: 1fr 10px 1fr 10px 1fr;
grid-template-rows: 1fr 10px 1fr;
grid-template-areas:
"a a a . b"
". . . . ."
"c . d . e"

「.」 (U+002E FULL STOP)代表空的格子。詳見 @大漠 的答案。

無論如何,在 CSS Grid 的青春期里,我們期待更多特性的萌芽,你準備好了嗎?

Demo:多種方案實現跨行或誇列布局

筆記本鍵盤壞了,背個鍵盤迴來寫答案,容易嗎!!!???????????

2015年12月05日 更新

很高興的告訴大家,CSS Grid 布局現在已經增加了 grid-gap 屬性來控制間距,而且 WebKit, Blink, Firefox 都已經實現。

以上

壹絲


flexible box,你值得擁有:

&
&
&
&
&&
& .flex-container
{
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 440px;
width: 660px;
}

.flex-container section
{
box-sizing: border-box;
padding: 10px;
margin: 10px;
width: 200px;
height: 200px;
border: solid 1px;
border-radius: 5px;
}

.flex-container section:first-child
{
height: 420px;
}
& &
&
&

&A& &B& &C& &D& &E& &

&
&

基本上table布局能做到的,flexible box也都能做到,但flexible box的優越性在於可以徹底的分離布局和內容,就像上面這樣。


坐等 @一絲姐姐的詳細答案。採用了CSS Grid Layout Module寫了兩個。A Pen by Airen 和A Pen by Airen 相關原理可以看看早前整理的相關文檔:css3 grid layout


Bootstrap 之類的都提供了 12/16 格系統 CSS · Bootstrap#grid,非常方便實現這種布局。

Bootstrap 網格系統的原理是:

1. 每一格 float: left;

2. 格的寬度是 (n/12)%,col-*-3 就是 25%;

3. 提供了四個響應式斷點:xs sm md lg,可以在不同寬度的頁面中有不同的布局。

網格是基礎功能,響應式布局是基於網格的擴展功能。


動手練習了一下,參考了Ivony 的答案。有不妥地方請指正。謝謝

A Pen by Aztack

&
&
&
&&THE MOST ROMANTIC GETAWAY&Blessed with dreamy beaches, pounding surf, luxurious spas and swanky restaurants, it』s easy to see why thousands flock to Indonesia』s tourist mecca every year. &
&
& &
&Seoul&
&
& &
&Singapore&
&
& &
&Macao&
&
& &
&Phuket&
&
& & &

.container {
font-family:Tahoma;
display:flex;
flex-wrap: wrap;
height: 400px;
width: 600px;
flex-direction: column;
font-size: 12px;

span{
color:white;
position: absolute;
z-index:1;
margin: 10px;
bottom: 1em;
}
b{
position: absolute;
z-index: 1;
color: white;
font-size: 18px;
width: 100%;
text-align: center;
margin-top: 50%;
transform: translateY(-50%);
}
div {
border-radius: 8px;
box-sizing: border-box;
display:flex;
border: 4px solid transparent;
background-clip:padding-box;
height: 50%;
position: relative;
overflow: hidden;
flex-grow:1;
img {
position: absolute;
}
}
}


任何能引起reflow的屬性,比如float,不是非得用的話,我一般不用,改為使用margin-top負值實現那一效果,比如一個左右各一個50%寬度的div,如果用float,直接float:left,width:50%就可以了,但我為了避免reflow,方法是讓兩div按照普通流排列,各50%寬度,然後後面那個div給一個margin-keft:auto,margin-top:負值div高度。類似的,三列,四列,更多列也都是可以使用這種方法實現的


咦,這不是我今天放出去的面試題嘛。。。現在我肯定不好回答嘛。先佔坑觀察一下啰。

補充:其實我估計此問題和我的面試題表面上的類似只是巧合。

需要澄清的是,我當時的提問並非是預設好問題來考察一般的CSS布局實現的。實際情況是面試者曾在過去公司做過包含跟題圖非常類似的內容和效果的頁面(具體頁面暫時不提供鏈接,免得泄漏面試者的身份)。他(她)當時的實現是div容器下a元素對應每個圖片(圖片本身以background-image呈現),float布局。我隨口問這樣的實現方案比直接拿table做的方案好在哪裡。其次,因為面試者表示今後的發展方向想做前端組件化,所以我就拿他曾經做過的頁面問這個東西怎麼組件化——這裡其實暗含如何捕捉需求和如何抽象組件。當然這已經和本題限定的「布局實現」想去甚遠了。


用table你這是要置seo於何地?響應式布局也就是float加百分比寬度,翻翻bootsteap的源碼就知道了,還要鬧哪樣,嫌笨重非要寫的這個瀏覽器能用那個不能用才行?


css3

grid,或者(flex、box、flexbox)

誰能告訴我,伸縮布局,到底哪個名字靠譜點。。


用position做的話最簡單了


非常trick的方法,實際項目里也用過。用的inline-block和box-shadow。如果用Bootstrap的話利用自帶的grid system加上一點自定義樣式就可以了,缺點是不靈活,語義化程度低。間隙也可以用border或者偽元素來做。

http://codepen.io/anon/pen/XJBwYZ


bootstrap 有套柵格系統的,然後再嵌套一下應該口以~ 全局 CSS 樣式 · Bootstrap 中文文檔


不考慮兼容性,搞個概念版可以用flexbox。


設置好每個div的寬高,一個float不就解決了么,有什麼笨重的呀?還是我對問題理解不夠透徹?


這不算是 answer 吧。

把某高票答案的 grid 部分補完正確的 -ms- 前綴版本。

.grid {
display: -ms-grid;
-ms-grid-columns: 1fr 1fr 1fr;
-ms-grid-rows: 1fr 1fr;
}
.grid .a {
-ms-grid-row-span: 2;
}
.grid:hover .a{
-ms-grid-column-span:2;
-ms-grid-row-span:1
}
.grid:hover .b{-ms-grid-column:3}
.grid:hover .c{
-ms-grid-column:1;
-ms-grid-row:2
}
.grid .b,.grid .d{-ms-grid-column:2}
.grid .c,.grid .e{-ms-grid-column:3}
.grid .d,.grid .e{-ms-grid-row:2}


不考慮兼容,flexbox,考慮兼容,inline-block


不考慮兼容性flex和table table-row table-cell甚至直接上canvas都可以實現,需要兼容低版本IE的話還是table方便些,問題其實可以引申一下:除去實現靜態展示之外,如果還要求帶著動畫互換單元格位置(比如交換佔兩列和佔兩行的單元格)有什麼簡單的實現方式?


div img ul li img img li img img ul li li li


不考慮兼容性的話,單行的柵格可以用flex,多行的柵格可用grid。

等待各路大神的答案,占坑學習。


Div浮動,設置每一塊的寬高,應該能解決吧。


CSS 浮動效果應該可以做到吧


最流行的莫過於div+css了


用css3的grid


推薦閱讀:

到底 CSS 還有必要語義么?若沒有必要,類名要怎樣寫?
Normalize.css 與傳統的 CSS Reset 有哪些區別?
SCSS 有那些優勢,是否可以全面取代CSS?
大家都是怎麼玩node.js的?
ReactJS 真的好嗎?

TAG:網頁設計 | 前端開發 | HTML | CSS |