html結構的拆與合
斷續進度條
下面是一個進度條,估計大家大概一眼就可以看出這個進度條與普通的不一樣,這個進度條是有缺失地區的,有點像被老鼠偷吃了,斷斷續續的。
斷續進度條
這個原本是一個朋友發給我的,問我有什麼好的建議,當時想了想也確實想不到什麼好的辦法,就只好說一個個切吧,那就是本文所說的拆了,結構如下:
底部灰色由progress的背景實現,其餘每個done表示一個藍色段,每個undo表示一個灰色段,各自設定對應的寬度
.progress
.progress-done
.progress-undo
.progress-done
.progress-undo
.progress-done
...
第二版本
去掉了undo,直接對done使用絕對位置(因為progress容器的灰色跟undo灰色是一樣的)
.progress
.progress-done*n
第三版本
在常規的進度條上使用絕對位置添加undo,相對來說這個版本更好,可以在常規與特殊化之間進行方便的切換
.progress
.progress-done
.progress-undone*n
從上面三個版本總結來說:第一個版本是不管三七二十一,都拆了;而第二個版本是加入了一些思考,把藍色的拆了出來,把灰色的合在一起了;而第三個版本則是在第二個基礎上再根據實際情境轉化,進一步最佳化拆與合的思想,先把斷斷續續的藍色合成一個,然後通過灰色一個個去拆,以達到視覺上的拆開藍色。這就是本文拆與合的思想來源。
下面我們繼續領略下拆合之美。
擴充應用
標題右側內容
先來個簡單常見的,標題右側有操作的,如下圖:
標題右側內容
對於第一個html結構如下:
.block-hd
h3.block-tt
a.link-xxx
對於第二種結構,我們就得用到合了,不能再是簡單的羅列了,代碼如下:
.block-hd
h3.block-tt
.hd-right
a.link-xxx
a.link-xxx
對比這兩種情況,第一種只有一個操作,我們可以直接對操作定位在右邊;而第二種有兩個操作(甚至更多操作),這時候我們就不能再簡單的一個個去定位了,而是增加一個包裹(hd-right)把所有的操作合在一起,然後對包裹進行定位在右側。
這裡我們把零散的組合在一起定位,體現了合的基本原則。
經典的圖文混排
如下圖:第一種是最簡單的,左邊圖片右邊文字;第二種左邊圖片下面還有內容,可能是標題,也可能是一些操作;第三種在第二種基礎上右邊又出現了一部分內容
下面我們對結構進行一次次演變:
// 極簡主義
.imgtext-mix
img.mix-img
h3.mix-tt
.mix-intro
// 添加連結
.imgtext-mix
a.mix-img-link>img.mix-img
h3.mix-tt>a.mix-tt-link
.mix-intro
// 第一次合,將圖片右邊內容包裹
.imgtext-mix
a.mix-img-link>img.mix-img
.mix-text
h3.mix-tt>a.mix-tt-link
.mix-intro
// 第二次合,將左側圖片等內容進行包裹
.imgtext-mix
.mix-left
a.mix-img-link>img.mix-img
.left-oper
.mix-text
h3.mix-tt>a.mix-tt-link
.mix-intro
// 第三次合,將最右側資訊進行包裹
.imgtext-mix
.mix-left
a.mix-img-link>img.mix-img
.left-oper
.mix-text
h3.mix-tt>a.mix-tt-link
.mix-intro
.mix-right
...
先從極簡主義出發,然後根據空間原則,一步步組合,從結構上進行空間上地區的劃分,實現需要的效果,這是由簡單的一鍋煮到分類煮,由拆的本質到合的美學體現。
其他拆合
從最終要實現的效果來說,我們對結構要做的無非是上下,左右,脫離與覆蓋的拆合。第一個進度條的例子很好的說明了覆蓋的拆合(星級評論也可用到),擴充應用的說的更多的是左右的拆合,下面我們繼續說說上下與脫離的拆合。
上下拆合
這個最典型的莫過於網站整體布局了,可詳見HTML整站結構設計
header.header>.inner-center
section.section-mainr>.inner-center
footer.footerr>.inner-center
脫離拆合
如果從使用css實現的結果來說,所有要應用fixed,absolute的結構都屬於脫離的拆合。這裡最典型的莫過於fixed導航,及fixed的右下角的回到頂部,效果請看w3cplus,當你滾動捲軸的時候會發現頂部導航一直fixed在頂部,而右下角會出現一個返回頂部的小按鈕
說了這麼多,總結起來就是:html結構中到處都映射著拆與合的思想。
拆合之道
所謂拆,就是儘可能讓每個元素獨立或者是每個效果獨立。元素獨立這個比較簡單,比較好理解,就是給每個元素都有各自對應的標籤;而效果獨立這個就得去根據實戰分析,靈活使用了。
而所謂合,就是儘可能少用元素或把一些元素使用標籤包裹組合起來以達到統一控制。少用標籤這塊,one div這種已經做出很好的解釋了,css3的進步為這提供了強有力的技術保證;而對於包裹組合這個也得根據實戰去取捨。
總之,html結構肯定不是越簡單越好,當然也肯定不是越複雜越好,而是建立在拆合之上的一種取捨之道。
css設計中的不變與可變
一個面試題
首先這是一個面試題,其次反正我是沒做過這個面試題,最後忘了是哪個廠的面試題。
具體的要求我忘了,大概的意思就是要這個內容在視窗內垂直方向置中,以圖片為參考,文字上下延伸,上面文字多了向上撐開,下面文字多了向下撐開,圖片大小固定,文字多少不固定(紅線是我加的,作為垂直方向的中間線,以輔助說明)。這裡文字屬於可變因子,而圖片屬於固定因子。
思路分析
首先,我們看到這裡的圖片都在同一水平線上,文字的多少根本不能影響圖片,所以我們得出可能的兩種方案,第一種文字正常文檔流,圖片絕對位置;第二種文字絕對位置,圖片正常文檔流。
其次,因為上面的文字延伸方向是朝上,本身就違反了正常的文檔流方向(正常的應該是隨著文字的增加向下延伸高度),所以得出上面的文字部分必然得絕對位置,設定bottom值
最後,結合上面兩個原因,我們先採用第二種方案實驗,文字絕對位置,圖片正常文檔流。
這裡,我們使用上篇文章中拆的思想得到html結構如下:
ul.demo
li
.text-top
img.img-center
.text-bottom
主要css代碼如下:
.demo{
position:absolute;
top: 50%;
}
.demo li{
float: left;
width: 120px;
margin: 0 20px;
position: relative;
}
.text-top{
position: absolute;
bottom: 90px;
left: 0;
}
.img-center{
margin-top: -34px;
width: 120px;
height: 68px;
}
.text-bottom{
position: absolute;
top: 50px;
}
常見執行個體
內容流體布局
這裡選擇側邊欄固定,內容為剩餘寬度的流體布局。側邊欄為固定因子,內容為可變因子。
section.section-main
.inner-center.clearfix
.main>.content
aside.aside-right
.main{
float: left;
width: 100%;
}
.main .content{
margin-right: 320px;
}
.aside-right{
float: left;
width: 300px;
margin-left: -320px;
}
圖文混排
還是之前的那個圖文混排,一般來說圖片是固定寬度的,而文字部分是不設定寬度的。固定因子為圖片的寬度,可變因子為文字的寬度。
.imgtext-mix
a.mix-img-link>img.mix-img
.mix-text
h3.mix-tt>a.mix-tt-link
.mix-intro
.mix-img-link{
float: left;
width: 200px;
margin-right: 20px;
}
.mix-text{
overflow: hidden;
}
容器寬度不定,但寬高比一定
這個不變的因子是寬高比,可變的因子是寬度。
移動端的可變與不變
有很多剛入門移動端重構的人一般都會問一個問題,移動端是不是都要用百分比啊。其實拋開那些新的單位rem、vw、vh等,移動端除了百分比,px也是可以用的,根本不是你想象的那樣。用什麼單位,最主要的還是要把握好可變與不可變。如果你把握好了,那移動端重構其實跟pc也是一樣的。當然如果你習慣pc上的動不動就設定一個固定的寬高,那估計就得受挫了。
全屏的圖片滾動
全屏的這個東西,在vw還不能使用的情況下,那非100%莫屬了(這裡的全屏是指寬度鋪滿整個螢幕,不包括高度)。
ul.imgslide
li*4>img
// float布局
.imgslide{
width: 400%;
}
.imgslide li{
width: 25%;
float: left;
}
// absoulte布局
.imgslide{
width: 100%;
height: 100px;
position: relative;
}
.imgslide li{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.imgslide li:nth-child(n+1){
transform: translate(100%, 0);
}
圖文混排列表
還是前面的圖文混排,哈哈,對於pc也許你可以無視右邊文字的可變直接設定width,但是移動端那就對不起了,必須要考慮這個可變因子。
這個估計90%的移動端都有這個效果,當然不可能設計給你的是375px的稿子,然後你就做了個375px寬度的效果。但是如果按照設計稿的比例,然後設定圖片和寬度的百分比呢,這種情況圖片寬度的改變,當然會影響圖片高度的改變(如果是固定的高度那圖片估計就沒法看了,各種被展開或是變形),而圖片高度的改變就會影響整體行的改變,那估計拿著不同的手機,看到的右邊的文字內容或高或低也是醉了。
百分比效果大概如下圖:
所以這裡一般設計的是圖片固定大小不變,右邊文字可變,佔滿其餘空間。實現跟上面的圖文混排一樣,當然技術上可以使用很多方法如flex,absolute,float等
單行列表
同樣單行列表,標題因為長度不一屬於可變因子,不宜直接控制其寬度。而右側的一些按鈕或輔助資訊相對來說使用絕對位置在右邊比較合理。
ul.line-list
li
p.title+i.icon-xxx
.line-list li{
position: relative;
padding-right: 40px;
line-height: 40px;
}
.line-list li .icon-xxx{
position: absolute;
right: 10px;
top: 50%;
tranform: translate(0, -50%);
}
// 如果文字比較長,需要做超出省略截斷
.line-list li .title{
padding-left: 10px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
等分
這裡的等分指水平的等分,可以使用的技術有flex,float,table-cell等,其中float應該是最low的,因為你必須要設定item的寬度,三等分設定33.33%,四等分設定25%等,這種重複利用性太low,已經不適合更進階的移動端了,所以flex和table-cell是不錯的選擇,根本不需要在意item的個數(當然得確定一行能顯示下,顯示不下那也是悲催)。所以這種情況下連單位都是多餘的。
ul.equal-list
li*n
// flex
.equal-list{
display: flex;
}
.equal-list li{
flex: 1;
}
// table-cell
.equal-list{
display: table;
table-layout: fixed;
width: 100%;
}
.equal-list li{
display: table-cell;
}
translate
translate中使用的百分比單位是針對自己寬高的百分比,所以對於未知寬高的計算來說,是非常大的優勢,尤其用在水平和垂直置中上。
.center-translate{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
當然這些變與可變的還有很多,總之,在移動端的可變因子比pc上更多,更多的對寬度或高度的不確定,就需要各種方法去避免直接設定死寬度或高度,當然慶幸的是,css3的支援讓這些不確定因素的控制變得趨向簡單。
變與不變之道
最後不管是移動端還是pc端,對於動不動就設定一個具體width或height的方式註定可擴充性欠缺。所以尤其是在做萬用群組件的時候,一定要進一步深挖掘,瞭解更多的使用情境,每個情境的一些特殊特徵,甚至於對未來的修改都有可預見性。
可能這裡說得更多的是寬度方面的控制,其實對於方法的選擇也一樣,同一種效果,可能有很多方法去實現,而每種方法都有各自的利弊,所以也要根據實際情況去靈活變通使用,這同樣也屬於可變的。如果你所有的都是一刀切,那就是固定的一個思維了,無所謂變通了。
如果從一個更高的角度來說,沒有什麼是恒定的不變,一切皆可變。也許這個網站的不可變,到了那個網站就得變,所以拒絕教條主義,一切從實際情況出發,根據需求分析,得出一個合理的實踐。