所謂的負邊距就是margin取負值的狀況,如margin:-100px,margin:-100%。當一個元素與另外一個元素margin取負值時將拉近距離。常見的功能以下:javascript
當多個元素同時從標準流中脫離開來時,若是前一個元素的寬度爲100%寬度,後面的元素經過負邊距能夠實現上移。當負的邊距超過自身的寬度將上移,只要沒有超過自身寬度就不會上移,示例以下:css
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>負邊距</title> <style type="text/css"> * { margin: 0; padding: 0; } #div1 { height: 100px; background: lightblue; width: 100%; float: left; } #div2 { height: 100px; background: lightgreen; width: 30%; float: left; margin-left: -100%; } </style> </head> <body> <div id="div1">div1 </div> <div id="div2">div2 </div> </body> </html>
margin-left:-29%時運行效果:html
margin-left:-30%時運行效果:html5
margin-left:-100%時運行效果:java
開發中常須要在頁面中展現一些列表,如商品展現列表等,若是咱們要實現以下佈局:jquery
示例代碼:git
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>負邊距</title> <style type="text/css"> * { margin: 0; padding: 0; } #div1 { width: 800px; margin: 0 auto; border: 3px solid lightblue; overflow: hidden; margin-top: 10px; } .box { width: 180px; height: 180px; margin: 0 20px 20px 0; background: lightgreen; float: left; } </style> </head> <body> <div id="div1"> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> </div> </body> </html>
運行後的結果:github
可是上面的效果中右邊多出了20px的距離,底下多出20px空白,解決方法以下:web
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>負邊距</title> <style type="text/css"> * { margin: 0; padding: 0; } #div1 { width: 780px; height: 380px; margin: 0 auto; border: 3px solid lightblue; overflow: hidden; margin-top: 10px; } .box { width: 180px; height: 180px; margin: 0 20px 20px 0; background: lightgreen; float: left; } #div2{ margin-right: -20px; } </style> </head> <body> <div id="div1"> <div id="div2"> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> <div class="box"> </div> </div> </div> </body> </html>
方法是使用了邊距摺疊,能夠在前面的文章中查看到細節,基本原理以下圖所示:ajax
具體請參考《CSS3與頁面佈局學習總結(三)——BFC、定位、浮動、7種垂直居中方法》
方法一:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>負邊距</title> <style type="text/css"> * { margin: 0; padding: 0; list-style: none; } #news { width: 200px; border: 2px solid lightblue; margin: 20px 0 0 20px; } #news li{ height: 26px; line-height: 26px; border-bottom: 1px dashed lightblue; } .lastLi{ margin-bottom:-1px ; } </style> </head> <body> <div id="news"> <ul> <li>Item A</li> <li>Item B</li> <li>Item C</li> <li>Item D</li> <li class="lastLi">Item E</li> </ul> </div> </body> </html>
方法二:
使用CSS3中的新增長選擇器,選擇最後一個li,不使用類樣式,好處是當li的個數不肯定時更加方便。
若是li的border-bottom顏色與ul的border顏色是同樣的時候,在視覺上是被隱藏了。若是其顏色不一致的時候仍是有問題,給ul寫個overflow:hidden;就能夠解決這個問題。
練習:
經典三列布局,也叫作聖盃佈局【Holy Grail of Layouts】是Kevin Cornell在2006年提出的一個佈局模型概念,在國內最先是由淘寶UED的工程師傳播開來,在中國也有叫法是雙飛翼佈局,它的佈局要求有幾點:
一、三列布局,中間寬度自適應,兩邊定寬;
二、中間欄要在瀏覽器中優先展現渲染;
三、容許任意列的高度最高;
四、要求只用一個額外的DIV標籤;
五、要求用最簡單的CSS、最少的HACK語句;
在不增長額外標籤的狀況下,聖盃佈局已經很是完美,聖盃佈局使用了相對定位,之後佈局是有侷限性的,並且寬度控制要改的地方也多。在淘寶UED(User Experience Design)探討下,增長多一個div就能夠不用相對佈局了,只用到了浮動和負邊距,這就是咱們所說的雙飛翼佈局,實現的代碼以下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>雙飛翼</title> <style type="text/css"> * { margin: 0; padding: 0; } body, html { height: 100%; font: 20px/40px "microsoft yahei"; color: white; } #container { width: 90%; margin: 0 auto; height: 100%; } #header, #footer { height: 12.5%; background: deepskyblue; } #main { height: 75%; } #center, #left, #right { height: 100%; float: left; } #center { width: 100%; background: lightgreen; } #right { background: lightblue; width: 20%; margin-left: -20%; } #left { background: lightcoral; width: 20%; margin-left: -100%; } #main-inner { padding-left: 20%; } </style> </head> <body> <div id="container"> <div id="header"> header </div> <div id="main"> <div id="center"> <div id="main-inner"> center </div> </div> <div id="left"> left </div> <div id="right"> right </div> </div> <div id="footer"> footer </div> </div> </body> </html>
運行效果:
示例中增長一個main-inner的目的是由於當left上移時與center重疊了,left覆蓋了center,經過main-inner的padding將left佔用的位置空出。
欄柵格系統就是利用浮動實現的多欄佈局,在bootstrap中用的很是多,這裏以一個980像素的寬實現4列的柵格系統,示例代碼以下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>柵格系統</title> <style type="text/css"> * { padding: 0; margin: 0; } html, body { height: 100%; } #container { width: 980px; margin: 0 auto; height: 10%; } #container div { height: 100%; } .col25 { width: 25%; background: lightgreen; float: left; } .col50 { width: 50%; background: lightblue; float: left; } .col75 { width: 75%; background: lightcoral; float: left; } </style> </head> <body> <div id="container"> <div class="col50"> A </div> <div class="col50"> B </div> <div class="col25"> C </div> </div> </body> </html>
運行結果:
一樣的原理能夠輕易擴展到8列,10列,16列的柵格系統。
柵格系統並無真正實現分欄效果(如word中的分欄),CSS3爲了知足這個要求增長了多列布局模塊,若是須要實現多列布局模塊先看看這幾個CSS3屬性:
column-count:<integer> | auto
功能:設置或檢索對象的列數
適用於:除table外的非替換塊級元素, table cells, inline-block元素
<integer>: 用整數值來定義列數。不容許負值
auto: 根據 <' column-width '> 自定分配寬度
column-gap:<length> | normal
功能:設置或檢索對象的列與列之間的間隙
適用於:定義了多列的元素
計算值:絕對長度值或者normal
column-rule:<' column-rule-width '> || <' column-rule-style '> || <' column-rule-color '>
功能:設置或檢索對象的列與列之間的邊框。與border屬性相似。
適用於:定義了多列的元素
columns:<' column-width '> || <' column-count '>
功能:設置或檢索對象的列數和每列的寬度
適用於:除table外的非替換塊級元素, table cells, inline-block元素
<' column-width '>: 設置或檢索對象每列的寬度
<' column-count '>: 設置或檢索對象的列數
示例代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>多列布局</title> <style type="text/css"> #div1{ column-count: 3; /*分3欄*/ column-gap: 40px; /*欄間距*/ column-rule: 2px solid lightgreen; /*欄間分隔線,與border設置相似*/ line-height: 26px; font-size: 14px; height: 500px; background: lightcyan; } </style> </head> <body> <div id="div1"> CSS即層疊樣式表(Cascading StyleSheet)。 在網頁製做時採用層疊樣式表技術,能夠有效地對頁面的佈局、字體、顏色、背景和其它效果實現更加精確的控制。 只要對相應的代碼作一些簡單的修改,就能夠改變同一頁面的不一樣部分,或者頁數不一樣的網頁的外觀和格式。CSS3是CSS技術的升級版本,CSS3語言開發是朝着模塊化發展的。之前的規範做爲一個模塊實在是太龐大並且比較複雜,因此,把它分解爲一些小的模塊,更多新的模塊也被加入進來。這些模塊包括: 盒子模型、列表模塊、超連接方式 、語言模塊 、背景和邊框 、文字特效 、多欄佈局等。CSS即層疊樣式表(Cascading StyleSheet)。 在網頁製做時採用層疊樣式表技術,能夠有效地對頁面的佈局、字體、顏色、背景和其它效果實現更加精確的控制。 只要對相應的代碼作一些簡單的修改,就能夠改變同一頁面的不一樣部分,或者頁數不一樣的網頁的外觀和格式。CSS3是CSS技術的升級版本,CSS3語言開發是朝着模塊化發展的。之前的規範做爲一個模塊實在是太龐大並且比較複雜,因此,把它分解爲一些小的模塊,更多新的模塊也被加入進來。這些模塊包括: 盒子模型、列表模塊、超連接方式 、語言模塊 、背景和邊框 、文字特效 、多欄佈局等。 </div> </body> </html>
運行結果:
假設在項目中有一個這樣的需求:同一行有3個菜單,每一個菜單佔1/3的寬度,怎麼實現?
可能你會這樣實現:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; } html, body { height: 100%; } #menu { width: 980px; margin: 0 auto; } #menu li{ width: 33.3%; float: left; } </style> </head> <body> <ul id="menu"> <li><a href="#" class="item">公司簡介</a></li> <li><a href="#" class="item">商品展現</a></li> <li><a href="#" class="item">後臺管理</a></li> </ul> </body> </html>
結果:
上面的辦法有明顯的不足就是可擴展性太差,由於若是再添加一項就會有一個菜單項會換行,解決方法是:CSS3中提供了強大的彈性盒佈局。示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; } html, body { height: 100%; } #menu { width: 980px; margin: 0 auto; display: flex; /*當前塊爲彈性盒*/ } #menu li{ flex: auto; /*彈性盒中的單項*/ float: left; } #menu li a{ display:block; height: 26px; line-height: 26px; border:1px solid cornflowerblue; margin-right: 2px; text-decoration: none; text-align: center; } </style> </head> <body> <ul id="menu"> <li><a href="#" class="item">公司簡介</a></li> <li><a href="#" class="item">商品展現</a></li> <li><a href="#" class="item">後臺管理</a></li> <li><a href="#" class="item">企業文化</a></li> <li><a href="#" class="item">在線諮詢</a></li> </ul> </body> </html>
運行結果:
display屬性值flex: 將對象做爲彈性伸縮盒顯示
flex:none | <flex-grow> <flex-shrink > || <flex-basis>
功能:設置或檢索彈性盒模型對象的子元素如何分配空間
適用於:flex子項
none: none關鍵字的計算值爲: 0 0 auto
<flex-grow>: 用來指定擴展比率,即剩餘空間是正值時此「flex子項」相對於「flex容器」裏其餘「flex子項」能分配到空間比例。
在「flex」屬性中該值若是被省略則默認爲「1」
<flex-shrink>: 用來指定收縮比率,即剩餘空間是負值時此「flex子項」相對於「flex容器」裏其餘「flex子項」能收縮的空間比例。
在收縮的時候收縮比率會以伸縮基準值加權
在「flex」屬性中該值若是被省略則默認爲「1」
<flex-basis>: 用來指定伸縮基準值,即在根據伸縮比率計算出剩餘空間的分佈以前,「flex子項」長度的起始數值。
在「flex」屬性中該值若是被省略則默認爲「0%」
在「flex」屬性中該值若是被指定爲「auto」,則伸縮基準值的計算值是自身的 <width> 設置,若是自身的寬度沒有定義,則長度取決於內容。
示例:以下狀況每一個元素的計算寬是多少
<ul class="flex"> <li>a</li> <li>b</li> <li>c</li> </ul>
.flex{display:flex;width:800px;margin:0;padding:0;list-style:none;} .flex :nth-child(1){flex:1 1 300px;} .flex :nth-child(2){flex:2 2 200px;} .flex :nth-child(3){flex:3 3 400px;}
本例定義了父容器寬(即主軸寬)爲800px,因爲子元素設置了伸縮基準值flex-basis,相加300+200+400=900,那麼子元素將會溢出900-800=100px;
因爲同時設置了收縮因子,因此加權綜合可得300*1+200*2+400*3=1900px;
因而咱們能夠計算a,b,c將被移除的溢出量是多少:
a被移除溢出量:(300*1/1900)*100,即約等於16px
b被移除溢出量:(200*2/1900)*100,即約等於21px
c被移除溢出量:(400*3/1900)*100,即約等於63px
最後a,b,c的實際寬度分別爲:300-16=284px, 200-21=179px, 400-63=337px
可見算法比較麻煩,簡單的作法以下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; } html, body { height: 100%; } #menu { width: 980px; margin: 0 auto; display: flex; /*當前塊爲彈性盒*/ } #menu li { float: left; } #menu li a { display: block; height: 26px; line-height: 26px; border: 1px solid cornflowerblue; margin-right: 2px; text-decoration: none; text-align: center; } .a { flex: 1; } .b { flex: 2; } .c { flex: 3; } </style> </head> <body> <ul id="menu"> <li class="a"> <a href="#" class="item">公司簡介</a> </li> <li class="b"> <a href="#" class="item">商品展現</a> </li> <li class="c"> <a href="#" class="item">後臺管理</a> </li> </ul> </body> </html>
運行結果:
Flex容器能夠設置屬性flex-flow,取值爲row,row-reverse,column,column-reverse四種值
row:顯示在一行中
row-reverse:顯示在一行中,反轉
column:顯示在一列中
column-reverse:顯示在一列中 反轉
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; } html, body { height: 100%; padding-top :20px; } #menu { width: 980px; margin: 0 auto; display: flex; /*當前塊爲彈性盒*/ flex-flow: row-reverse; /*子項在一行中顯示,反轉*/ } #menu li { flex: auto; } #menu li a { display: block; height: 26px; line-height: 26px; border: 1px solid cornflowerblue; margin-right: 2px; text-decoration: none; text-align: center; } </style> </head> <body> <ul id="menu"> <li class="a"> <a href="#" class="item">A公司簡介</a> </li> <li class="b"> <a href="#" class="item">B商品展現</a> </li> <li class="c"> <a href="#" class="item">C後臺管理</a> </li> </ul> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; } html, body { height: 100%; padding-top :20px; } #menu { margin: 0 auto; display: flex; /*當前塊爲彈性盒*/ flex-flow: column-reverse; height: 200px; overflow: hidden; } #menu li{ border: 1px solid cornflowerblue; margin-bottom: 5px; text-align: center; } #menu li a { text-decoration: none; vertical-align: middle; } .a{ flex: 1; } .b{ flex: 2; } .c{ flex: 3; } </style> </head> <body> <ul id="menu"> <li class="a"> <a href="#" class="item">A公司簡介</a> </li> <li class="b"> <a href="#" class="item">B商品展現</a> </li> <li class="c"> <a href="#" class="item">C後臺管理</a> </li> </ul> </body> </html>
固定佈局和流式佈局在網頁設計中最經常使用的兩種佈局方式。固定佈局能呈現網頁的原始設計效果,流式佈局則不受窗口寬度影響,流式佈局使用百分比寬度來限定佈局元素,這樣能夠根據客戶端分辨率的大小來進行合理的顯示。
固定佈局效果:
流式佈局效果:
利用前面的知識點能夠實現這兩種佈局,這裏就不去實現了
瀑布流佈局是流式佈局的一種。是當下比較流行的一種網站頁面佈局,視覺表現爲良莠不齊的多欄佈局,隨着頁面滾動條向下滾動,這種佈局還會不斷加載數據塊並附加至當前尾部。最先採用此佈局的網站是Pinterest,逐漸在國內流行開來。
鼻祖:Pinterest
通用類:豆瓣市集,花瓣網,我喜歡,讀圖知天下
美女圖片:圖麗網
時尚資訊類:看潮網
時尚購物類:蘑菇街,美麗說,人人逛街,卡當網
品牌推廣類:凡客達人
家居o2o類:新巢網小貓家
微博社交類: 都愛看
搞笑圖片類:道趣兒
藝術收藏類:微藝術
潮流圖文分享:荷都分享網
優勢
一、有效的下降了界面複雜度,節省了空間:咱們再也不須要臃腫複雜的頁碼導航連接或按鈕了。
二、對觸屏設備來講,交互方式更符合直覺:在移動應用的交互環境當中,經過向上滑動進行滾屏的操做已經成爲最基本的用戶習慣,並且所須要的操做精準程度遠遠低於點擊連接或按鈕。
三、更高的參與度:以上兩點所帶來的交互便捷性可使用戶將注意力更多的集中在內容而不是操做上,從而讓他們更樂於沉浸在探索與瀏覽當中。
缺點
1. 有限的用例:
無限滾動的方式只適用於某些特定類型產品當中一部分特定類型的內容。
例如,在電商網站當中,用戶時常須要在商品列表與詳情頁面之間切換,這種狀況下,傳統的、帶有頁碼導航的方式能夠幫助用戶更穩妥和準確的回到某個特定的列表頁面當中。
2. 額外的複雜度:
那些用來打造無限滾動的JS庫雖然都自稱很容易使用,但你總會須要在本身的產品中進行不一樣程度的定製化處理,以知足大家本身的需求;另外這些JS庫在瀏覽器和設備兼容性等方面的表現也良莠不齊,你必須作好充分的測試與調整工做。
3. 再見了,頁腳:
若是使用了比較典型的無限滾動加載模式,這就意味着你能夠和頁腳說拜拜了。
最好考慮一下頁腳對於你的網站,特別是用戶的重要性;若是其中確實有比較重要的內容或連接,那麼最好換一種更傳統和穩妥的方式。
千萬不要耍弄你的用戶,當他們一次次的瀏覽到頁面底部,看到頁腳,卻由於自動加載的內容忽然出現而不管如何都沒法點擊頁腳中的連接時,他們會變的愈加憤怒。
5. SEO:
集中在一頁當中動態加載數據,與一頁一頁的輸出相比,究竟那種方式更利於SEO,這是你必須考慮的問題。對於某些以類型網站來講,在這方面進行冒險是很不划算的。
6. 關於頁面數量的印象:
其實站在用戶的角度來看,這一點並不是負面;不過,若是對於你的網站來講,經過更多的內容頁面展現更多的相關信息(包括廣告)是很重要的策略,那麼單頁無限滾動的方式對你並不適用。
masonry是一個響應式網格佈局庫(非jQuery)。(Cascading grid layout library)
若是使用CSS+JavaScript固然能夠實現瀑布流佈局,但相對麻煩,masonry是一個javascript插件,經過該插件能夠輕鬆實現瀑布流佈局,和CSS中float的效果不太同樣的地方在 於,float先水平排列,而後再垂直排列,使用Masonry則垂直排列元素,而後將下一個元素放置到網格中的下一個開發區域。這種效果能夠最小化處理 不一樣高度的元素在垂直方向的間隙。
官網:http://masonry.desandro.com/
源碼:https://github.com/desandro/masonry
能夠去官網或github下載「masonry.pkgd.min.js」,將下載到的插件添加到項目中,並在頁面中添加引用,以下所示:
<script src="js/masonry/masonry.pkgd.min.js" type="text/javascript" charset="utf-8"></script>
CDN:
<script src="https://unpkg.com/masonry-layout@4.1/dist/masonry.pkgd.js"></script> <!-- or --> <script src="https://unpkg.com/masonry-layout@4.1/dist/masonry.pkgd.min.js"></script>
在頁面中使用HTML+CSS準備須要使用瀑布流顯示的內容,以下所示:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>瀑布流佈局</title> <style type="text/css"> #grid { width: 1000px; margin: 0 auto; } .grid-item { width: 200px; float: left; } .a { background: lightblue; height: 200px; } .b { background: lightcoral; height: 300px; } .c { background: lightgreen; height: 500px; } .d { background: lightsalmon; height: 350px; } .e { background: lightseagreen; height: 150px; } </style> </head> <body> <div id="grid"> <div class="grid-item a"> </div> <div class="grid-item b"> </div> <div class="grid-item a"> </div> <div class="grid-item b"> </div> <div class="grid-item a"> </div> <div class="grid-item b"> </div> <div class="grid-item a"> </div> <div class="grid-item b"> </div> <div class="grid-item a"> </div> <div class="grid-item b"> </div> <div class="grid-item a"> </div> <div class="grid-item b"> </div> <div class="grid-item c"> </div> <div class="grid-item d"> </div> <div class="grid-item e"> </div> <div class="grid-item c"> </div> <div class="grid-item d"> </div> <div class="grid-item e"> </div> <div class="grid-item c"> </div> <div class="grid-item d"> </div> <div class="grid-item e"> </div> <div class="grid-item c"> </div> <div class="grid-item d"> </div> <div class="grid-item e"> </div> <div class="grid-item c"> </div> <div class="grid-item d"> </div> <div class="grid-item e"> </div> <div class="grid-item c"> </div> <div class="grid-item d"> </div> <div class="grid-item e"> </div> </div> <script src="js/masonry/masonry.pkgd.min.js" type="text/javascript" charset="utf-8"></script> </body> </html>
沒有使用瀑布流佈局時的效果:
使用jQuery:
$('.grid').masonry({ // options... itemSelector: '.grid-item', columnWidth: 200 });
原生JavaScript:
// init with element var grid = document.querySelector('.grid'); var msnry = new Masonry( grid, { // options... itemSelector: '.grid-item', columnWidth: 200 });
使用HTML屬性:
<div class="grid" data-masonry='{ "itemSelector": ".grid-item", "columnWidth": 200 }'> <div class="grid-item"></div> <div class="grid-item"></div> ... </div>
經常使用屬性以下:
itemSelector : '.item',//瀑布流佈局中的單項選擇器 columnWidth : 240 ,//一列的寬度 isAnimated:true,//使用jquery的佈局變化,是否啓用動畫 animationOptions:{ //jquery animate屬性 漸變效果 Object { queue: false, duration: 500 } }, gutterWidth:0,//列的間隙 Integer isFitWidth:true,//是否適應寬度 Boolean isResizableL:true,//是否可調整大小 Boolean isRTL:false,//是否使用從右到左的佈局 Boolean
初始化代碼以下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>瀑布流佈局</title> <style type="text/css"> #grid { width: 1000px; margin: 0 auto; } .grid-item { width: 200px; float: left; } .a { background: lightblue; height: 200px; } .b { background: lightcoral; height: 300px; } .c { background: lightgreen; height: 500px; } .d { background: lightsalmon; height: 350px; } .e { background: lightseagreen; height: 150px; } </style> </head> <body> <div id="grid"> <div class="grid-item a"> </div> <div class="grid-item b"> </div> <div class="grid-item a"> </div> <div class="grid-item b"> </div> <div class="grid-item c"> </div> <div class="grid-item d"> </div> <div class="grid-item e"> </div> <div class="grid-item c"> </div> <div class="grid-item d"> </div> <div class="grid-item a"> </div> <div class="grid-item b"> </div> <div class="grid-item a"> </div> <div class="grid-item b"> </div> <div class="grid-item a"> </div> <div class="grid-item b"> </div> <div class="grid-item d"> </div> <div class="grid-item e"> </div> <div class="grid-item c"> </div> <div class="grid-item d"> </div> <div class="grid-item e"> </div> <div class="grid-item a"> </div> <div class="grid-item b"> </div> <div class="grid-item c"> </div> <div class="grid-item d"> </div> <div class="grid-item e"> </div> <div class="grid-item c"> </div> <div class="grid-item e"> </div> <div class="grid-item c"> </div> <div class="grid-item d"> </div> <div class="grid-item e"> </div> </div> <script src="js/masonry/masonry.pkgd.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var msnry = new Masonry('#grid', { itemSelector: '.grid-item', columnWidth: 200 }); </script> </body> </html>
運行結果:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>瀑布流佈局</title> <style type="text/css"> #grid { width: 1000px; margin: 0 auto; } </style> </head> <body> <div id="grid"> <div class="grid-item"> <a href="#"> <img src="img/h/h(1).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(2).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(3).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(4).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(11).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(12).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(5).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(6).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(7).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(8).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(11).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(12).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(9).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(10).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(11).jpg" width="200" /> </a> </div> <div class="grid-item"> <a href="#"> <img src="img/h/h(12).jpg" width="200" /> </a> </div> </div> <script src="js/masonry/masonry.pkgd.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> window.onload = function() { var msnry = new Masonry('#grid', { itemSelector: '.grid-item', columnWidth: 200 }); } </script> </body> </html>
運行結果:
注意:上面的示例中咱們使用了window.onload事件,緣由是若是圖片沒有加載完成就執行瀑布流佈局會引發堆疊的問題,其實就是初始化是沒有檢測到圖片的高度,window.onload在有許多圖片的環境下會有性能問題,這裏給你們介紹另外一個組件。
imagesLoaded 是一個用於來檢測網頁中的圖片是否載入完成的 JavaScript 工具庫。支持回調的獲取圖片加載的進度,還能夠綁定自定義事件。能夠結合 jQuery、RequireJS 使用。
官網:http://imagesloaded.desandro.com/
源碼:https://github.com/desandro/imagesloaded
示例代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>imagesLoaded – 檢測網頁中的圖片是否加載</title> </head> <body> <div id="div1"> <img src="img/h/h(2).jpg" width="300" /><img src="img/h/h(1).jpg" width="300" /> </div> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script src="js/imagesloaded-master/imagesloaded.pkgd.min.js" type="text/javascript" charset="utf-8"></script> <script> imagesLoaded(document.querySelector('#div1'), function(instance) { alert('全部的圖片都加載完成了'); }); $('#div1').imagesLoaded() .always(function(instance) { console.log('all images loaded'); }) .done(function(instance) { console.log('all images successfully loaded'); }) .fail(function() { console.log('all images loaded, at least one is broken'); }) .progress(function(instance, image) { var result = image.isLoaded ? 'loaded' : 'broken'; console.log('image is ' + result + ' for ' + image.img.src); }); </script> </body> </html>
運行結果:
Infinite Scroll也是基於jQuery插件,是一個用於滾動分頁的插件(當移動滾動條時將動態加載更多內容),有網友稱這種效果爲」無刷新無分頁完美瀑布流」展示方式。
官網:http://infinite-scroll.com/
源碼:https://github.com/infinite-scroll/infinite-scroll
經常使用屬性:
$('#masonny-div').infinitescroll({ navSelector : "#next", // 頁面分頁元素(成功後會被隱藏) nextSelector : "#next a", // 須要點擊的下一頁連接,和2的html要對應 itemSelector : ".item" , // ajax回來以後,每一項的selecter animate : true, //加載完畢是否採用動態效果 extraScrollPx: 100, //向下滾動的像素,必須開啓動態效果 // debug : true, //調試的時候,能夠打開 bufferPx : 5, //提示語展示的時長,數字越大,展示時間越短 loading: { finishedMsg: '沒有更多內容了', //當加載失敗,或者加載不出內容以後的提示語 img: 'loading-new.gif', //自定義loadding的動畫圖 msgText : '正在加載中...', //加載時的提示語 }, }, function( newElements, opt ) { //成功後執行自定義的函數 //若是須要對新內容進行加工,就在這裏實現 } };
屬性與事件官網有詳細的說明這裏只列出來了部分,下面是官網列出的選擇:
$('.selector').infinitescroll({ loading: { finished: undefined, finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>", img: null, msg: null, msgText: "<em>Loading the next set of posts...</em>", selector: null, speed: 'fast', start: undefined }, state: { isDuringAjax: false, isInvalidPage: false, isDestroyed: false, isDone: false, // For when it goes all the way through the archive. isPaused: false, currPage: 1 }, behavior: undefined, binder: $(window), // used to cache the selector for the element that will be scrolling nextSelector: "div.navigation a:first", navSelector: "div.navigation", contentSelector: null, // rename to pageFragment extraScrollPx: 150, itemSelector: "div.post", animate: false, pathParse: undefined, dataType: 'html', appendCallback: true, bufferPx: 40, errorCallback: function () { }, infid: 0, //Instance ID pixelsFromNavToBottom: undefined, path: undefined, // Can either be an array of URL parts (e.g. ["/page/", "/"]) or a function that accepts the page number and returns a URL maxPage:undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work) });
p1.html頁面:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .item { height: 200px; } </style> </head> <body> <h2>產品列表</h2> <div id="items"> <p class="item">產品一</p> <p class="item">產品一</p> <p class="item">產品一</p> <p class="item">產品一</p> <p class="item">產品一</p> <p class="item">產品一</p> </div> <a href="p2.html" id="next">下一頁</a> <script src="../js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script src="../js/infinite-scroll/jquery.infinitescroll.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $('#items').infinitescroll({ navSelector: "#next", // 頁面分頁元素(成功後會被隱藏) nextSelector: "a#next", // 須要點擊的下一頁連接,和2的html要對應 itemSelector: ".item", // ajax回來以後,每一項的selecter,好比每篇文章都有item這個class debug: true, //是否調試 dataType: 'html', //數據類型 maxPage: 3, //最大頁數 path: function(index) { //路徑 return "p" + index + ".html"; } }, function(newElements, data, url) { //成功後的回調 //console.log("路徑:" + url); $(newElements).css('background-color', '#ffef00'); // $(this).append(newElements); }); </script> </body> </html>
p2.html頁面:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>P2</title> </head> <body> <p class="item">產品二</p> <p class="item">產品二</p> <p class="item">產品二</p> <p class="item">產品二</p> <p class="item">產品二</p> <p class="item">產品二</p> </body> </html>
p3.html頁面:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>P3</title> </head> <body> <p class="item">產品三</p> <p class="item">產品三</p> <p class="item">產品三</p> <p class="item">產品三</p> <p class="item">產品三</p> <p class="item">產品三</p> </body> </html>
運行效果:
m1.html頁面:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>相冊</title> <style type="text/css"> .item { float: left; min-height: 300px; } </style> </head> <body> <h2>相冊</h2> <div id="items"> <p class="item"><img src="../img/i/1.jpg" /></p> <p class="item"><img src="../img/i/2.jpg" /></p> <p class="item"><img src="../img/i/3.jpg" /></p> <p class="item"><img src="../img/i/4.jpg" /></p> <p class="item"><img src="../img/i/5.jpg" /></p> <p class="item"><img src="../img/i/6.jpg" /></p> </div> <a href="m2.json" id="next"></a> <script src="../js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script src="../js/infinite-scroll/jquery.infinitescroll.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $('#items').infinitescroll({ navSelector: "#next", nextSelector: "a#next", itemSelector: ".item", debug: true, dataType: 'json', maxPage: 3, appendCallback:false, path: function(index) { return "m" + index + ".json"; } }, function(data) { for(var i=0;i<data.length;i++){ $("<p class='item'><img src='../img/i/"+data[i]+".jpg' /></p>").appendTo("#items"); } }); </script> </body> </html>
m2.json數據:
[7,8,9,10,11,12]
m3.json數據:
[13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
運行結果:
由於沒有使用瀑布流佈局因此有點不規整,這裏主要演示分頁。
做業:
完成一個瀑布流+延遲加載圖片的相冊或商品列表,要求圖片大小不一,示例。
一、有後臺,經過ajax加載後臺的json
二、200條數據以上
三、使用技術參考:masonry+imagesloaded+infinitescroll
@media早在css2.1中就有了,用於判斷媒介類型,如screen屏幕,print打印機,projection投影儀,all表示全部,固然還有許多不經常使用的。能夠指定CSS在什麼樣的媒介中應用,如只在打印時應用某些樣式,如:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>打印</title> <!--該樣式只會應用在打印時--> <style type="text/css" media="print"> .noprint { display:none; } div{ font-size:30px; } </style> </head> <body> <div> Installing Cordova Cordova command-line runs on Node.js and is available on NPM. Follow platform specific guides to install additional platform dependencies. Open a command prompt or Terminal, and type npm install -g cordova. </div> <button onclick="print();" class="noprint">打印</button> </body> </html>
不使用媒介時運行效果:
使用媒介時運行效果:
a)、內部樣式
@media screen and (width:800px){ … }
b)、導入樣式
@import url(example.css) screen and (width:800px);
c)、連接樣式
<link media="screen and (width:800px)" rel="stylesheet" href="example.css" />
d)、XML中應用樣式
<?xml-stylesheet media="screen and (width:800px)" rel="stylesheet" href="example.css" ?>
在頁面上放一個層,當屏幕大小在100-640之間時
示例代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>媒介查詢</title> <style type="text/css"> #div1 { background: lightblue; height: 100px; } @media only screen and (min-width: 100px) and (max-width: 640px) { #div1 { background: lightgreen; height: 200px; } } </style> </head> <body> <div id="div1"> Hello World! </div> </body> </html>
全屏時的運行效果:
縮小瀏覽器的效果:
@media queries是CSS3中引入的,不只能夠實現媒介類型的查詢能夠實現設備特性的查詢,能夠簡單認爲是對CSS2.1中的media的加強,基本語法以下:
@media [not|only] media_type and feature
not:取反操做
only:讓不支持media query的設備但讀取media type類型的瀏覽器忽略這個樣式
media_type:是媒介類型,具體以下:
feature:定義設備特性,多數容許加前綴min-,max-,多個條件可使用and鏈接,and兩側須要空格。
常見寫法:
@media only screen and (min-width: 320px) and (max-width: 640px) {
}
@media (min-device-width:1024px) and (max-width:989px),screen and (max-device-width:480px),(max-device-width:480px) and (orientation:landscape),(min-device-width:480px) and (max-device-width:1024px) and (orientation:portrait) { CSS樣式... }
and表示與,條件要同時知足;逗號表示或。
在前面的佈局中咱們學習柵格系統,這裏經過媒介查詢實現響應式柵格系統,腳本以下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>響應式柵格</title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <style type="text/css"> * { margin: 0; padding: 0; } html, body { height: 100%; font: 20px/20px "microsoft yahei"; } div { min-height: 100px; } .row { width: 800px; background: deepskyblue; margin: 0 auto; } .row:after { content: ' '; display: table; clear: both; } .col25 { width: 25%; background: lightgreen; } .col50 { width: 50%; background: lightcoral; } .col75 { width: 75%; background: lightblue; } [class*=col] { float: left; } /*0-480手機*/ @media only screen and (max-width:480px) { .row { width: 100%; } [class*=col] { float: none; margin-top: 5px; width: 100%; } } /*480-960平板,手機橫屏*/ @media only screen and (min-width: 480px) and (max-width: 960px) { .row { width: 480px; } } /*960PC屏幕*/ @media only screen and (min-width:960px) { .row { width: 960px; } } </style> </head> <body> <div id="container"> <div id="header" class="row"> header </div> <div id="main" class="row"> <div id="left" class="col25">left</div> <div id="center" class="col50">center</div> <div id="right" class="col25">right</div> </div> <div id="footer" class="row"> footer </div> </div> </body> </html>
示例代碼中經過@media設置了多個斷點,當知足條件時樣式會應用,達到響應式的目的,屏幕大960時:
480-960之間的效果:
在手機上模擬的效果:
respond.js是一個用於讓IE8如下瀏覽器支持@media queries的插件,也就是使用Respond.js能讓IE6-8支持CSS3 Media Query。Bootstrap裏面就引入了這個JS文件,壓縮後只有3KB。該腳本循環遍歷頁面上的全部 CSS 引用,並使用媒體查詢分析 CSS 規則。而後,該腳本會監控瀏覽器寬度變化,添加或刪除與 CSS 中媒體查詢匹配的樣式。最終結果是,可以在本來不支持的瀏覽器上運行媒體查詢。
要注意的問題:
if CSS files are encoded in UTF-8 with Byte-Order-Mark, they will not work with Respond.js in IE7 or IE8.
微軟的utf-8格式且BOM的文件會出問題,BOM格式文檔頭3個字節就是BOM,會影響程序對文檔的處理。
最近有測試發現IE8仍是出現了問題,動畫@keyframe中的@符號形成的影響會使respond.js失效,所以,在使用respond.js時,儘可能就不要用CSS3動畫。
下載地址:https://github.com/scottjehl/Respond/
引入方法:
<!--[if lt IE 9]> <script src="html5shiv.js"></script> <script src="respond.min.js"></script> <![endif]-->
a)、桌面優先(優雅降級)
這是一種傳統的作法,開發項目時優先PC端,而後再經過一些hack的方法讓項目正常運行在移動端,所謂的降級能夠簡單認爲就是將一些信息隱藏,由於移動端的可視範圍有限,必須給用戶提供簡潔核心的內容。
b)、移動優先(漸進加強)
a)、對於產品設計師,一個新產品先設計移動版,而後纔是桌面版。
b)、對於工程師,一個新產品,先開發移動版,而後纔是桌面版本。
這樣的好處是能把握好最核心最關鍵內容,讓界面簡潔。
練習1:
請模擬以下的響應式顯示效果,要求兼容各類設備:
練習2:
模擬:http://cordova.apache.org/頭部
PC端效果:
移動端效果:
viewport也稱視口,PC上是指瀏覽器窗口的可視區域。先了解兩個概念:
可見視口(visual viewport):瀏覽器窗口的可視區域
佈局視口(layout viewport):CSS在應用時所設置的佈局最大寬度。佈局視口能夠大於可見視口。
移動設備上的viewport都是要大於瀏覽器可視區域的、這樣就會產生一個默認縮放的結果,請看示例以下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>viewport</title> </head> <body> <p> viewport也稱視口,PC上是指瀏覽器窗口的可視區域。先了解兩個概念: 可見視口(visual viewport):瀏覽器窗口的可視區域 佈局視口(layout viewport):CSS在應用時所設置的佈局最大寬度。佈局視口能夠大於可見視口。 </p> </body> </html>
運行效果:
在手機上顯示的效果:
以上是iphone5顯示的效果,字體根本看不清楚緣由以下:
CSS中的1px並不等於設備的1px,PC中CSS的1個像素每每都是對應着電腦屏幕的1個物理像素
CSS中的像素是邏輯上的px
屏幕上的像素是物理上的px,二者有區別
要考慮PPI,pixels per inch每英寸像素數
當PPI爲90時每一個像素爲0.011英寸
iPhone4的PPI爲326,若是CSS像素再和設備像素保持對應,人眼將很難看清較小的字體或者圖案。
移動設備上的viewport分爲layout viewport、visual viewport和ideal viewport 三類,ideal viewport是最適合移動設備的viewport,ideal viewport的寬度等於移動設備的屏幕寬度,也就是寬度爲100%的效果。ideal viewport 的意義在於,不管在何種分辨率的屏幕下,那些針對ideal viewport 而設計的網站,不須要用戶手動縮放,也不須要出現橫向滾動條,均可以完美的呈現給用戶。
http://viewportsizes.com/ 各類設備ideal viewport
就是相同英寸下正常分辨率的PC機的物理像素!通常爲72px/英寸,即每英寸寬或高的屏幕有72個物理顏色點。
移動設備默認的viewport是layout viewport,也就是那個比屏幕要寬的viewport,但在進行移動設備網站的開發時,咱們須要的是ideal viewport。
利用meta標籤對viewport進行控制,如:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
參數解釋:
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>viewport</title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> </head> <body> <p> viewport也稱視口,PC上是指瀏覽器窗口的可視區域。先了解兩個概念: 可見視口(visual viewport):瀏覽器窗口的可視區域 佈局視口(layout viewport):CSS在應用時所設置的佈局最大寬度。佈局視口能夠大於可見視口。 </p> </body> </html>
效果:
首先若是不設置meta viewport標籤,那麼移動設備上瀏覽器默認的寬度(佈局視口)值爲800px,980px,1024px等這些,總之是大於屏幕寬度(可見視口)的。這裏的寬度所用的單位px都是指css中的px,它跟表明實際屏幕物理像素的px不是一回事。
每一個移動設備瀏覽器中都有一個理想的寬度(ideal viewport),這個理想的寬度是指css中的寬度,跟設備的物理寬度沒有關係,在css中,這個寬度就至關於100%的所表明的那個寬度。
通常在head中加上以下的meta便可:
<meta name="viewport" content="width=device-width, initial-scale=1" />
rem是CSS3新引進來的一個度量單位,相對長度單位。相對於根元素(即html元素)font-size計算值的倍數,如:
height:2rem;,則高度的大小爲32px(字體默認爲16px,chrome最小爲12px),若是根元素的字體爲15px,則結果爲30px。
頁面中的尺寸都以html元素的font-size爲相對單位,爲默認設置爲20px,若是須要一個200px的大小則使用10rem,而後當屏幕大小變化時經過javascript或media queries修改字體大小。
示例代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>rem</title> <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <style> html { height: 100%; width: 100%; font-family: 'Microsoft YaHei'; font-size: 20px; overflow: hidden; outline: 0; } body { height: 100%; margin: 0; overflow: hidden; -webkit-user-select: none; /*取消用戶選擇*/ width: 100%; } header, footer { width: 100%; line-height: 1.5rem; font-size: 1rem; color: #000; border: 1px solid #ccc; text-align: center; background-color: #ccc; } .bd { margin-top: 1rem; margin-bottom: .5rem; margin-right: -.5rem; font-size: 0; } .bd:after { clear: both; } .box { width: 5rem; height: 5rem; display: inline-block; margin-right: .5rem; margin-bottom: .5rem; } .blue-box { background-color: #06c; } .org-box { background-color: #1fc195; } </style> </head> <body> <header>我是頭部</header> <div class="bd"> <div class="box blue-box"></div> <div class="box org-box"></div> <div class="box blue-box"></div> <div class="box org-box"></div> <div class="box blue-box"></div> <div class="box org-box"></div> <div class="box blue-box"></div> <div class="box org-box"></div> <div class="box blue-box"></div> </div> <footer>我是頁腳</footer> <script> //定義一個方法並執行 (function(doc, win) { //得到文檔的根節點html var docEl = doc.documentElement; //若是window中存在orientationchange對象,則取orientationchange,不然取resize //爲了事件綁定 resizeEvt = 'orientationchange' in win ? 'orientationchange' : 'resize'; //定義一個方法,從新計算font-size大小 var recalc = function() { //頁面的寬度 var clientWidth = docEl.clientWidth; //若是沒有寬度則退出 if(!clientWidth) return; //從新計算font-size大小,假定320的寬度時字體大小爲20;,當頁面變化時從新設置字體大小 docEl.style.fontSize = 20 * (clientWidth / 320) + 'px'; }; //若是瀏覽器不支持添加事件監聽則結束 if(!doc.addEventListener) return; //添加事件監聽,指定事件處理函數的時期或階段(boolean)true表示在捕獲事件執行,false表示冒泡時執行 win.addEventListener(resizeEvt, recalc, false); //當Dom樹加載完成時執行計算,DOMContentLoaded事件要在window.onload以前執行 doc.addEventListener('DOMContentLoaded', recalc, false); })(document, window); </script> </body> </html>
運行效果:
示例代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>rem and media queries</title> <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <style> html { height: 100%; width: 100%; font-family: 'Microsoft YaHei'; font-size: 20px; overflow: hidden; outline: 0; } .box { width: 5rem; height: 5rem; display: inline-block; margin-right: .5rem; margin-bottom: .5rem; } .blue-box { background-color: #06c; } .org-box { background-color: #1fc195; } @media only screen and (max-width: 300px) { html { font-size: 10px; } } @media only screen and (min-width: 300px) and (max-width: 640px) { html { font-size: 20px; } } @media only screen and (min-width: 640px) and (max-width: 960px) { html { font-size: 30px; } } @media only screen and (min-width: 960px){ html { font-size: 40px; } } </style> </head> <body> <div class="bd"> <div class="box blue-box"></div> <div class="box org-box"></div> <div class="box blue-box"></div> <div class="box org-box"></div> <div class="box blue-box"></div> <div class="box org-box"></div> <div class="box blue-box"></div> <div class="box org-box"></div> <div class="box blue-box"></div> </div> </body> </html>
運行結果:
github:https://github.com/zhangguo5/CSS3_4.git
參照:http://www.cnblogs.com/best