一、负边距与浮动布局
1.1、负边距
所谓的负边距就是margin取负值的情况,如margin:-100px,margin:-100%。当一个元素与另一个元素margin取负值时将拉近距离。常见的功能如下:
1.1.1、向上移动
当多个元素同时从标准流中脱离开来时,如果前一个元素的宽度为100%宽度,后面的元素通过负边距可以实现上移。当负的边距超过自身的宽度将上移,只要没有超过自身宽度就不会上移,示例如下:
<!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%时运行效果:
margin-left:-30%时运行效果:
margin-left:-100%时运行效果:
1.1.2、去除列表右边框
开发中常需要在页面中展示一些列表,如商品展示列表等,如果我们要实现如下布局:
示例代码:
<!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>
运行后的结果:
但是上面的效果中右边多出了20px的距离,底下多出20px空白,解决方法如下:
<!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>
方法是使用了边距折叠,可以在前面的文章中查看到细节,基本原理如下图所示:
方法2
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>负边距</title> <style type="text/css"> * { margin: 0; padding: 0; } #div1 { width: 780px; margin: 0 auto; border: 3px solid lightblue; overflow: hidden; margin-top: 10px; } #div2{ margin-right: -20px; margin-bottom: -20px; overflow: auto; } .box { width: 180px; height: 180px; margin: 0 20px 20px 0; background: lightgreen; float: left; } </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>
效果:
1.1.3、负边距+定位,实现水平垂直居中
具体请参考《CSS3与页面布局学习总结(三)——BFC、定位、浮动、7种垂直居中方法》
1.1.4、去除列表最后一个li元素的border-bottom
方法一:
<!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;就可以解决这个问题。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> * { margin: 0; padding: 0; } ul { margin: 0 auto; margin-top: 20px; width: 260px; border: 2px solid #1FC195; list-style: none; } ul li { height: 30px; line-height: 30px; border-bottom: 1px dashed #1FC195; font-size: 14px; padding-left: 5px; } ul li:last-child { margin-bottom: -1px; } </style> </head> <body> <ul> <li>新闻列表新闻列表新闻列表</li> <li>新闻列表新闻列表新闻列表</li> <li>新闻列表新闻列表新闻列表</li> <li>新闻列表新闻列表新闻列表</li> <li>新闻列表新闻列表新闻列表</li> <li>新闻列表新闻列表新闻列表</li> <li>新闻列表新闻列表新闻列表</li> </ul> </body> </html>
运行结果:
1.2、双飞翼布局
经典三列布局,也叫做圣杯布局【Holy Grail of Layouts】是Kevin Cornell在2006年提出的一个布局模型概念,在国内最早是由淘宝UED的工程师传播开来,在中国也有叫法是双飞翼布局,它的布局要求有几点:
1、三列布局,中间宽度自适应,两边定宽;
2、中间栏要在浏览器中优先展示渲染;
3、允许任意列的高度最高;
4、要求只用一个额外的DIV标签;
5、要求用最简单的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占用的位置空出。
1.3、多栏布局
1.3.1、栅格系统
栏栅格系统就是利用浮动实现的多栏布局,在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列的栅格系统。
1.3.2、多列布局
栅格系统并没有真正实现分栏效果(如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>
运行结果:
二、弹性布局(Flexbox)
2.1、概要
假设在项目中有一个这样的需求:同一行有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属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。
2009年,W3C提出了一种新的方案—-Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。
2.2、Flex布局的定义
Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。
任何一个容器都可以指定为Flex布局,如果值为flex则容器为块标签。
.box{display:flex;}
行内元素也可以使用Flex布局,如果值为inline-flex则容器为行内标签。
.box{display:inline-flex;}
Webkit内核的浏览器,必须加上-webkit前缀。
.box{display:-webkit-flex;/* Safari */display:flex;}
注意,设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。
display属性值flex: 将对象作为弹性伸缩盒显示。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> #div1{ background: yellow; display: flex; height: 150px; } #div1 div,#div2 div{ width: 100px; height: 100px; background: #1fc195; } #div2{ background: yellow; display: inline-flex; height: 150px; } </style> </head> <body> <div id="div1"> <div>1</div> <div>2</div> <div>3</div> </div> <div id="div2"> <div>4</div> <div>5</div> <div>6</div> </div> </body> </html>
结果:
div2此时为内联元素,并未占用整行。
2.3、基本概念
采用Flex布局的元素,称为Flex容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”。
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
2.4、容器的属性
以下6个属性设置在容器上。
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
2.4.1、 flex-direction属性
flex-direction属性决定主轴的方向(即项目的排列方向)。
.box{flex-direction:row|row-reverse|column|column-reverse;}
它可能有4个值:
row(默认值):主轴为水平方向,起点在左端。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:20px/40px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ flex-direction: row; /**默认方向*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height: 100px; flex: auto; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
row-reverse:主轴为水平方向,起点在右端。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:20px/40px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ flex-direction: row-reverse; /**row-reverse:主轴为水平方向,起点在右端。*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height: 100px; flex: auto; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
column:主轴为垂直方向,起点在上沿。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:20px/40px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ flex-direction: column; /**column:主轴为垂直方向,起点在上沿。*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height: 100px; flex: auto; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
column-reverse:主轴为垂直方向,起点在下沿。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:20px/40px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ flex-direction: column-reverse; /**column-reverse:主轴为垂直方向,起点在下沿*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; } .a{ flex:1; } .b{ flex:2; } .c{ flex:3; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
把单项的flex属性取消可以查看起点位置。
2.4.2、flex-wrap属性
默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
.box{flex-wrap:nowrap|wrap|wrap-reverse;}
它可能取三个值。
(1)nowrap(默认):不换行。
(2)wrap:换行,第一行在上方。
(3)wrap-reverse:换行,第一行在下方。
2.4.3、flex-flow
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
.box{flex-flow:||;}
Flex容器可以设置属性flex-flow,取值为row,row-reverse,column,column-reverse四种值
row:显示在一行中
row-reverse:显示在一行中,反转
column:显示在一列中
column-reverse:显示在一列中 反转
取flex-wrap的值
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:20px/40px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ flex-flow: wrap-reverse; } #menu li { margin: 5px; background: lightgoldenrodyellow; height:100px; width: 200px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="a">4公司简介</li> <li class="b">5商品展示</li> <li class="c">6后台管理</li> <li class="a">7公司简介</li> <li class="b">8商品展示</li> <li class="c">9后台管理</li> </ul> </body> </html>
结果:
2.4.4、justify-content属性
justify-content属性定义了项目在主轴上的对齐方式。
.box{justify-content:flex-start|flex-end|center|space-between|space-around;}
它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。
flex-start(默认值):左对齐
示例:
<!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 { margin: 0 auto; display: flex; /**指定为弹性盒容器*/ background: lightgreen; height: 300px; justify-content:flex-start; } #menu li { margin: 5px; background: lightgoldenrodyellow; height: 100px; } .a,.c{ width: 100px; } .b{ width: 200px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
flex-end:右对齐
示例:
<!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 { margin: 0 auto; display: flex; /**指定为弹性盒容器*/ background: lightgreen; height: 300px; justify-content:flex-end; } #menu li { margin: 5px; background: lightgoldenrodyellow; height: 100px; } .a,.c{ width: 100px; } .b{ width: 200px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
center: 居中
示例:
<!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 { margin: 0 auto; display: flex; /**指定为弹性盒容器*/ background: lightgreen; height: 300px; justify-content:center; } #menu li { margin: 5px; background: lightgoldenrodyellow; height: 100px; } .a,.c{ width: 100px; } .b{ width: 200px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
space-between:两端对齐,项目之间的间隔都相等。
示例:
<!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 { margin: 0 auto; display: flex; /**指定为弹性盒容器*/ background: lightgreen; height: 300px; justify-content:space-between; } #menu li { margin: 5px; background: lightgoldenrodyellow; height: 100px; } .a,.c{ width: 100px; } .b{ width: 200px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
示例:
<!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 { margin: 0 auto; display: flex; /**指定为弹性盒容器*/ background: lightgreen; height: 300px; justify-content:space-around; } #menu li { margin: 5px; background: lightgoldenrodyellow; height: 100px; } .a,.c{ width: 100px; } .b{ width: 200px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
2.4.5、align-items属性
align-items属性定义项目在交叉轴上如何对齐。
.box{align-items:flex-start|flex-end|center|baseline|stretch;}
它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。
flex-start:交叉轴的起点对齐。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:20px/40px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ align-items: flex-start; /*交叉轴的起点对齐。*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height:100px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
flex-end:交叉轴的终点对齐。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:20px/40px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ align-items: flex-end; /*flex-end:交叉轴的终点对齐。*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height:100px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
center:交叉轴的中点对齐。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:20px/40px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ align-items: center; } #menu li { margin: 5px; background: lightgoldenrodyellow; height:100px; width: 200px; } #menu li.b{ height: 200px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
baseline: 项目的第一行文字的基线对齐。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:20px/40px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ align-items: baseline; /**baseline: 项目的第一行文字的基线对齐。*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height:100px; width: 200px; } #menu li.b{ height: 200px; font-size: 40px; } #menu li.d{ height: 230px; font-size: 40px; line-height: 100px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="d">4企业文化</li> </ul> </body> </html>
结果:
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:20px/40px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ align-items: stretch; /**stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。。*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; width: 200px; } #menu li.b{ height: 200px; font-size: 40px; } #menu li.d{ height: 230px; font-size: 40px; line-height: 100px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="d">4企业文化</li> </ul> </body> </html>
结果:
2.4.6、align-content属性
align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
.box{align-content:flex-start|flex-end|center|space-between|space-around|stretch;}
该属性可能取6个值。
flex-start:与交叉轴的起点对齐。
flex-end:与交叉轴的终点对齐。
center:与交叉轴的中点对齐。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:14px/20px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ flex-wrap: wrap; align-content: center; } #menu li { margin: 5px; background: lightgoldenrodyellow; height:30px; width: 200px; } #menu li.b{ width: 300px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> </ul> </body> </html>
结果:
space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值):轴线占满整个交叉轴。
align-content:center对单行是没有效果的,而align-items:center不管是对单行还是多行都有效果,而在我们日常开发中用的比较多的就是align-items。
2.5、项目的属性
以下6个属性设置在项目上。
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- align-self
2.5.1 order属性
order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
.item{order:;}
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:14px/20px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height:30px; width: 200px; order: 10; } #menu li.b{ width: 300px; order: 0; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="a">4公司简介</li> <li class="b">5商品展示</li> <li class="c">6后台管理</li> </ul> </body> </html>
结果:
2.5.2 flex-grow属性
flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
.item{flex-grow:;/* default 0 */}
如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
当flex-grow为默认值0时的示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:14px/20px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height:30px; width:100px; flex-grow: 0; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="a">4公司简介</li> <li class="b">5商品展示</li> <li class="c">6后台管理</li> </ul> </body> </html>
结果:
当flex-grow为1时的示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:14px/20px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height:30px; width:100px; flex-grow: 1; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="a">4公司简介</li> <li class="b">5商品展示</li> <li class="c">6后台管理</li> </ul> </body> </html>
结果:
当flex-grow为2时的示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:14px/20px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height:30px; width:100px; flex-grow: 1; } #menu li.b{ flex-grow: 2; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="a">4公司简介</li> <li class="b">5商品展示</li> <li class="c">6后台管理</li> </ul> </body> </html>
运行结果:
2.5.3 flex-shrink属性
flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
.item{flex-shrink:;/* default 1 */}
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
负值对该属性无效。
flex-shrink为0时不收缩示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:14px/20px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height:30px; width:300px; flex-shrink: 1; } #menu li.b{ flex-shrink: 0; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="a">4公司简介</li> <li class="b">5商品展示</li> <li class="c">6后台管理</li> </ul> </body> </html>
结果:
flex-shrink越大空间不足时收缩越多:
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:14px/20px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height:30px; width:300px; flex-shrink: 1; } #menu li.b{ flex-shrink: 2; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="a">4公司简介</li> <li class="b">5商品展示</li> <li class="c">6后台管理</li> </ul> </body> </html>
结果:
2.5.4 flex-basis属性
flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
.item{flex-basis:|auto;/* default auto */}
它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:14px/20px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ } #menu li { margin: 5px; background: lightgoldenrodyellow; height:30px; width:100px; } #menu li.b{ flex-basis: 200px; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="a">4公司简介</li> <li class="b">5商品展示</li> <li class="c">6后台管理</li> </ul> </body> </html>
结果:
2.5.5 flex属性
flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
.item{flex:none|[<\'flex-grow\'><\'flex-shrink\'>?||<\'flex-basis\'>]}
该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
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> <style> .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;} </style>
本例定义了父容器宽(即主轴宽)为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>
运行结果:
2.5.6 align-self属性
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
.item{align-self:auto|flex-start|flex-end|center|baseline|stretch;}
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:14px/20px "Microsoft YaHei"; } html, body { height: 100%; } #menu { margin: 0 auto; background: lightgreen; height: 300px; display: flex; /**指定为弹性盒容器*/ align-items: center; } #menu li { margin: 5px; background: lightgoldenrodyellow; height:30px; width:100px; } #menu li.b{ flex-basis: 200px; align-self: flex-end; } </style> </head> <body> <ul id="menu"> <li class="a">1公司简介</li> <li class="b">2商品展示</li> <li class="c">3后台管理</li> <li class="a">4公司简介</li> <li class="b">5商品展示</li> <li class="c">6后台管理</li> </ul> </body> </html>
该属性可能取6个值,除了auto,其他都与align-items属性完全一致。
2.6、flex 布局应用
2.6.1、flex设置元素垂直居中对齐
在之前的一篇文章中记载过如何垂直居中对齐,方法有很多,但是在学习了flex布局之后,垂直居中更加容易实现
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> *{ margin: 0; padding: 0; } .demo { width: 500px; height: 300px; background: lightgreen; display: flex; /*设置为flex布局*/ justify-content: center; /*水平居中*/ align-items: center; /*垂直居中*/ } </style> </head> <body> <div class="demo"> <img src="../img/tv.png"/> </div> </body> </html>
运行结果:
2.6.2、用flex布局制作导航栏
以前在写导航栏的时候,总是用float或者display:inline-block实现,但是这两种方法都会有各种问题,比如浮动会影响父元素以及兄弟元素的样式,需要清除浮动
现在用flex会很方便,并且是弹性布局
代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>flex</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; font:20px/40px "Microsoft YaHei"; } ul{ display: flex; } li{ flex: 1; text-align: center; background: lightsalmon; color: white; border-right: 1px solid #fff; } li:last-child{ border-right: 0; } </style> </head> <body> <ul id="menu"> <li class="a">公司简介</li> <li class="b">商品展示</li> <li class="c">后台管理</li> </ul> </body> </html>
效果如图所示:
我们只要在HTML代码里面多加两个li元素,导航便弹性变化
不需要改变css代码,即可在导航栏中增加项目
2.6.3、图文列表
有时候需要做成左图右文字的样式,如下图所示:
此时用flex会很方便
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>多列布局</title> <style type="text/css"> .demo { display: flex; /*设置为flex布局*/ justify-content: space-around; margin-bottom: 10px; border: 2px solid #528CE0; padding: 10px; } .demo > div { flex: none; } .left { width: 30%; width: 30%; background: #d4cdcd; } .right { width: 60%; height: 200px; } .btn{ background: #528CE0; color: white; width: 70px; } </style> </head> <body> <div class="demo"> <div class="left"></div> <div class="right"> <p>产品标题产品标题产品标题</p> <span>总人数99</span> <span>剩余人数33</span> <div class="btn">立即参与</div> </div> </div> <div class="demo"> <div class="left"></div> <div class="right"> <p>产品标题产品标题产品标题</p> <span>总人数99</span> <span>剩余人数33</span> <div class="btn">立即参与</div> </div> </div> <div class="demo"> <div class="left"></div> <div class="right"> <p>产品标题产品标题产品标题</p> <span>总人数99</span> <span>剩余人数33</span> <div class="btn">立即参与</div> </div> </div> <div class="demo"> <div class="left"></div> <div class="right"> <p>产品标题产品标题产品标题</p> <span>总人数99</span> <span>剩余人数33</span> <div class="btn">立即参与</div> </div> </div> </body> </html>
运行结果:
甚至有多列布局,
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>多列布局</title> <style type="text/css"> .demo{ width: 600px; height: 150px; border: 1px solid #b7b2b7; margin: 30px auto; padding-top: 17px; display: flex; /*设置为flex布局*/ justify-content: space-around; } .demo > div{ flex: none; } </style> </head> <body> <div class="demo"> <div class="left"></div> <div class="center"> <p>description</p> <p>description</p> <p>description</p> <span>description</span> </div> <div class="btn">确认</div> <div class="btn">取消</div> </div> <div class="demo"> <div class="left"></div> <div class="center"> <p>description</p> <p>description</p> <p>description</p> <span>description</span> </div> <div class="btn">确认</div> <div class="btn">取消</div> </div> <div class="demo"> <div class="left"></div> <div class="center"> <p>description</p> <p>description</p> <p>description</p> <span>description</span> </div> <div class="btn">确认</div> <div class="btn">取消</div> </div> </body> </html>
结果:
2.6.4、固定百分比布局
HTML代码:
<div class="demo">
<div class="item item1"></div>
<div class="item item2"></div>
<div class="item item3"></div>
<div class="item item4"></div>
</div>
(1) 等分布局:
CSS代码:
.demo{
display: flex;
}
.item{
flex: 1;
}
(2)某一个固定
CSS代码:
.demo{
display: flex;
}
.item{
flex: 1;
}
.item2{
flex: 0 0 50%;
}
(3)某两个固定
CSS代码:
.demo{
display: flex;
}
.item{
flex: 1;
}
.item2{
flex: 0 0 50%;
}
.item4{
flex: 0 0 20%;
}
(4)三个固定
CSS代码:
.demo{
display: flex;
}
.item{
flex: 1;
}
.item1{
flex: 0 0 10%;
}
.item2{
flex: 0 0 50%;
}
.item4{
flex: 0 0 20%;
}
2.6.5. 圣杯布局
HTML代码:
<div class="demo">
<div class="header">头部</div>
<div class="body">
<div class="left">left</div>
<div class="center">center</div>
<div class="right">right</div>
</div>
<div class="footer">底部</div>
</div>
CSS代码:
.demo{
display: flex;
flex-direction: column;
}
.demo div{
flex: 1;
}
.body{
display: flex;
}
.header,.footer,.left,.right{
flex: 0 0 20%!important;
}
2.6.6、输入框布局
有时需要在输入框的前部添加提示,或者后部添加按钮,如图所示:
HTML代码:
<div class="demo">
<span class="tip"></span>
<input type="text" name="" />
<button>search</button>
</div>
CSS代码:
.demo{
display: flex;
}
input{
flex:1;
}
2.6.7、 底部footer固定在底部,但是不是fixed定位
页面会经常用到固定的底栏,但是当页面内容过少时,footer会到页面中间,下面用flex来解决
HTML代码:
<div class="demo">
<div class="main">这是主要内容</div>
<div class="footer">这是底部</div>
</div>
CSS代码:
.demo{
display: flex;
flex-direction: column;
}
.main{
flex: 1;
}
.footer{
width: 100%;
height: 120px;
}
2.6.8. 流式布局
如下如所示:
HTML代码如下:
<div class="demo">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
CSS代码:
.demo{
width: 258px;
height: 300px;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
}
.item{
flex: 0 0 33.333333%;
height: 80px;
box-sizing: border-box;
}
2.7、小节
a)、弹性布局默认不改变项目的宽度,但是它默认改变项目的高度。如果项目没有显式指定高度,就将占据容器的所有高度。
b)、虽然 Flexbox 非常适合缩放,对齐和重新排序元素,但以下情况应该尽量避免使用 Flexbox 布局:
1.整体页面布局
2.完全支持旧浏览器的网站
三、流式布局(Fluid)
固定布局和流式布局在网页设计中最常用的两种布局方式。固定布局能呈现网页的原始设计效果,流式布局则不受窗口宽度影响,流式布局使用百分比宽度来限定布局元素,这样可以根据客户端分辨率的大小来进行合理的显示。
固定布局效果:
流式布局效果:
利用前面的知识点可以实现这两种布局,这里就不去实现了
三、瀑布流布局
瀑布流布局是流式布局的一种。是当下比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。最早采用此布局的网站是Pinterest,逐渐在国内流行开来。
3.1、常见瀑布流布局网站
鼻祖:Pinterest
通用类:豆瓣市集,花瓣网,我喜欢,读图知天下
美女图片:图丽网
时尚资讯类:看潮网
时尚购物类:蘑菇街,美丽说,人人逛街,卡当网
品牌推广类:凡客达人
家居o2o类:新巢网小猫家
微博社交类: 都爱看
搞笑图片类:道趣儿
艺术收藏类:微艺术
潮流图文分享:荷都分享网
3.2、特点
优点
1、有效的降低了界面复杂度,节省了空间:我们不再需要臃肿复杂的页码导航链接或按钮了。
2、对触屏设备来说,交互方式更符合直觉:在移动应用的交互环境当中,通过向上滑动进行滚屏的操作已经成为最基本的用户习惯,而且所需要的操作精准程度远远低于点击链接或按钮。
3、更高的参与度:以上两点所带来的交互便捷性可以使用户将注意力更多的集中在内容而不是操作上,从而让他们更乐于沉浸在探索与浏览当中。
缺点
1. 有限的用例:
无限滚动的方式只适用于某些特定类型产品当中一部分特定类型的内容。
例如,在电商网站当中,用户时常需要在商品列表与详情页面之间切换,这种情况下,传统的、带有页码导航的方式可以帮助用户更稳妥和准确的回到某个特定的列表页面当中。
2. 额外的复杂度:
那些用来打造无限滚动的JS库虽然都自称很容易使用,但你总会需要在自己的产品中进行不同程度的定制化处理,以满足你们自己的需求;另外这些JS库在浏览器和设备兼容性等方面的表现也参差不齐,你必须做好充分的测试与调整工作。
3. 再见了,页脚:
如果使用了比较典型的无限滚动加载模式,这就意味着你可以和页脚说拜拜了。
最好考虑一下页脚对于你的网站,特别是用户的重要性;如果其中确实有比较重要的内容或链接,那么最好换一种更传统和稳妥的方式。
千万不要耍弄你的用户,当他们一次次的浏览到页面底部,看到页脚,却因为自动加载的内容突然出现而无论如何都无法点击页脚中的链接时,他们会变的越发愤怒。
5. SEO:
集中在一页当中动态加载数据,与一页一页的输出相比,究竟那种方式更利于SEO,这是你必须考虑的问题。对于某些以类型网站来说,在这方面进行冒险是很不划算的。
6. 关于页面数量的印象:
其实站在用户的角度来看,这一点并非负面;不过,如果对于你的网站来说,通过更多的内容页面展示更多的相关信息(包括广告)是很重要的策略,那么单页无限滚动的方式对你并不适用。
3.3、masonry实现瀑布流布局
masonry是一个响应式网格布局库(非jQuery)。(Cascading grid layout library)
如果使用CSS+JavaScript当然可以实现瀑布流布局,但相对麻烦,masonry是一个javascript插件,通过该插件可以轻松实现瀑布流布局,和CSS中float的效果不太一样的地方在 于,float先水平排列,然后再垂直排列,使用Masonry则垂直排列元素,然后将下一个元素放置到网格中的下一个开发区域。这种效果可以最小化处理 不同高度的元素在垂直方向的间隙。
官网:http://masonry.desandro.com/
源码:https://github.com/desandro/masonry
3.3.1、下载并引用masonry
可以去官网或github下载“masonry.pkgd.min.js”,将下载到的插件添加到项目中,并在页面中添加引用,如下所示:
<script src="js/masonry/masonry.pkgd.min.js" type="text/javascript" charset="utf-8"></script>
- masonry.pkgd.js un-minified
- masonry.pkgd.min.js minified
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>
3.3.2、准备内容
在页面中使用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>
没有使用瀑布流布局时的效果:
3.3.3、初始化插件
使用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>
运行结果:
3.3.4、使用了图片的瀑布流
<!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在有许多图片的环境下会有性能问题,这里给大家介绍另一个组件。
3.3.5、图片基础
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>图片</title> </head> <body> <img src="#" lowsrc="../img/mm.jpg" alt="家" title="家俱" longdesc="http://www.baidu.com" onload="console.log(\'加载完成a\')" onerror="console.log(\'加载失败a\')" /> <img src="#" lowsrc="../img/mm.jpg" alt="家" title="家俱" longdesc="http://www.baidu.com" onload="console.log(\'加载完成b\')" onerror="this.src=\'../img/phone.png\';" /> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script type="text/javascript"> var img=$("<img src=\'../img/css_sprites.png\'/>"); img.load(function(){ console.log(\'图片加载完成!\'); $("body").append(img); }); </script> </body> </html>
结果:
3.4、图片加载处理
3.4.1、imagesLoaded 图片加载进度监听
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>
运行结果:
示例2:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>imagesLoaded – 检测网页中的图片是否加载</title> </head> <body> <div id="div1"> <h2 id="msg"></h2> <img src="../img/h/h(2).jpg" width="300" /><img src="../img/h/h(1).jpg" width="300" /> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319210707776-403119185.png" alt="" /></p> <p>管理信息系统登录界面:</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319210724979-1119915147.jpg" alt="" /></p> <p>管理信息系统后台界面:</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319210738432-854332365.jpg" alt="" /></p> <p><img src="http://images2015.cnblogs.com/blog/63651/201704/63651-20170403153745066-468375996.png" alt="" /></p> <p><img src="http://images2015.cnblogs.com/blog/63651/201704/63651-20170403153851988-693921773.png" alt="" /></p> <p><img src="http://images2015.cnblogs.com/blog/63651/201704/63651-20170403153959957-1916226567.png" alt="" /></p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170320102945752-510492367.png" alt="" /></p> <p>后台UI源文件效果预览1.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211458479-1573731955.jpg" alt="" /></p> <p>后台UI源文件效果预览2.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211514635-1085976697.jpg" alt="" /></p> <p>后台UI源文件效果预览3.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211522495-367520285.jpg" alt="" /></p> <p>后台UI源文件效果预览4.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211533416-313715133.jpg" alt="" /></p> <p>后台UI源文件效果预览5.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211601260-1282800119.jpg" alt="" /></p> <p>后台UI源文件效果预览6.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211651541-257820397.jpg" alt="" /></p> <p>后台UI源文件效果预览7.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211733963-600455455.jpg" alt="" /></p> <p>后台UI源文件效果预览8.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211741229-375627068.jpg" alt="" /></p> <p>后台UI源文件效果预览9.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211747495-1038741445.jpg" alt="" /></p> <p>后台UI源文件效果预览10.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211821541-1870563995.jpg" alt="" /></p> <p>后台UI源文件效果预览11.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211847526-88858662.jpg" alt="" /></p> <p>后台UI源文件效果预览12.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211918901-1487416243.jpg" alt="" /></p> <p>后台UI源文件效果预览13.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211935198-1455577157.jpg" alt="" /></p> <p>后台UI源文件效果预览14.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211939698-2023943995.jpg" alt="" /></p> <p>后台UI源文件效果预览15.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319211955979-1280535056.jpg" alt="" /></p> <p>后台UI源文件效果预览16.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212002260-769742404.jpg" alt="" /></p> <p>后台UI源文件效果预览17.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212019526-1867955856.jpg" alt="" /></p> <p>后台UI源文件效果预览18.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212027198-1710146675.jpg" alt="" /></p> <p>后台UI源文件效果预览19.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212033088-1858074339.jpg" alt="" /></p> <p>后台UI源文件效果预览20.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212038948-1018032788.jpg" alt="" /></p> <p>后台UI源文件效果预览21.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212044448-485785412.jpg" alt="" /></p> <p>后台UI源文件效果预览22.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212050620-2069625287.jpg" alt="" /></p> <p>后台UI源文件效果预览23.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212055323-72502592.jpg" alt="" /></p> <p> </p> <p> </p> <p>后台UI源文件效果预览24.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212101307-1670477572.jpg" alt="" /></p> <p>后台UI源文件效果预览25.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212107041-1752314202.jpg" alt="" /></p> <p>后台UI源文件效果预览26.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212113573-843908032.jpg" alt="" /></p> <p>后台UI源文件效果预览27.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212119479-1961410540.jpg" alt="" /></p> <p>后台UI源文件效果预览28.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212124588-2050526211.jpg" alt="" /></p> <p>后台UI源文件效果预览29.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212133963-345654335.jpg" alt="" /></p> <p>后台UI源文件效果预览30.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212139651-2085714868.jpg" alt="" /></p> <p>后台UI源文件效果预览31.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212209963-1505909711.jpg" alt="" /></p> <p>后台UI源文件效果预览32.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212217323-1285298741.jpg" alt="" /></p> <p>后台UI源文件效果预览33.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212224932-1909112377.jpg" alt="" /></p> <p>后台UI源文件效果预览34.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212234276-1478200637.jpg" alt="" /></p> <p>后台UI源文件效果预览35.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212535416-746129132.jpg" alt="" /></p> <p>后台UI源文件效果预览36.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212541354-451500014.jpg" alt="" /></p> <p>后台UI源文件效果预览37.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212613760-844809474.jpg" alt="" /></p> <p>后台UI源文件效果预览38.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212620557-776804426.jpg" alt="" /></p> <p>后台UI源文件效果预览39.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212628276-1531913723.jpg" alt="" /></p> <p>后台UI源文件效果预览40.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212636713-1576030888.jpg" alt="" /></p> <p>后台UI源文件效果预览41.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212645213-1328314494.jpg" alt="" /></p> <p>后台UI源文件效果预览42.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212653916-1728096300.jpg" alt="" /></p> <p>后台UI源文件效果预览43.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212702307-1916172043.jpg" alt="" /></p> <p>后台UI源文件效果预览44.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212711729-767609725.jpg" alt="" /></p> <p>后台UI源文件效果预览45.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212720245-1474820956.jpg" alt="" /></p> <p>后台UI源文件效果预览46.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212728979-1033613408.jpg" alt="" /></p> <p>后台UI源文件效果预览47.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212736995-992230524.jpg" alt="" /></p> <p>后台UI源文件效果预览48.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212749260-266950659.jpg" alt="" /></p> <p>后台UI源文件效果预览49.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212757245-1650723680.jpg" alt="" /></p> <p>后台UI源文件效果预览50.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212822463-1289739165.jpg" alt="" /></p> <p>后台UI源文件效果预览51.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212830416-720826789.jpg" alt="" /></p> <p>后台UI源文件效果预览52.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212840620-623419195.jpg" alt="" /></p> <p>后台UI源文件效果预览53.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212851073-2070968428.jpg" alt="" /></p> <p>后台UI源文件效果预览54.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212858885-721901521.jpg" alt="" /></p> <p>后台UI源文件效果预览55.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212907182-117093308.jpg" alt="" /></p> <p>后台UI源文件效果预览56.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212914635-418040247.jpg" alt="" /></p> <p>后台UI源文件效果预览57.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212922385-1216341652.jpg" alt="" /></p> <p>后台UI源文件效果预览58.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212930291-527202617.jpg" alt="" /></p> <p>后台UI源文件效果预览59.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212937479-238445367.jpg" alt="" /></p> <p> </p> <p>后台UI源文件效果预览60.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212949495-1168504867.jpg" alt="" /></p> <p>后台UI源文件效果预览61.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319212957495-587805195.jpg" alt="" /></p> <p>后台UI源文件效果预览62.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213006166-887235383.jpg" alt="" /></p> <p>后台UI源文件效果预览63.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213013995-1880131966.jpg" alt="" /></p> <p>后台UI源文件效果预览64.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213022463-479679065.jpg" alt="" /></p> <p>后台UI源文件效果预览65.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213031854-307158776.jpg" alt="" /></p> <p>后台UI源文件效果预览66.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213038838-982540405.jpg" alt="" /></p> <p>后台UI源文件效果预览67.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213049307-210755769.jpg" alt="" /></p> <p>后台UI源文件效果预览68.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213056651-88654019.jpg" alt="" /></p> <p>后台UI源文件效果预览69.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213103651-1340111007.jpg" alt="" /></p> <p>后台UI源文件效果预览70.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213111979-1990254477.jpg" alt="" /></p> <p>后台UI源文件效果预览71.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213123120-42377418.jpg" alt="" /></p> <p>后台UI源文件效果预览72.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213130307-473956631.jpg" alt="" /></p> <p>后台UI源文件效果预览73.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213141307-8268135.jpg" alt="" /></p> <p>后台UI源文件效果预览74.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213153510-644201557.jpg" alt="" /></p> <p>后台UI源文件效果预览75.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213201666-1574964734.jpg" alt="" /></p> <p>后台UI源文件效果预览76.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213212198-725946488.jpg" alt="" /></p> <p>后台UI源文件效果预览77.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213219276-568665808.jpg" alt="" /></p> <p>后台UI源文件效果预览78.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213227166-1096207415.jpg" alt="" /></p> <p>后台UI源文件效果预览78.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213234291-512151309.jpg" alt="" /></p> <p>后台UI源文件效果预览80.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213241213-1353552770.jpg" alt="" /></p> <p>后台UI源文件效果预览81.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213248166-1202711403.jpg" alt="" /></p> <p>后台UI源文件效果预览82.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213258245-1102416390.jpg" alt="" /></p> <p>后台UI源文件效果预览83.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213305838-865548337.jpg" alt="" /></p> <p>后台UI源文件效果预览84.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213312166-424235563.jpg" alt="" /></p> <p>后台UI源文件效果预览85.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213320182-310152719.jpg" alt="" /></p> <p>后台UI源文件效果预览86.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213330495-1303439323.jpg" alt="" /></p> <p>后台UI源文件效果预览87.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213338557-1213240156.jpg" alt="" /></p> <p>后台UI源文件效果预览88.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213346510-1570198481.jpg" alt="" /></p> <p>后台UI源文件效果预览89.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213356448-1692105900.jpg" alt="" /></p> <p>后台UI源文件效果预览90.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213404604-910791420.jpg" alt="" /></p> <p>后台UI源文件效果预览91.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213411526-539349830.jpg" alt="" /></p> <p>后台UI源文件效果预览92.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213429401-718695402.jpg" alt="" /></p> <p>后台UI源文件效果预览93.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213448979-907316264.jpg" alt="" /></p> <p>后台UI源文件效果预览94.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213500870-448776637.jpg" alt="" /></p> <p>后台UI源文件效果预览95.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213508682-657176788.jpg" alt="" /></p> <p>后台UI源文件效果预览96.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213518026-1052811140.jpg" alt="" /></p> <p>后台UI源文件效果预览97.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213525932-1326458502.jpg" alt="" /></p> <p>后台UI源文件效果预览98.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213533370-1038572861.jpg" alt="" /></p> <p>后台UI源文件效果预览99.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213540807-1750200096.jpg" alt="" /></p> <p>后台UI源文件效果预览100.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213548229-1349456854.jpg" alt="" /></p> <p>后台UI源文件效果预览101.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213555620-1293747046.jpg" alt="" /></p> <p>后台UI源文件效果预览102.jpg</p> <p><img src="http://images2015.cnblogs.com/blog/63651/201703/63651-20170319213602541-1840125225.jpg" alt="" /></p> <p>后台UI源文件效果预览103.jpg</p> </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(\'所有的图片都加载完成了\'); }); var count = $("#div1 img").size(); var i = 0; $(\'#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) { i++; $("#msg")[0].innerHTML +=Math.round(i * 100 / count) + "%" + " ->"; var result = image.isLoaded ? \'loaded\' : \'broken\'; console.log(\'image is \' + result + \' for \' + image.img.src); }); </script> </body> </html>
效果:
3.4.2、图片延迟加载
jQuery图片延迟加载插件jQuery.lazyload,使用延迟加载在可提高网页下载速度。在某些情况下,它也能帮助减轻服务器负载。
基于 jQuery 的图片延迟加载插件,在用户滚动页面到图片之后才进行加载。对于有较多的图片的网页,使用图片延迟加载,能有效的提高页面加载速度。
官网:https://appelsiini.net/projects/lazyload/
帮助:http://code.ciaoca.com/jquery/lazyload/
注意事项:
需要真正实现图片延迟加载,必须将真实图片地址写在 data-original 属性中。若 src 与 data-original 相同,则只是一个特效而已,并不达到延迟加载的功能。
使用方法
引用jquery和jquery.lazyload.js到你的页面
<script src="jquery-1.11.0.min.js"></script> <script src="jquery.lazyload.js?v=1.9.1"></script>
html图片调用方法
为图片加入样式lazy 图片路径引用方法用data-original
<img class="lazy" data-original="img/bmw_m1_hood.jpg"> <img class="lazy" data-original="img/bmw_m1_side.jpg"> <img class="lazy" data-original="img/viper_1.jpg"> <img class="lazy" data-original="img/viper_corner.jpg"> <img class="lazy" data-original="img/bmw_m3_gt.jpg"> <img class="lazy" data-original="img/corvette_pitstop.jpg">
js出始化lazyload并设置图片显示方式
<script type="text/javascript" charset="utf-8"> $(function() { $("img.lazy").lazyload({effect: "fadeIn"}); }); </script>
在图片中也可以不使用 class="lazy",初始化时使用:
$("img").lazyload({effect: "fadeIn"});
这样就可以对全局的图片都有效!
如果想提载入图片,可以使用 threshold 进行设置,
$("img.lazy").lazyload({ threshold :180});
以上实例的含义是:在图片距离屏幕180px时提前载入:
引入
<script src="jquery-1.11.0.min.js"></script> <script src="jquery.lazyload.js?v=1.9.1"></script>
路径依据实际目录来确定。
<script type="text/javascript" charset="utf-8"> $(function() { $("img.lazy").lazyload({effect: "fadeIn"}); }); </script>
图片引用lazyload 方式
<img class="lazy" data-original="img/bmw_m1_hood.jpg" />
参数设置
$("img.lazy").lazyload({ placeholder : "img/grey.gif", //用图片提前占位 // placeholder,值为某一图片路径.此图片用来占据将要加载的图片的位置,待图片加载时,占位图则会隐藏 effect: "fadeIn", // 载入使用何种效果 // effect(特效),值有show(直接显示),fadeIn(淡入),slideDown(下拉)等,常用fadeIn threshold: 200, // 提前开始加载 // threshold,值为数字,代表页面高度.如设置为200,表示滚动条在离目标位置还有200的高度时就开始加载图片,可以做到不让用户察觉 event: \'click\', // 事件触发时才加载 // event,值有click(点击),mouseover(鼠标划过),sporty(运动的),foobar(…).可以实现鼠标莫过或点击图片才开始加载,后两个值未测试… container: $("#container"), // 对某容器中的图片实现效果 // container,值为某容器.lazyload默认在拉动浏览器滚动条时生效,这个参数可以让你在拉动某DIV的滚动条时依次加载其中的图片 failurelimit : 10 // 图片排序混乱时 // failurelimit,值为数字.lazyload默认在找到第一张不在可见区域里的图片时则不再继续加载,但当HTML容器混乱的时候可能出现可见区域内图片并没加载出来的情况,failurelimit意在加载N张可见区域外的图片,以避免出现这个问题. });
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> img { display: block; margin-bottom: 500px; } </style> </head> <body> <div id="div1"> <img data-original="../img/animal/1.jpg" src="../demo06_css303/daddcart.jpg"/> <img data-original="../img/animal/2.jpg" src="../demo06_css303/daddcart.jpg"/> <img data-original="../img/animal/3.jpg" src="../demo06_css303/daddcart.jpg"/> <img data-original="../img/animal/4.jpg" /> <img data-original="../img/animal/5.jpg" /> <img data-original="../img/animal/6.jpg" /> <img data-original="../img/animal/7.jpg" /> <img data-original="../img/animal/8.jpg" /> <img data-original="../img/animal/9.jpg" /> <img data-original="../img/animal/10.jpg" /> <img data-original="../img/animal/11.jpg" /> <img data-original="../img/animal/12.jpg" /> </div> <script src="../js/jquery-1.11.3.js" type="text/javascript" charset="utf-8"></script> <script src="../js/jquery_lazyload197/jquery.lazyload.min.js?v=1.9.7" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $("#div1 img").lazyload({ "effect":"fadeIn", "effectspeed":"3000" }); </script> </body> </html>
结果:
3.5、Infinite Scroll 滚动分页
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) });
3.5.1、异步加载普通页面
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>
运行效果:
3.5.2、异步加载json并解析
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]
运行结果:
因为没有使用瀑布流布局所以有点不规整,这里主要演示分页。
四、响应式布局(Responsive)
4.1、媒介类型
@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>
不使用媒介时运行效果:
使用媒介时运行效果:
4.2、媒介查询的应用位置(Media Queries)
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" ?>
4.3、Media Queries Hello World
在页面上放一个层,当屏幕大小在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>
全屏时的运行效果:
缩小浏览器的效果:
4.4、媒介查询语法
@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表示与,条件要同时满足;逗号表示或。
4.5、响应式栅格系统(Responsive)
在前面的布局中我们学习栅格系统,这里通过媒介查询实现响应式栅格系统,脚本如下:
<!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之间的效果:
在手机上模拟的效果:
4.6、respond.js
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]-->
4.7、移动优先(Mobile First)
a)、桌面优先(优雅降级)
这是一种传统的做法,开发项目时优先PC端,然后再通过一些hack的方法让项目正常运行在移动端,所谓的降级可以简单认为就是将一些信息隐藏,因为移动端的可视范围有限,必须给用户提供简洁核心的内容。
b)、移动优先(渐进增强)
a)、对于产品设计师,一个新产品先设计移动版,然后才是桌面版。
b)、对于工程师,一个新产品,先开发移动版,然后才是桌面版本。
这样的好处是能把握好最核心最关键内容,让界面简洁。
练习
4.8、视区(viewport)
4.8.1、需要设置viewport的原因
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。
常用主流移动设备CSS3 Media Queries整理
@charset "utf-8";
/**
* iPhone 4/4s landscape & portrait
*/
@media only screen
and (min-device-width: 320px)
and (max-device-width: 480px) {
}
/**
* iPhone 4/4s portrait
*/
@media only screen
and (min-device-width: 320px)
and (max-device-width: 480px)
and (orientation:portrait) {
}
/**
* iPhone 4/4s landscape
*/
@media only screen
and (min-device-width: 320px)
and (max-device-width: 480px)
and (orientation:landscape) {
}
/**
* iPhone 5/5s landscape & portrait
*/
@media only screen
and (min-device-width: 320px)
and (max-device-width: 568px) {
}
/**
* iPhone 5/5s portrait
*/
@media only screen
and (min-device-width: 320px)
and (max-device-width: 568px)
and (orientation: portrait) {
}
/**
* iPhone 5/5s landscape
*/
@media only screen
and (min-device-width: 320px)
and (max-device-width: 568px)
and (orientation: landscape) {
}
/**
* iPhone 6 landscape & Portrait
*/
@media only screen
and (min-device-width: 375px)
and (max-device-width: 667px) {
}
/**
* iPhone 6 Portrait
*/
@media only screen
and (min-device-width: 375px)
and (max-device-width: 667px)
and (orientation : portrait) {
}
/**
* iPhone 6 landscape
*/
@media only screen
and (min-device-width: 375px)
and (max-device-width: 667px)
and (orientation : landscape) {
}
/**
* iPhone 6+ Portrait
*/
@media only screen
and (min-device-width: 414px)
and (max-device-width: 736px)
and (orientation : portrait) {
}
/**
* iPhone 6+ landscape
*/
@media only screen
and (min-device-width: 414px)
and (max-device-width: 736px)
and (orientation : landscape) {
}
/**
* Galaxy S3 landscape & portrait
*/
@media screen
and (device-width: 320px)
and (device-height: 640px) {
}
/**
* Galaxy S3 portrait
*/
@media screen
and (device-width: 320px)
and (device-height: 640px)
and (orientation: portrait) {
}
/**
* Galaxy S3 landscape
*/
@media screen
and (device-width: 320px)
and (device-height: 640px)
and (orientation: landscape) {
}
/**
* Galaxy S5 landscape & portrait
*/
@media screen
and (device-width: 360px)
and (device-height: 640px) {
}
/**
* Galaxy S5 portrait
*/
@media screen
and (device-width: 360px)
and (device-height: 640px)
and (orientation: portrait) {
}
/**
* Galaxy S5 landscape
*/
@media screen
and (device-width: 360px)
and (device-height: 640px)
and (orientation: landscape) {
}
/**
* iPad landscape & portrait
*/
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (-webkit-min-device-pixel-ratio: 1) {
}
/**
* iPad portrait
*/
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (orientation: portrait)
and (-webkit-min-device-pixel-ratio: 1) {
}
/**
* iPad landscape
*/
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (orientation: landscape)
and (-webkit-min-device-pixel-ratio: 1) {
}
4.8.2、设置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>
效果:
4.8.3、小节
首先如果不设置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实现响应式布局
rem是CSS3新引进来的一个度量单位,相对长度单位。相对于根元素(即html元素)font-size计算值的倍数,如:
height:2rem;,则高度的大小为32px(字体默认为16px,chrome最小为12px),如果根元素的字体为15px,则结果为30px。
页面中的尺寸都以html元素的font-size为相对单位,为默认设置为20px,如果需要一个200px的大小则使用10rem,然后当屏幕大小变化时通过javascript或media queries修改字体大小。
5.1、使用javascript设置相对尺寸
示例代码:
<!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>
运行效果:
5.2、使用媒介查询设置字体尺寸
示例代码:
<!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>
运行结果:
六、示例下载
https://git.coding.net/zhangguo5/CSS301.git
github:https://github.com/zhangguo5/CSS3_4.git
https://git.coding.net/zhangguo5/HTML5_143.git
七、作业
7.1、请参考负边距布局内容,实现商品展示,当鼠标悬停在价格与产品名称上时显示详细介绍(请使用float+负边距、定位、flexbox多种方式实现)
当屏幕宽度不足以容下两个或以上的产品时,纵向展示。(选作)
素材:https://coding.net/u/zhangguo5/p/CSS301/git/tree/master/img/product
内容也可以参考如下部分:
7.2、请使用Masonry+imageLoaded插件完成图片的瀑布流布局
7.3、搭建后台开发环境,MySQL+Java1.8+Idea+Servlet+Spring MVC+Rest
7.4、完成一个瀑布流+延迟加载图片的相册或商品列表,要求图片大小不一,示例。显示时除了图片还需要至少一个字符串,如标题,价格等。
a、有后台,通过ajax加载后台的json
b、200条数据以上
c、使用技术参考:masonry+imagesloaded+infinitescroll
d、图片放在后台的目录下
e、后台可以实现管理图片、上传等维护数据的功能(选作)
7.5、请模拟如下的响应式显示效果,要求兼容各种设备:
7.6、模拟:http://cordova.apache.org/头部
PC端效果:
移动端效果:
7.7、请完成一个响应式表格。
要求:在电脑上显示时按网格显示,在手机端显示时按单行显示,风格如下所示:
电脑:
手机:
7.8、使用flexbox实现9个不同位置的定位
左中右x上中下=9
如绝对居中
。。。