css佈局 - 工作中常見的兩欄佈局案例及分析
突然想到要整理這麼一篇平時工作中相當常見但是我們又很忽視的佈局的多種處理方法。臨時就在我經常瀏覽的網站上抓的相對應的截圖。(以後看到其他型別的我再補充)
既然截了圖,咱們就直接看人家使用的佈局方式,畢竟站在前輩肩膀上學習,我整理起來更輕鬆[哈哈]。(然後我再說一些我能想到的處理方式,幫助我們在工作中應對不同的佈局結構時,選擇性的去找最適合自己頁面佈局的方法)
說在前面:為了更好的看出來兩列結構,截圖我都做了藍線和紅線的框選。顏色較深的換成了黃線。總之就是為了讓你一眼看出來,哪塊和哪塊。適合佈局萌新,大佬們請無視我。
目錄:
一、大結構上的導航欄和內容區域兩欄佈局
1、部落格園為例
2、騰訊課堂個人中心頁
3、慕課網個人中心頁
4、github個人中心頁
二、mini版的nav+cont結構
三、類似九宮格佈局的兩列結構
四、圖文兩列布局
1、左圖右文字非垂直居中,
2、左圖,右固定行數的文字,右側文字和左邊圖片垂直居中。
3、左圖右文字溢位隱藏
五、左右兩端佈局
六、icon + 文字
七、最後加一個面試(送分)題
一、大結構上的導航欄和內容區域兩欄佈局
首先我們從 大結構上 說起,因為我發現很多網站從整個首屏的大結構上都是這種兩欄佈局:
旁邊是側邊欄導航,中間是大塊內容區域。比如下圖中我學習常用的幾個網站
部落格園個人中心頁
騰訊課堂個人中心頁面
騰訊課堂搜尋介面
慕課網個人中心頁面
github個人中心頁面
四個網站截圖往這裡一貼,瞬間我覺得自己練成了《葵花寶典》
這佈局結構不能說一模一樣,但讓我們前端看這就是一樣啊!!
我們先來看看這四個網站的分別實現方式,說不定剛好就是四種實現方式呢啊哈哈哈哈~
1、部落格園的:(比較正常的佈局實現)
大結構一個main包裹。
核心框架結構如下:
核心css,我總結有以下幾點:
-
左邊內容、右邊nav均設定左浮動
-
main 沒有觸發bfc,也沒有使用偽元素清除浮動,而是使用了一個空標籤清除浮動。但我們平時不用空標籤,而是用偽類元素。具體下邊css程式碼中體現。
-
右邊nav欄固定寬度,並用margin/padding-left隔開和左邊內容區域的距離
-
值的注意的是左邊內容區域寬度設定為百分百,並使用margin-left負值使得自身向左位移,以給右邊的nav騰出空間和左邊並列一排。
-
因為mainCont向左移,超出了main區域。所以mainCont的兒子mainCont-inner使用margin-left再向右移動回來。
-
main的最外邊元素cnblogs-body設定百分比寬度,並用margin實現水平居中。
具體css樣式:
簡陋效果:
特別說明:
mainCont父元素margin-left: -22em; 子元素margin-left:22em;到底咋實現的?
mainCont父元素向左偏移,把右側nav的位置留了出來。剛好到-22em的時候,nav盛下了。但是他卻犧牲了自己,超出了螢幕外邊。
也就是這張圖一開始的樣式。左邊粉色超出了瀏覽器螢幕。裡邊的文字都看不到了。
然後我們讓子元素mainCont-inner再margin-left把超出的位置頂回來。實際上就是讓其左邊超出main的位置都設定為margin的區域。這樣內容區域我們就能看到了。當然也可以設定padding-left:22em;不過那樣如果你的mainCont-inner裡有border或背景色(比如本例)還是會有超出看不到的問題。
2、騰訊課堂的:其結構和上一個剛好相反,nav在左側,實現原理差不多。
首先,html也很語義化、相當標準:(學習了)
相信這麼一張截圖,你已經看穿了一切。
其核心結構如下:
樣式關鍵點:
-
main父元素負責整體的水平居中。
-
nav負責左邊元素的左浮動+可展示寬度220px
-
mainCont負責佔據右邊剩餘位置,在這裡具體做法是讓其跟隨左側也形成浮動流。然後寬度100%,在浮動流的世界裡,mainCont再用margin-left不斷向左逼近,直到把nav佔據的220px找補回來(margin-left:-220px)。自己心滿意得的蓋住了nav。還得用padding把nav讓出來。
-
width:100%的元素使用了padding後的,寬度會增大。使用box-sizing把padding的寬度算到width中。
-
main偽元素after清楚浮動,解決父元素塌陷問題。
發現:如果把nav和mainCont的浮動都去掉,單純用margin負值不起作用。
具體css樣式
我的實現:
覺得左邊這裡浮動已經形成浮動流,他佔據左邊220畫素的日子也付東流了。所以右邊這裡沒必要再浮動了。可以直接使用padding-left把左邊nav佔據的220px空出來就行了。況且不用float就是塊級元素,連width啥的都不要了。mainCont裡邊只用這一行程式碼就行:
簡陋效果
心得:
html語義化
外邊的那層結構用來佈局,裡邊的結構用來承載樣式。至於全域性可繼承的屬性則可以放到body。
對於騰訊網課程這個樣式,使用的左右固定寬度+左右浮動。不想整理了。感興趣的自己開啟這個頁面檢視吧。
3、慕課網的:左側absolute定位脫離文件流,右側自適應。
哈哈哈,看到這裡我好開心,因為真的就像我開始說的,這仨網站的實現方式竟然真的都不一樣。
左側浮動:
右側自適應,margin讓出左側範圍。
html結構:
樣式關鍵點:
-
main負責控制總寬度和水平居中。
-
左側nav浮動
-
右側內容區margin讓出nav的寬度範圍。自適應。
css樣式:
簡陋的效果
4、最後說Github,就比較簡單粗暴了
百分比寬度+浮動。
html結構:
樣式關鍵點分析:
-
main負責控制最大寬度和水平居中
-
main偽元素清除浮動
-
nav和cont都左浮動,並且使用百分比平分main的空間。
css結構:
簡陋樣式:
果然,四個網站四種樣式。看來平時多看看別人的程式碼還是很能開拓思路的。
二、mini版的nav+cont結構
像不像上邊大結構縮放0.5倍後的樣式。左邊內容區域(content),右邊導航欄(nav)。
看git的程式碼,都是一個風格,幾乎寬度百分比定天下。上邊截圖程式碼的同樣是這個思路,具體實現如下。
html大致結構:
css關鍵思路:
-
main依舊應該負責總寬度和水平居中之類的佈局,這裡因為這一小塊是巢狀在其他結構裡的。就沒有什麼設定。
-
nav樣式上在右邊,但是結構上被放到了上邊。進行右浮動。這也是一個知識點:設定右浮動的元素結構放前邊比較好。具體原因我給忘了。
-
上邊h2通欄因為內容在左側,所以直接設定了100%寬度(也就是沒設定寬度)
-
h2右側的內容,利用浮動會形成文字環繞效果。讓該內容直接右浮動就自動繞開了nav的空間。
-
內容區域設定了左浮動和自身視覺寬度上的width值(也就是設計稿上多寬這裡設定了多寬)不過我的愚見,覺得這裡可以不設定浮動。反而設定上百分比寬度是為了自適應很有必要。
css程式碼:
簡陋效果:
驚悚的是,我居然沒有找到他的清除浮動。在哪~
三、類似九宮格佈局的兩列結構
github的實現方法是flex的兩端對齊:
關鍵點
-
父元素ol設定display:flex,並兩端對齊。
完了
歡迎去看我整理的九宮格佈局的實現方法吧。雖然我整理的是一排三列。但是兩列也適用。
四、圖文兩列布局
1、左圖右文字非垂直居中,以右側內容撐開高度為自由高度。這種的我們省心,不用考慮垂直居中的問題。
關於這種左圖右文字的兩列布局,我上一篇已經寫了很多種實現方法了,這裡我們使用最簡單的float實現:
<div class="wrapper"> <div class="img"></div> <div class="txt">我是右邊內容示範區</div> </div>
以下,img和txt的第一行才是最核心的佈局程式碼,其他都是美化用的樣式程式碼。
.img{ float: left; width: 50px; height: 50px; border-radius: 50%; background: #eee; } .txt{ margin-left: 70px; border: 1px solid salmon; height: 150px; line-height: 150px; text-align: center; }
效果
2、左圖,右固定行數的文字,右側文字和左邊圖片垂直居中。這種實現方式就有限了。
同上,左圖右多行文字垂直居中,(截圖這裡限制了兩行)但實際開發中,我遇到過有的設計稿不限制行數還要有垂直居中的。
先說上邊這種,其實還用1的那種,圖片浮動右邊設定margin-left的方法也可以。不過我們為了自適應的垂直居中,也就是假如我下邊那行座右銘文字過多換行的話,整個右邊紅框區域還能垂直居中:
這裡我們用flex實現:
示例效果:
如果是pc端考慮相容性實在不想用偉大的css3實現,也可以這麼做:
inline-block + vertical-align 屢試不爽
txt這裡還有個寬度設定,截圖時還沒加入。。
不管是內容少:
還是內容多,都能駕馭:(相容性還好,想相容ie6、7先出去槍斃自己幾分鐘,然後再回來寫inline-block的適配)
同樣,下邊這種,也是左邊圖(只不過是方形的),右邊是多行文案。同時這裡還設定了兩行固定顯示,更好說了:
3、左圖右文字溢位隱藏
關鍵點是左邊absolute“漂浮”起來(父元素需要relative限制一下)
然後右邊自適應佔據整個父元素的寬度,並用margin-left把左邊圖片遮擋的部位空出來。
奧對了,還有限制兩行溢位顯示小...,並且最底部是兩端佈局。
先說溢位小點點:
正常這麼設定,就是一行超出顯示小點點。像這樣:
若要控制規定行數顯示小點點:
這樣就是第二行顯示小點點了:
(授人以漁 - 可以百度搜索“多行文字溢位顯示省略號點點點...”)
而至於兩端佈局見下邊。
五、左右兩端佈局
下邊畫了三處:
這個巢狀結構你看出來了嗎?事先沒看原始碼前,我一打眼覺得是左邊一大塊,右邊一小塊的兩端佈局。但是細看發現原作把 logo單獨摘了出來,logo右邊的內容再分兩列兩端佈局。如下畫的紅框裡的綠和藍:
這個就簡單多了
左邊和右邊內容分別左右浮動:
flex兩端佈局
左邊左浮動,右邊寬度自適應並text-aligin:right;
文字兩端佈局
這種方式我想到了,但是程式碼沒有實現。網上百度看別人實現了。有點尷尬。flag先立這裡,有時間實現了補上吧。
六、icon + 文字
可以說是非常非常 常見的、幾乎100%設計稿必備結構了。
1、看個淘寶的截圖
這種一般都是文字不超過六個字,行數不超過一行。
其實都不能算是需要我們注意的正兒八經的兩列結構了。但是我想說的是我們工作中,常常抓耳撓腮的不是他的實現。而是在垂直方向上要求icon和文字居中的適配問題:
a、垂直居中問題:
圖和文字都是內聯塊元素,我一般都使用vertical-align實現,
b、垂直居中適配問題:
使用了vertical-align:middle,由於文字的下沉特性,還是覺得上下總是偏那麼幾畫素不居中。前端看不出來,設計師走查都不給你過。要麼只能margin微調,但常常情況是這個手機調好了,另一個手機又不行了。此消彼長,跟打地鼠似的。那我們怎麼破?
那就是我工作中佈局的一個小技巧,也是和張大神學的,vertical-align設定middle,而是設定具體的
畫素值。至於設定多少,正值還是負值都看你自己的實際專案和效果上下調整即可。雖然是很小的一個點,但是工作中真的幫助我擋住了很多測試提的同類型bug。
2、github的處理和我平時方法略顯不同:
用font字型+偽元素的處理方式
右邊的Beiging又一個padding-left值把左邊的icon讓了出來。而左邊的icon使用的字型,放在i標籤的偽元素before上了。
對了,說到偽元素,問一個很基礎但是很多人都混亂的問題:
請問什麼是偽元素,什麼是偽類?偽元素的權重高還是偽類的權重高?
這是一個前端老阿姨我親身經歷的題。雖然簡單的不像話,但是我摔得也很不像話。哈哈哈。順便提一下,讓每一個看到的你心裡回憶一下這個點。歡迎基礎紮實的你的留言~
好了,終於把自己心血來潮列的目錄添滿了,我和我的電腦現在都反映很慢了。那就完了?當然不是,因為,還有,一個!!!
七、最後加一個面試(送分)題
題目:移動端的input輸入框自適應。
類似效果如下:
解法一:flex:
html:
<div class="box"> <input type="text"> <button>按鈕</button> </div>
css:
.box{ background: rgb(218, 255, 184); padding: 5px; display: flex; align-items: center; justify-content: space-between; } input{ flex: 1; } button{ width: 80px; }
解法二、float佈局
html:
<div class="box"> <button>按鈕</button> <div class="input-box"> <input type="text"> </div> </div>
css:
.box{ background: rgb(218, 255, 184); padding: 5px; /* display: flex; align-items: center; justify-content: space-between; */ } .input-box{ width: 100%; margin-left: 80px; } input{ width: 100%; /* flex: 1; */ } button{ width: 80px; float: left; }
解法三、float+margin負邊距
html:
<div class="box"> <div class="input-box"> <input type="text"> </div> <button>按鈕</button> </div>
css:
.box{ background: rgb(218, 255, 184); padding: 5px; /* display: flex; align-items: center; justify-content: space-between; */ } .input-box{ float: left; width: 100%; margin-right: -80px; } input{ width: 100%; border: 1px solid #eee; padding: 5px 90px 4px 10px; box-sizing: border-box; /* flex: 1; */ } button{ width: 80px; }
ps:
padding-right: 90是為了留出按鈕的位置,不讓按鈕擋住文字。
解法四、定位佈局
html:
<div class="box"> <div class="input-box"> <input type="text"> </div> <button>按鈕</button> </div>
css:
.box{ background: rgb(218, 255, 184); padding: 5px; /* display: flex; align-items: center; justify-content: space-between; */ position: relative; height: 40px; } .input-box{ /* float: left; width: 100%; margin-right: -80px; */ position: absolute; left: 0; right: 80px; } input{ width: 100%; border: 1px solid #eee; /* padding: 5px 90px 4px 10px; */ padding: 5px 10px; box-sizing: border-box; /* flex: 1; */ } button{ width: 80px; position: absolute; right: 0; }