常见布局实现:
作者:Sweet_KK
链接:https://juejin.im/post/5aa252ac518825558001d5de
来源:掘金
一、水平居中
文本/行内元素/行内块元素居中
#parent{
text-align: center;
}
text-align 只控制行内内容(文字、行内元素、行内块元素)如何相对于他的块父元素对齐
优缺点
- 优点:简单快捷,容易理解,兼容性非常好
- 缺点:只对行内内容有效;属性会继承影响到后代行内内容;如果子元素宽度大于父元素宽度则无效,只有后代行内内容中宽度小于设置text-align属性的元素宽度的时候,才会水平居中
单个块级元素
#son{
100px; /*必须定宽*/
margin: 0 auto;
}
在margin有节余的同时如果左右margin设置auto,将会根据剩余空间自动计算分配,如果是上下margin设置auto的时候计算值为0
优缺点
- 优点:简单;兼容性好
- 缺点:必须定宽,并且值不能为auto;宽度要小于父元素,否则无效
多个块级元素
#parent{
text-align: center;
}
.son{
display: inline-block; /*改为行内或者行内块级形式,以达到text-align对其生效*/
}
原理:text-align只控制行内内容(文字、行内元素、行内块级元素)如何相对他的块父元素对齐
优缺点
- 优点:简单,容易理解,兼容性非常好
- 缺点:只对行内内容有效;属性会继承影响到后代行内内容;块级改为inline-block换行、空格会产生元素间隔
使用绝对定位实现
#parent{
height: 200px;
200px; /*定宽*/
position: relative; /*父相*/
background-color: #f00;
}
#son{
position: absolute; /*子绝*/
left: 50%; /*父元素宽度一半,这里等同于left:100px*/
transform: translateX(-50%); /*自身宽度一半,等同于margin-left: -50px;*/
100px; /*定宽*/
height: 100px;
background-color: #00ff00;
}
原理:子绝父相,top、right、bottom、left的值是相对于父元素尺寸的,然后margin或者transform是相对于自身尺寸的,组合使用达到水平居中的目的
优缺点
- 优点:使用margin-left兼容性好;不管是块级还是行内元素都可以实现
- 缺点:代码较多;脱离文档流;使用margin-left需要知道宽度值;使用transform兼容性不好(ie9+)
任意个元素(flex)
#parent{
display: flex;
justify-content: center;
}
原理:设置当前主轴对齐方式为居中。
优缺点:
- 优点:功能强大
- 缺点:felx的PC兼容性,Android4.0+
小结:
- 水平居中需要优先考虑哪些元素自带居中效果,最先想到的当然是
text-align:center
了,但是只对行内有效,使用text-align
需要先display:inline-block
或者display-inline
- 然后考虑可不可以用
margin:0 auto
- 然后考虑功能强大flex
二、垂直居中
行内元素/单行文本/行内块元素
#parent{
height: 150px;
line-height: 150px; /*与height等值*/
}
原理: line-height
最终表现是通过inline box 实现的,而无论inline box所占据的高度是多少,其占据的空间都是与文字内容公用水平中垂线的
优缺点:
- 优点: 简单,兼容性好
- 缺点: 只能用于单行行内内容,且高度必须已知
图片
#parent{
height: 150px;
line-height: 150px;
font-size: 0;
}
img#son{vertical-align: middle;} /*默认是基线对齐,改为middle*/
原理: 张鑫旭vertical-align和line-height
缺点
- 优点:简单;兼容性好
- 缺点:需要添加font-size: 0; 才可以完全的垂直居中;不过需要主要,html#parent包裹img之间需要有换行或空格
单个块级元素
<!--html-->
<div id="parent">
<div id="son"></div>
</div>
使用tabel-cell实现:
#parent{
display: table-cell;
vertical-align: middle;
}
原理:CSS Table,使表格内容对齐方式为middle
优缺点
- 优点:简单;宽高不定;兼容性好(ie8+)
- 缺点:设置tabl-cell的元素,宽度和高度的值设置百分比无效,需要给它的父元素设置display: table; 才生效;table-cell不感知margin,在父元素上设置table-row等属性,也会使其不感知height;设置float或position会对默认布局造成破坏,可以考虑为之增加一个父div定义float等属性;内容溢出时会自动撑开父元素
使用绝对定位实现:
#parent{
height: 150px;
position: relative; /*父相*/
}
#son{
position: absolute; /*子绝*/
top: 50%; /*父元素高度一半,这里等同于top:75px;*/
transform: translateY(-50%); /*自身高度一半,这里等同于margin-top:-25px;*/
height: 50px;
}
原理:子绝父相
优缺点:
- 优点:使用margin-top兼容性好;不管是块级还是行内元素都可以实现
- 缺点:代码较多;脱离文档流;使用margin-top需要知道高度值;使用transform兼容性不好(ie9+)
#parent{position: relative;}
#son{
position: absolute;
margin: auto 0;
top: 0;
bottom: 0;
height: 50px;
}
原理:当top、bottom为0时,margin-top&bottom会无限延伸占满空间并且平分
优缺点
- 优点:简单;兼容性较好(ie8+)
- 缺点:脱离文档流
使用flex实现:
#parent{
display: flex;
align-items: center;
}
或
#parent{display: flex;}
#son{align-self: center;}
或
#parent{display: flex;}
#son{margin: auto 0;}
小结:
- 对于垂直居中,最先想到的应该就是 line-height 了,但是这个只能用于行内内容;
- 其次就是考虑能不能用vertical-align: middle
- 然后便是绝对定位,虽然代码多了点,但是胜在适用于不同情况;
- 移动端兼容性允许的情况下能用flex就用flex
三、水平垂直居中
行内/行内块级/图片
#parent{
height: 150px;
line-height: 150px; /*行高的值与height相等*/
text-align: center;
font-size: 0; /*消除幽灵空白节点的bug*/
}
#son{
/*display: inline-block;*/ /*如果是块级元素需改为行内或行内块级才生效*/
vertical-align: middle;
}
原理:text-align: center
; 控制行内内容相对于块父元素水平居中,然后就是line-height和vertical-align的基友关系使其垂直居中,font-size: 0; 是为了消除近似居中的bug
优缺点
- 优点:代码简单;兼容性好(ie8+)
- 缺点:只对行内内容有效;需要添加font-size: 0; 才可以完全的垂直居中;不过需要注意html中#parent包裹#son之间需要有换行或空格;熟悉line-height和vertical-align的基友关系较难
table-cell
#parent{
height: 150px;
200px;
display: table-cell;
vertical-align: middle;
/*text-align: center;*/ /*如果是行内元素就添加这个*/
}
#son{
/*margin: 0 auto;*/ /*如果是块级元素就添加这个*/
100px;
height: 50px;
}
原理:CSS Table,使表格内容垂直对齐方式为middle,然后根据是行内内容还是块级内容采取不同的方式达到水平居中
优缺点
- 优点:简单方便,充分利用默认样式
- 缺点:只适用于行内内容;需要清除部分默认样式;水平垂直居中兼容性很好,但是ie下点击会有凹陷效果!
绝对定位
#parent{
position: relative;
}
#son{
position: absolute;
top: 50%;
left: 50%;
/*定宽高时等同于margin-left:负自身宽度一半;margin-top:负自身高度一半;*/
transform: translate(-50%,-50%);
}
原理:子绝父相,top、right、bottom、left的值是相对于父元素尺寸的,然后margin或者transform是相对于自身尺寸的,组合使用达到几何上的水平垂直居中
缺点
- 优点:使用margin兼容性好;不管是块级还是行内元素都可以实现
- 缺点:代码较多;脱离文档流;使用margin需要知道宽高;使用transform兼容性不好(ie9+)
绝对居中
#parent{
position: relative;
}
#son{
position: absolute;
margin: auto;
100px;
height: 50px;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
原理:当top、bottom为0时,margin-top&bottom设置auto的话会无限延伸占满空间并且平分;当left、right为0时,margin-left&right设置auto的话会无限延伸占满空间并且平分
优缺点
- 优点:无需关注宽高;兼容性较好(ie8+)
- 缺点:代码较多;脱离文档流
flex
#parent{
display: flex;
}
#son{
margin: auto;
}
或
#parent{
display: flex;
justify-content: center;
align-items: center;
}
或
#parent{
display: flex;
justify-content: center;
}
#son{
align-self: center;
}
优缺点
- 优点:简单灵活;功能强大
- 缺点:PC端兼容性不好,移动端(Android4.0+)
视窗居中
#son{
/*0如果去掉,则会多出滚动条并且上下都是50vh的margin。如果去掉就给body加上overflow:hidden;*/
margin: 50vh auto 0;
transform: translateY(-50%);
}
原理:vh为视口单位,视口即文档可视的部分,50vh就是视口高度的50/100,设置50vh上边距再
优缺点
- 优点:简单;容易理解;两句代码达到屏幕水平垂直居中
- 缺点:兼容性不好(ie9+,Android4.4+)
小结
- 一般情况下,水平垂直居中,我们最常用的就是绝对定位加负边距了,缺点就是需要知道宽高,使用transform倒是可以不需要,但是兼容性不好(ie9+);
- 其次就是绝对居中,绝对定位设置top、left、right、bottom为0,然后margin:auto; 让浏览器自动平分边距以达到水平垂直居中的目的;
- 如果是行内/行内块级/图片这些内容,可以优先考虑line-height和vertical-align 结合使用,不要忘了还有text-align ,这个方法代码其实不多,就是理解原理有点困难,想要熟练应对各种情况还需好好研究;
- 移动端兼容性允许的情况下能用flex就用flex。
四、两列布局
左列定宽,右列自适应
1、利用float+margin实现
<body>
<div id="left">左列定宽</div>
<div id="right">右列自适应</div>
</body>
#left {
background-color: #f00;
float: left;
100px;
height: 500px;
}
#right {
background-color: #0f0;
height: 500px;
margin-left: 100px; /*大于等于#left的宽度*/
}
2、利用float+margin(fix)实现
<body>
<div id="left">左列定宽</div>
<div id="right-fix">
<div id="right">右列自适应</div>
</div>
</body>
#left {
background-color: #f00;
float: left;
100px;
height: 500px;
}
#right-fix {
float: right;
100%;
margin-left: -100px; /*正值大于或等于#left的宽度,才能显示在同一行*/
}
#right{
margin-left: 100px; /*大于或等于#left的宽度*/
background-color: #0f0;
height: 500px;
}
3、使用float+overflow实现
<body>
<div id="left">左列定宽</div>
<div id="right">右列自适应</div>
</body>
#left {
background-color: #f00;
float: left;
100px;
height: 500px;
}
#right {
background-color: #0f0;
height: 500px;
overflow: hidden; /*触发bfc达到自适应*/
}
<!--优缺点:-->
<!--优点:代码简单,容易理解,无需关注定宽的宽度,利用bfc达到自适应效果-->
<!--缺点:浮动脱离文档流,需要手动清除浮动,否则会产生高度塌陷;不支持ie6-->
4、使用table实现
<div id="parent">
<div id="left">左列定宽</div>
<div id="right">右列自适应</div>
</div>
#parent{
100%;
display: table;
height: 500px;
}
#left {
100px;
background-color: #f00;
}
#right {
background-color: #0f0;
}
#left,#right{
display: table-cell; /*利用单元格自动分配宽度*/
}
<!--优缺点:-->
<!--优点:代码简单,容易理解,无需关注定宽的宽度,利用单元格自动分配达到自适应效果-->
<!--缺点:margin失效;设置间隔比较麻烦;不支持ie8--->
5、使用绝对定位实现
<body>
<div id="parent">
<div id="left">左列定宽</div>
<div id="right">右列自适应</div>
</div>
</body>
#parent{
position: relative; /*子绝父相*/
}
#left {
position: absolute;
top: 0;
left: 0;
background-color: #f00;
100px;
height: 500px;
}
#right {
position: absolute;
top: 0;
left: 100px; /*值大于等于#left的宽度*/
right: 0;
background-color: #0f0;
height: 500px;
}
6、使用flex实现
<body>
<div id="parent">
<div id="left">左列定宽</div>
<div id="right">右列自适应</div>
</div>
</body>
#parent{
100%;
height: 500px;
display: flex;
}
#left {
100px;
background-color: #f00;
}
#right {
flex: 1; /*均分了父元素剩余空间*/
background-color: #0f0;
}
7、使用Grid实现
<body>
<div id="parent">
<div id="left">左列定宽</div>
<div id="right">右列自适应</div>
</div>
</body>
#parent {
100%;
height: 500px;
display: grid;
grid-template-columns: 100px auto; /*设定2列就ok了,auto换成1fr也行*/
}
#left {
background-color: #f00;
}
#right {
background-color: #0f0;
}
左列自适应,右列定宽
和左侧定宽右侧自适应同理,除了不能用上面的float+margin(fix)实现
一列不定,一列自适应
盒子宽度随着内容增加或减少发生变化,另一个盒子自适应
1、使用float+overflow实现
<body>
<div id="parent">
<div id="left">左列不定宽</div>
<div id="right">右列自适应</div>
</div>
</body>
#left {
margin-right: 10px;
float: left; /*只设置浮动,不设宽度*/
height: 500px;
background-color: #f00;
}
#right {
overflow: hidden; /*触发bfc*/
height: 500px;
background-color: #0f0;
}
优缺点:
- 优点:代码简单,容易理解,无需关注宽度,利用bfc达到自适应效果
- 缺点:浮动脱离文档流,需要手动清除浮动,否则会产生高度塌陷;不支持ie6
2、使用flex实现
<body>
<div id="parent">
<div id="left">左列不定宽</div>
<div id="right">右列自适应</div>
</div>
</body>
#parent{
display: flex;
}
#left { /*不设宽度*/
margin-right: 10px;
height: 500px;
background-color: #f00;
}
#right {
height: 500px;
background-color: #0f0;
flex: 1; /*均分#parent剩余的部分*/
}
3、使用Grid实现
<body>
<div id="parent">
<div id="left">左列不定宽</div>
<div id="right">右列自适应</div>
</div>
</body>
#parent{
display: grid;
grid-template-columns: auto 1fr; /*auto和1fr换一下顺序就是左列自适应,右列不定宽了*/
}
#left {
margin-right: 10px;
height: 500px;
background-color: #f00;
}
#right {
height: 500px;
background-color: #0f0;
}
三列布局
1、 两列定宽,一列自适应
1.1使用float+margin实现
<body>
<div id="parent">
<div id="left">左列定宽</div>
<div id="center">中间定宽</div>
<div id="right">右列自适应</div>
</div>
</body>
#parent{
min- 310px; /*100+10+200,防止宽度不够,子元素换行*/
}
#left {
margin-right: 10px; /*#left和#center间隔*/
float: left;
100px;
height: 500px;
background-color: #f00;
}
#center{
float: left;
200px;
height: 500px;
background-color: #eeff2b;
}
#right {
margin-left: 320px; /*等于#left和#center的宽度之和加上间隔,多出来的就是#right和#center的间隔*/
height: 500px;
background-color: #0f0;
}
1.2使用float+overflow实现
<body>
<div id="parent">
<div id="left">左列定宽</div>
<div id="center">中间定宽</div>
<div id="right">右列自适应</div>
</div>
</body>
#parent{
min- 320px; /*100+10+200+20,防止宽度不够,子元素换行*/
}
#left {
margin-right: 10px; /*间隔*/
float: left;
100px;
height: 500px;
background-color: #f00;
}
#center{
margin-right: 10px; /*在此定义和#right的间隔*/
float: left;
200px;
height: 500px;
background-color: #eeff2b;
}
#right {
overflow: hidden; /*触发bfc*/
height: 500px;
background-color: #0f0;
}
<!--优缺点:-->
<!--优点:代码简单,容易理解,无需关注定宽的宽度,利用bfc达到自适应效果-->
<!--缺点:浮动脱离文档流,需要手动清除浮动,否则会产生高度塌陷;不支持ie6-->
1.3使用table实现
<body>
<div id="parent">
<div id="left">左列定宽</div>
<div id="center">中间定宽</div>
<div id="right">右列自适应</div>
</div>
</body>
#parent {
100%;
height: 520px; /*抵消上下间距10*2的高度影响*/
margin: -10px 0; /*抵消上下边间距10的位置影响*/
display: table;
/*左右两边间距大了一点,子元素改用padding设置盒子间距就没有这个问题*/
border-spacing: 10px; /*关键!!!设置间距*/
}
#left {
display: table-cell;
100px;
background-color: #f00;
}
#center {
display: table-cell;
200px;
background-color: #eeff2b;
}
#right {
display: table-cell;
background-color: #0f0;
}
<!--优缺点:-->
<!--优点:代码简单,容易理解,无需关注定宽的宽度,利用单元格自动分配达到自适应效果-->
<!--缺点:margin失效;设置间隔比较麻烦;不支持ie8--->
1.4使用flex实现
<body>
<div id="parent">
<div id="left">左列定宽</div>
<div id="center">中间定宽</div>
<div id="right">右列自适应</div>
</div>
</body>
#parent {
height: 500px;
display: flex;
}
#left {
margin-right: 10px; /*间距*/
100px;
background-color: #f00;
}
#center {
margin-right: 10px; /*间距*/
200px;
background-color: #eeff2b;
}
#right {
flex: 1; /*均分#parent剩余的部分达到自适应*/
background-color: #0f0;
}
1.5、使用Grid实现
<body>
<div id="parent">
<div id="left">左列定宽</div>
<div id="center">中间定宽</div>
<div id="right">右列自适应</div>
</div>
</body>
#parent {
height: 500px;
display: grid;
grid-template-columns: 100px 200px auto; /*设置3列,固定第一第二列的宽度,第三列auto或者1fr*/
}
#left {
margin-right: 10px; /*间距*/
background-color: #f00;
}
#center {
margin-right: 10px; /*间距*/
background-color: #eeff2b;
}
#right {
background-color: #0f0;
}
2、两侧定宽,中间自适应
效果:
2.1、双飞翼布局方法
<body>
<div id="header"></div>
<!--中间栏需要放在前面-->
<div id="parent">
<div id="center">
<div id="center_inbox">中间自适应</div>
<hr> <!--方便观察原理-->
</div>
<div id="left">左列定宽</div>
<div id="right">右列定宽</div>
</div>
<div id="footer"></div>
</body>
#header {
height: 60px;
background-color: #ccc;
}
#left {
float: left;
100px;
height: 500px;
margin-left: -100%; /*调整#left的位置,值等于自身宽度*/
background-color: #f00;
opacity: 0.5;
}
#center {
height: 500px;
float: left;
100%;
background-color: #eeff2b;
}
#center_inbox{
height: 480px;
border: 1px solid #000;
margin: 0 220px 0 120px; /*关键!!!左右边界等于左右盒子的宽度,多出来的为盒子间隔*/
}
#right {
float: left;
200px;
height: 500px;
margin-left: -200px; /*使right到指定的位置,值等于自身宽度*/
background-color: #0f0;
opacity: 0.5;
}
#footer {
clear: both; /*注意清除浮动!!*/
height: 60px;
background-color: #ccc;
}
2.2、圣杯布局方法
<body>
<div id="header"></div>
<div id="parent">
<!--#center需要放在前面-->
<div id="center">中间自适应
<hr>
</div>
<div id="left">左列定宽</div>
<div id="right">右列定宽</div>
</div>
<div id="footer"></div>
</body>
#header{
height: 60px;
background-color: #ccc;
}
#parent {
box-sizing: border-box;
height: 500px;
padding: 0 215px 0 115px; /*为了使#center摆正,左右padding分别等于左右盒子的宽,可以结合左右盒子相对定位的left调整间距*/
}
#left {
margin-left: -100%; /*使#left上去一行*/
position: relative;
left: -115px; /*相对定位调整#left的位置,正值大于或等于自身宽度*/
float: left;
100px;
height: 500px;
background-color: #f00;
opacity: 0.5;
}
#center {
float: left;
100%; /*由于#parent的padding,达到自适应的目的*/
height: 500px;
box-sizing: border-box;
border: 1px solid #000;
background-color: #eeff2b;
}
#right {
position: relative;
left: 215px; /*相对定位调整#right的位置,大于或等于自身宽度*/
200px;
height: 500px;
margin-left: -200px; /*使#right上去一行*/
float: left;
background-color: #0f0;
opacity: 0.5;
}
#footer{
height: 60px;
background-color: #ccc;
}
2.3使用Grid实现
<body>
<div id="parent">
<div id="header"></div>
<!--#center需要放在前面-->
<div id="center">中间自适应
<hr>
</div>
<div id="left">左列定宽</div>
<div id="right">右列定宽</div>
<div id="footer"></div>
</div>
</body>
#parent {
height: 500px;
display: grid;
grid-template-columns: 100px auto 200px; /*设定3列*/
grid-template-rows: 60px auto 60px; /*设定3行*/
/*设置网格区域分布*/
grid-template-areas:
"header header header"
"leftside main rightside"
"footer footer footer";
}
#header {
grid-area: header; /*指定在哪个网格区域*/
background-color: #ccc;
}
#left {
grid-area: leftside;
background-color: #f00;
opacity: 0.5;
}
#center {
grid-area: main; /*指定在哪个网格区域*/
margin: 0 15px; /*设置间隔*/
border: 1px solid #000;
background-color: #eeff2b;
}
#right {
grid-area: rightside; /*指定在哪个网格区域*/
background-color: #0f0;
opacity: 0.5;
}
#footer {
grid-area: footer; /*指定在哪个网格区域*/
background-color: #ccc;
}
其他的方法实现如下效果:
2.4使用table实现
<body>
<div id="parent">
<div id="left">左列定宽</div>
<div id="center">中间自适应</div>
<div id="right">右列定宽</div>
</div>
</body>
#parent {
100%;
height: 500px;
display: table;
}
#left {
display: table-cell;
100px;
background-color: #f00;
}
#center {
display: table-cell;
background-color: #eeff2b;
}
#right {
display: table-cell;
200px;
background-color: #0f0;
}
<!--优缺点:-->
<!--优点:代码简洁,容易理解;-->
<!--缺点:margin失效,采用border-spacing表格两边的间隔无法消除;不支持ie8--->
2.5使用flex实现
<body>
<div id="parent">
<div id="left">左列定宽</div>
<div id="center">中间自适应</div>
<div id="right">右列定宽</div>
</div>
</body>
#parent {
height: 500px;
display: flex;
}
#left {
100px;
background-color: #f00;
}
#center {
flex: 1; /*均分#parent剩余的部分*/
background-color: #eeff2b;
}
#right {
200px;
background-color: #0f0;
}
2.6使用position实现
<body>
<div id="parent">
<div id="left">左列定宽</div>
<div id="center">中间自适应</div>
<div id="right">右列定宽</div>
</div>
</body>
#parent {
position: relative; /*子绝父相*/
}
#left {
position: absolute;
top: 0;
left: 0;
100px;
height: 500px;
background-color: #f00;
}
#center {
height: 500px;
margin-left: 100px; /*大于等于#left的宽度,或者给#parent添加同样大小的padding-left*/
margin-right: 200px; /*大于等于#right的宽度,或者给#parent添加同样大小的padding-right*/
background-color: #eeff2b;
}
#right {
position: absolute;
top: 0;
right: 0;
200px;
height: 500px;
background-color: #0f0;
}
<!--优缺点:-->
<!--优点:容易理解,兼容性比较好-->
<!--缺点:需手动计算宽度确定边距;脱离文档流;代码繁多-->
多列布局
1、多列等宽
1.1使用float实现
<body>
<div id="parent">
<div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">5 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">6 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
</div>
</body>
#parent {
height: 500px;
}
.column{
float: left; /*添加浮动*/
16.66666666666667%; /*100÷列数,得出百分比*/
height: 500px;
}
.column:nth-child(odd){
background-color: #f00;
}
.column:nth-child(even){
background-color: #0f0;
}
<!--优缺点:-->
<!--优点:代码简单,容易理解;兼容性较好-->
<!--缺点:需要手动清除浮动,否则会产生高度塌陷-->
1.2、使用table实现
<body>
<div id="parent">
<div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">5 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">6 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
</div>
</body>
#parent {
100%;
height: 500px;
display: table;
}
.column{
display: table-cell; /*无需关注列数,单元格自动平分*/
}
.column:nth-child(odd){
background-color: #f00;
}
.column:nth-child(even){
background-color: #0f0;
}
<!--优缺点:-->
<!--优点:代码简单,容易理解;无需关注宽度。单元格自动等分-->
<!--缺点:margin失效;设置间隔比较麻烦;不兼容ie8--->
1.3、使用flex实现
<body>
<div id="parent">
<div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">5 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">6 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
</div>
</body>
#parent {
height: 500px;
display: flex;
}
.column{
flex: 1; /*无需关注列数,一起平分#parent*/
}
.column:nth-child(odd){
background-color: #f00;
}
.column:nth-child(even){
background-color: #0f0;
}
1.4、使用Grid实现
<body>
<div id="parent">
<div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">5 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">6 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
</div>
</body>
#parent {
height: 500px;
display: grid;
grid-template-columns: repeat(6,1fr); /*6就是列数*/
}
.column{}
.column:nth-child(odd){
background-color: #f00;
}
.column:nth-child(even){
background-color: #0f0;
}
2、九宫格布局
(1)使用table实现
<body>
<div id="parent">
<div class="row">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="row">
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
<div class="row">
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</div>
</body>
#parent {
1200px;
height: 500px;
margin: 0 auto;
display: table;
}
.row {
display: table-row;
}
.item {
border: 1px solid #000;
display: table-cell;
}
(2)使用flex实现
<body>
<div id="parent">
<div class="row">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="row">
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
<div class="row">
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</div>
</body>
#parent {
1200px;
height: 500px;
margin: 0 auto;
display: flex;
flex-direction: column;
}
.row {
display: flex;
flex: 1;
}
.item {
flex: 1;
border: 1px solid #000;
}
(3)使用Grid实现
<body>
<div id="parent">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</body>
#parent {
1200px;
height: 500px;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(3, 1fr); /*等同于1fr 1fr 1fr,此为重复的合并写法*/
grid-template-rows: repeat(3, 1fr); /*等同于1fr 1fr 1fr,此为重复的合并写法*/
}
.item {
border: 1px solid #000;
}
栅格系统
优缺点:
优点:代码简洁,容易理解;提高页面内容的流动性,能适应多种设备;
(1)用Less生成
/*生成栅格系统*/
@media screen and (max- 768px){
.generate-columns(12); /*此处设置生成列数*/
.generate-columns(@n, @i: 1) when (@i <= @n) {
.column-xs-@{i} {
(@i * 100% / @n);
}
.generate-columns(@n, (@i+1));
}
}
@media screen and (min- 768px){
.generate-columns(12); /*此处设置生成列数*/
.generate-columns(@n, @i: 1) when (@i <= @n) {
.column-sm-@{i} {
(@i * 100% / @n);
}
.generate-columns(@n, (@i+1));
}
}
div[class^="column-xs-"]{
float: left;
}
div[class^="column-sm-"]{
float: left;
}
编译后的CSS代码:
@media screen and (max- 768px) {
.column-xs-1 { 8.33333333%; }
.column-xs-2 { 16.66666667%; }
.column-xs-3 { 25%; }
.column-xs-4 { 33.33333333%; }
.column-xs-5 { 41.66666667%; }
.column-xs-6 { 50%; }
.column-xs-7 { 58.33333333%; }
.column-xs-8 { 66.66666667%; }
.column-xs-9 { 75%; }
.column-xs-10 { 83.33333333%; }
.column-xs-11 { 91.66666667%; }
.column-xs-12 { 100%; }
}
@media screen and (min- 768px) {
.column-sm-1 { 8.33333333%; }
.column-sm-2 { 16.66666667%; }
.column-sm-3 { 25%; }
.column-sm-4 { 33.33333333%; }
.column-sm-5 { 41.66666667%; }
.column-sm-6 { 50%; }
.column-sm-7 { 58.33333333%; }
.column-sm-8 { 66.66666667%; }
.column-sm-9 { 75%; }
.column-sm-10 { 83.33333333%; }
.column-sm-11 { 91.66666667%; }
.column-sm-12 { 100%; }
}
div[class^="column-xs-"]{
float: left;
}
div[class^="column-sm-"]{
float: left;
}
全屏布局
(1)使用绝对定位实现
<body>
<div id="parent">
<div id="top">top</div>
<div id="left">left</div>
<div id="right">right</div>
<div id="bottom">bottom</div>
</div>
</body>
html, body, #parent {height: 100%;overflow: hidden;}
#parent > div {
border: 1px solid #000;
}
#top {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 100px;
}
#left {
position: absolute;
top: 100px; /*值大于等于#top的高度*/
left: 0;
bottom: 50px; /*值大于等于#bottom的高度*/
200px;
}
#right {
position: absolute;
overflow: auto;
left: 200px; /*值大于等于#left的宽度*/
right: 0;
top: 100px; /*值大于等于#top的高度*/
bottom: 50px; /*值大于等于#bottom的高度*/
}
#bottom {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 50px;
}
优缺点:
- 优点:容易理解
- 缺点:代码繁多;需要计算好各个盒子的宽高;
(2)使用flex实现
<body>
<div id="parent">
<div id="top">top</div>
<div id="middle">
<div id="left">left</div>
<div id="right">right</div>
</div>
<div id="bottom">bottom</div>
</div>
</body>
*{
margin: 0;
padding: 0;
}
html,body,#parent{
height:100%;
}
#parent {
display: flex;
flex-direction: column;
}
#top {
height: 100px;
}
#bottom {
height: 50px;
}
#middle {
flex: 1;
display: flex;
}
#left {
200px;
}
#right {
flex: 1;
overflow: auto;
}
(3)使用Grid实现
<body>
<div id="parent">
<div id="top">top</div>
<div id="left">left</div>
<div id="right">right</div>
<div id="bottom">bottom</div>
</div>
</body>
*{
margin: 0;
padding: 0;
}
html, body, #parent {
height: 100%;
}
#parent {
100%;
height: 100%;
display: grid;
/*分成2列,第一列宽度200px,第二列1fr平分剩余的部分,此处换成auto也行*/
grid-template-columns: 200px 1fr;
/*分成3行,第一行高度100px,第二行auto为自适应,此处换成1fr也行,第3行高度为50px*/
grid-template-rows: 100px auto 50px;
/*定义网格区域分布*/
grid-template-areas:
"header header"
"aside main"
"footer footer";
}
#parent>div{
border: 1px solid #000;
}
#top{
grid-area: header; /*指定在哪个网格区域*/
}
#left{
grid-area: aside; /*指定在哪个网格区域*/
}
#right{
grid-area: main; /*指定在哪个网格区域*/
}
#bottom{
grid-area: footer; /*指定在哪个网格区域*/
}
媒体查询
[I]. 定义和规范
1.1 CSS2中的媒体查询
在CSS2中,媒体查询只使用于<style>
和 <link>
标签中,以media属性存在;media属性用于为不同的媒介类型规定不同的样式,而真正广泛使用的媒介类型是'screen'、'print'和'all'
all 适合所有设备
screen 计算机屏幕(默认值)
print 打印预览模式 / 打印页
tty 电传打字机以及使用等宽字符网格的类似媒介
tv 电视类型设备(低分辨率、有限的屏幕翻滚能力)
projection 放映机
handheld 手持设备(小屏幕、有限的带宽)
braille 盲人用点字法反馈设备
aural 语音合成器
<style media="screen,tv">
.box{
height: 100px;
100px;
background-color: lightblue;
}
</style>
<div class="box"></div>
1.2 CSS3中的媒体查询
在Media Queries Level 3规范中,媒体查询的能力被扩展,除了设备的类型,我们可以还获取到诸如窗口宽度、屏幕方向或分辨率等媒体特性(media features):
width – 输出设备渲染区域(如可视区域的宽度或打印机纸盒的宽度)的宽度
height – 输出设备渲染区域(如可视区域的高度或打印机纸盒的高度)的高度
device-width – 输出设备的宽度(整个屏幕或页的高度,而不是仅是渲染区域)
device-height – 输出设备的高度(整个屏幕或页的高度,而不是仅是渲染区域)
orientation – 设备处于横屏(宽度大于高度)模式还是竖屏(高度大于宽度)模式
aspect-ratio – 输出设备目标显示区域的宽高比
device-aspect-ratio – 输出设备的宽高比
resolution – 输出设备的分辨率(像素密度)
color – 检查设备支持多少种颜色等
color-index – 输出设备中颜色查询表中的条目数量
monochrome – 指定了一个黑白(灰度)设备每个像素的比特数
scan – 检查电视输出设备是顺序扫描还是隔行扫描
grid – 判断输出设备是网格设备还是位图设备
1.3Media Queries Level 4规范中新的媒体特性
几个有代表性的如:
update – 根据设备的更新频度区分其类型 (none 如打印机, slow 如电子墨水, fast 正常设备)
scripting – none 不支持脚本或未启用 | initial-only 仅支持页面初始化脚本 | enabled 支持脚本并且已启用
pointer – 设备交互的精度 (coarse不精确如手指, fine 精确如鼠标, none 无指点)
hover – 设备是否支持悬停状态
[II]. 使用形式
2.1 基本语法
媒体查询最基本的形式,就是单独或组合使用媒体类型和媒体特性(后者要置于括号中),如:
@media screen {
body {
font-size: 20px;
}
}
@media screen, print {
body {
font-size: 20px;
}
}
@media ( 30em) {
nav li {
display: block;
}
}
@media screen and ( 30em) {
nav li {
display: block;
}
}
2.2 嵌套
/*例子1:媒体类型套媒体特性*/
@media screen {
@media (min- 20em) {
img {
display: block;
100%;
height: auto;
}
}
@media (min- 40em) {
img {
display: inline-block;
max- 300px;
}
}
}
/*例子2:媒体特性多层嵌套*/
@media (hover: on-demand) {
@media (pointer: coarse) {
input[type=checkbox] ~ label {
padding: .5em;
}
}
@media (pointer: fine) {
input[type=checkbox] ~ label {
padding: .1em;
}
}
}
2.3 否定式查询
可以用关键字not表示一个否定查询; not必须置于查询的一开头并会对整条查询串生效,除非逗号分割的多条
@media not print {
body {
background: url('paisley.png');
}
}
/*否定`print and (min-resolution: 1.5dppx)`这一整个条件*/
@media not print and (min-resolution: 1.5dppx) {
.external {
background: url('arrow-lowres.png');
}
}
/* not A 或 not B */
@media not (hover: hover), not (pointer: coarse) {
font-size: 20px;
}
/*非法:not不在最前面*/
@media not print and not (min-resolution: 2dppx) {
}
/*非法:not不在最前面*/
@media screen and not (min-resolution: 2dppx) {
}
[III]. 媒体特性
3.1 根据媒体特性的范围查询
指定一个固定的宽度通常是没有意义的,更多的情况下,我们需要限定的是类似“小于等于”或“大于等于”这样的范围,而大多数媒体特性可以通过添加“max-”和“min-”前缀达到上述目的
/*0 至 30em*/
@media (max- 30em) {
nav li {
display: block;
}
}
/*30em 至 100em*/
@media (min- 30em) and (max- 100em) {
nav li {
display: block;
}
}
支持范围选择的特性 | 取值类型 |
---|---|
aspect-ratio | 诸如 1024/768 或 16:9 |
device-aspect-ratio | 诸如 1024/768 或 16:9 |
color | 整数 |
color-index | 整数 |
width | 合法宽度 |
height | 合法高度 |
device-width | 合法宽度 |
device-height | 合法高度 |
monochrome | 整数 |
resolution | 分辨率单位(dpi, dpcm, dppx) |
3.2 选项式的媒体特性查询
不同于取值连续的范围式查询,很多媒体特性只有几个固定的取值可供选择
@media screen and (orientation: portrait) {
#logo {
height: 10vh;
auto;
}
}
选项式的媒体特性 | 取值选项 | 备注 |
---|---|---|
grid | 布尔值(使用时直接写成 (grid) 来判断) | 是网格设备还是位图设备 |
hover | none, on-demand, hover | 是否支持悬停状态 |
orientation | portrait, landscape | 设备方向 |
light-level | dim, normal, washed | 环境光 |
pointer | none, coarse, fine | 设备交互的精度 |
scripting | none, initial-only, enabled | 是否支持脚本 |
update | none, slow, normal | 根据设备的更新频度区分其类型 |
scan | interlace, progressive | 电视输出设备是顺序扫描还是隔行扫描 |
any-hover | none, on-demand, hover | can be used to check whether any available input mechanism allows the user to hover over elements |
any-pointer | none, coarse, fine | Presence and accuracy of any pointing device available to the user |
inverted-colors | none, inverted | useragent或OS是否倒置了颜色 |
overflow-block | none, scroll, optional-paged, paged | 在block轴方向,当内容超出初始包含块或视口时,设备或浏览器的行为 |
overflow-inline | none, scroll | 在inline轴方向,当内容超出初始包含块或视口时,设备或浏览器的行为 |
@media screen and (hover: on-demand) {
input[type=checkbox] + label {
padding: .5em;
}
}
@media screen and (hover: none) and (pointer: coarse) {
input[type=checkbox] + label {
padding: .5em;
}
}
[IV]. 其他
4.1 针对高分屏的媒体查询
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
/* Retina屏幕下的样式 */
}
4.2 引入外部文件时的媒体查询
@import url(typography.css) screen, print;
@import url(hi-res-icons.css) (min-resolution: 1.5dppx), (min-resolution: 96dpi);
<!--即使媒体查询不符,样式文件总会被下载-->
<link rel="stylesheet" href="styles.css"
type="text/css" media="screen and (max- 480px)">
4.3 在style标签上的媒体查询
<style type="text/css" media="screen and (max- 480px)">
body {
font-size: 20px;
}
</style>
4.4 利用媒体查询实现图片自适应
<picture>
<source srcset="large.jpg" media="(min- 1024px)">
<source srcset="medium.jpg" media="(min- 680px)">
<!-- fallback -->
<img src="small.jpg" alt="">
</picture>
看上去很简单,但在实际应用中,考虑到各种情况,可能会是这样:
<picture>
<source src="large.jpg"
media="( (min-device-pixel-ratio: 1.5) and (min- 20.001em) and (max- 35.999em) ) or
( (max-device-pixel-ratio: 1.5) and (min- 120.001em) ) or
( (min-device-pixel-ratio: 1.5) and (min- 60.001em) )" />
<source src="medium.jpg"
media="( (max-device-pixel-ratio: 1.5) and (min- 20.001em) and (max- 35.999em) ) or
( (max-device-pixel-ratio: 1.5) and (min- 60.001em) ) or
( (min-device-pixel-ratio: 1.5) and (min- 10.001em) )" />
<source src="small.jpg" />
<!-- fallback -->
<img src="small.jpg" alt="" />
</picture>
4.5 扩展阅读:用srcset和sizes实现更好的图片自适应
- 对于固定宽度(不同设备的设计稿上尺寸相同)的图像:
-
srcset属性列出了浏览器可以选择加载的源图像池,是一个由逗号分隔的列表。
-
x描述符表示图像的设备像素比
-
浏览器根据运行环境,利用这些信息来选择适当的图像
-
不理解srcset的浏览器会直接加载src属性中声明的图像
-
<img src="pic-255.jpg" alt="pic"
srcset="pic-383.jpg 1.5x, pic-510.jpg 2x" />
- 可变宽度(根据设备有不同显示策略)的图像:基于viewport选择
-
w描述符告诉浏览器列表中的每个图象的宽度
-
如果srcset中任何图像使用了w描述符,那么必须要设置sizes属性
-
sizes属性有两个值:第一个是媒体条件;第二个是源图尺寸值
-
源图尺寸值不能使用百分比
-
浏览器利用srcset和sizes信息来自动选择最符合规定条件的图像
-
无法确定究竟显示哪张图像,因为每个浏览器挑选适当图像的算法有差异
-
4.6 扩展阅读:用 image-set() 设置响应式的背景图片
body {
/*
为普通屏幕使用 pic-1.jpg,
为高分屏使用 pic-2.jpg,
如果更高的分辨率则使用 pic-3.jpg,比如印刷
*/
background-image:
image-set(
url(../images/pic-1.jpg) 1x,
url(../images/pic-2.jpg) 2x,
url(../images/pic-3.jpg) 600dpi
);
}
4.7 在Javascript中使用媒体查询
-
全局方法 matchMedia(),其唯一参数为一个合法的媒体查询字符串
var isWideScreen = matchMedia("(min- 960px)");
console.log(isWideScreen.matches); //是否匹配 true | false
console.log(isWideScreen.media); //"(min- 960px)"
以下情况下 matches 属性会返回 false:
- [ ] 媒体查询条件不匹配
- [ ] 媒体查询字符串语法错误
- [ ] 浏览器不支持该查询特性
-
监听媒体的更改
function toggleClass(mq) {
if (mq.matches) {
document.body.classList.add('widescreen');
} else {
document.body.classList.remove('widescreen');
}
}
//添加监听
isWideScreen.addListener( toggleClass );
//撤销监听
isWideScreen.removeListener( toggleClass );
深度思考
一、响应式的优点和缺点??
响应式的优点
- 响应式设计可以向用户提供友好的Web界面,同样的布局,却可以在不同的设备上有不同排版,这就是响应式最大的优点,现在技术发展日新月异,每天都会有新款智能手机推出。如果你拥有响应式Web设计,用户可以与网站一直保持联系,而这也是基本的也是响应式实现的初衷。
- 响应式在开发维护和运营上,相对多个版本成本会降低很多。也无须花大量的时间在网站的维护上
- 方便改动,响应式设计是针对页面的,可以只对必要的页面进行改动,其他页面不受影响。
响应式的缺点
- 为了适配不同的设备,响应式设计需要大量专门为不同设备打造的css及js代码,这导致了文件增大,影响了页面加载速度。
- 在响应式设计中,图片、视频等资源一般是统一加载的,这就导致在低分辨率的机子上,实际加载了大于它的显示要求的图片或视频,导致不必要的流量浪费,影响加载速度;
- 局限性,响应式不适合一些大型的门户网或者电商网站,一般门户网或电商网站一个界面内容较多,对设计样式不好控制,代码过多会影响运行速度。
二、几种常见的浏览器内核
内核,就是常驻内存、能够快速响应的那一部分核心代码,非内核代码都是要用到时再调入内存并执行的。webkit内核更小巧快速,但兼容性不如IE内核。所以有些浏览器是用的双内核,可以在高速模式和兼容模式间切换
一、Trident内核代表产品Internet Explorer,又称其为IE内核。
Trident(又称为MSHTML),是微软开发的一种排版引擎。使用Trident渲染引擎的浏览器包括:IE、傲游、世界之窗浏览器、Avant、腾讯TT、Netscape 8、NetCaptor、Sleipnir、GOSURF、GreenBrowser和KKman等。
二、Gecko内核代表作品Mozilla
FirefoxGecko是一套开放源代码的、以C++编写的网页排版引擎。Gecko是最流行的排版引擎之一,仅次于Trident。使用它的最著名浏览器有Firefox、Netscape6至9。
三、WebKit内核代表作品Safari、Chromewebkit
是一个开源项目,包含了来自KDE项目和苹果公司的一些组件,主要用于Mac OS系统,它的特点在于源码结构清晰、渲染速度极快。缺点是对网页代码的兼容性不高,导致一些编写不标准的网页无法正常显示。主要代表作品有Safari和Google的浏览器Chrome。
四、Presto内核代表作品OperaPresto
是由Opera Software开发的浏览器排版引擎,供Opera 7.0及以上使用。它取代了旧版Opera 4至6版本使用的Elektra排版引擎,包括加入动态功能,例如网页或其部分可随着DOM及Script语法的事件而重新排版。
div+css布局较table布局有哪些优点?
使用table布局的特点
优点:
1、对于新手而言,容易上手,尤其对于一些布局中规中矩的网页,更让人首先想到excel,进而通过使用table去实现它。
2、表现上更加“严谨”,在不同浏览器中都能得到很好的兼容
3、通过复杂的表格套表格的形式,也可以实现比较复杂的布局需求。布置好表格,然后将内容放进去就可以了。
4、它可以不用顾及垂直居中的问题。
5、数据化的存放更合理。
缺点:
1、标签结构多,复杂,在表格布局中,主要是用到表格的相互嵌套使用,这样就会造成代码的复杂度更高!
2、表格布局,不利于搜索引擎抓取信息,直接影响到网站的排名
使用div+css布局的特点
优点
1、符合W3C标准的,W3C标准提出网页由三部分组成:结构(Structure)、表现(Presentation)和行为(Behavior)。结构清晰明了,结构、样式和行为分离,带来足够好的可维护性。
2、布局更加灵活多样,能够通过样式选择来实现界面设计方面的更多要求。
3、布局改版方便,不需要过多地变动页面内容,通常只要更换相应的css样式就可以将网页变成另外一种风格展现出来。
4、布局可以让一些重要的链接和文字信息等优先让搜索引擎抓取,内容更便于搜索。
5、增加网页打开速度,增强用户体验。
缺点
1、开发技术高,要考虑兼容版本浏览器。目前来看,DIV+CSS还没有实现所有浏览器的统一兼容。
2、CSS网站制作的设计元素通常放在1个外部文件中,或几个文件,
有可能相当复杂,甚至比较庞大,如果CSS文件调用出现异常,那么整个网站将变得惨不忍睹。
三、用CSS写一个简单的幻灯片效果页面
CSS3属性中有关于制作动画的三个属性:Transform,Transition,Animation。
transform属性向元素应用2D或3D转换。该属性允许我们对元素进行旋转、缩放、移动或倾斜。
transition是令一个或多个可以用数值表示的css属性值发生变化时产生过渡效果。
Animation字面上的意思,就是“动画”的意思,
@keyframes规则。
Keyframes具有其自己的语法规则,他的命名是由"@keyframes"开头,后面紧接着是这个“动画的名称”加上一对花括号“{}”,括号中就是一些不同时间段样式规则,有点像我们css的样式写法一样。
对于一个"@keyframes"中的样式规则是由多个百分比构成的,如“0%”到"100%"之间,我们可以在这个规则中创建多个百分比,我们分别给每一个百分比中给需要有动画效果的元素加上不同的属性,从而让元素达到一种在不断变化的效果,比如说移动,改变元素颜色,位置,大小,形状等,
不过有一点需要注意的是,我们可以使用“fromt”“to”来代表一个动画是从哪开始,到哪结束,也就是说这个"from"就相当于"0%"而"to"相当于"100%",值得一说的是,其中"0%"不能像别的属性取值一样把百分比符号省略。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>纯css幻灯片</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
margin: auto;
padding: 0;
}
div {
margin-top: 100px;
100px;
border: solid 1px #ccc;
overflow: hidden;
}
ul {
float: left;
display: flex;
}
ul li {
100px;
height: 100px;
text-align: center;
line-height: 100px;
list-style: none;
animation: slide 5s ease 0s infinite normal both;
}
/*停顿(开始)>左移>停顿>左移>归零(结束) 此为三张图片 多一张图片加一个停顿+左移*/
@keyframes slide {
0% {
transform: translateX(0%);
}
16.7% {
transform: translateX(0%);
}
33.3% {
transform: translateX(-100%);
}
50% {
transform: translateX(-100%);
}
66.7% {
transform: translateX(-200%);
}
83.3% {
transform: translateX(-200%);
}
100% {
transform: translateX(0%);
}
}
</style>
</head>
<body>
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
</body>
</html>
Bootstrap响应式布局原理
Bootstrap响应式布局是利用其栅格系统,对于不同的屏幕采用不同的类属性。Bootstrap提供了一套响应式、移动设备优先的流式栅格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为做多12列。
Bootstrap采取12列的栅格体系,根据主流设备的尺寸进行分段,每段宽度固定,通过百分比和媒体查询实现响应式布局。
栅格系统用于通过一系列的行(row)与列(column)的组合来创建页面布局。
栅格系统的工作原理:
- 行(row)必须包含在.container(固定宽度)或.container-fluid(100%宽度)中,以便为其赋予合适的排列(aligment
)和内补(padding)。 - 通过行(row)在水平方向创建一组列(column)。
- 自己内容应当放置于列(column)内,并且,只有列可以作为行(row)的直接子元素。
- 类似.row和.col-xs-4这种预定义的类,可以用来快速创建栅格布局。Bootstrap源码中定义的mixin也可以用来创建语义化布局。
- 通过为列设置padding属性,从而创建列与列之间的间隔(gutter)。通过为.row元素设置负值margin从而抵消为.container元素设置的padding,也就间接为行(row)所包含的列(column)抵消掉了padding。
- 栅格系统的列是通过指定1到12的值来表示其跨越范围。例如三个等宽的列可以使用三个.col-xs-4来创建。
- 如果一行(row)中包含了的列(column)大于12,多余的列所在的元素将作为一个整体另起一行排列。
- 栅格类适用于与屏幕宽度大于或等于分界点大小的设备,并且针对小屏幕覆盖栅格类。
为什么对于大屏设备,container的宽度要设计为1170px。既然是12列栅格,设计成1200px不是显得更规整、也更容易向产品和UI解释吗?
bootstrap为了避免内容占满屏幕,确保在1200px宽的设备两边留出一定的边距,因此将container的最大宽度设为1170px,并使用margin-left:auto和margin-right:auto将container居中,从而确保两边各留出15px的边距。所有列宽均设置为百分比,根本不考虑具体数值。
Bootstrap的栅格系统是一个三层结构,除了外围的container和内部的column,中间还有一个夹层row,并且Bootstrap要求所有的column必须包含在row里面,这是为什么呢?
Bootstrap将所有元素的盒模型设置为了border-box
因此container宽度为1170px,减去左右共30px的padding,于是container的内容宽度就只剩1140px,这下所有col栅格的百分比乘的都是1140而不是1170,为解决此问题,Bootstrap在container中新增了一个夹层row,通过使用负的margin增加row的宽度至1170px。这里用到了盒模型尺寸的计算原理:块元素左右外边距、左右border、左右内边距和width这七个值之和必须等于包含块的content width。row的包含块container的content width为1140px,因此对于row而言,就存在如下等量关系:
-15px+0+0+width+0+0+(-15px)= 1140
于是row的width就自动扩展到1170px了。
既然container左右两边都有15px的外边距了,为什么还要设计15px的内边距?如果没有这个内边距,不就不需要额外添一个夹层row了吗?
因为栅格之间需要间隔,因此每个column栅格都设置了15px的padding:
这意味着每个column实际上也可以看成一个container!我们可以在任意一个column内再嵌套一个栅格系统,而无需再添加container,只需添加一个row即可,不要将row理解成“行”,它就是一个包含块而已。这样的三层结构使得Bootstrap成为了一个可以无限嵌套的响应式系统,每一个栅格都可以看做一个独立的系统,container只不过是那个最大的栅格而已。
另外,Bootstrap栅格系统预设的数值,如列数、槽宽以及媒体查询阈值都是可以修改的。
列排序与列偏移
Bootstrap将所有列的position都设成了relative,就在于可对列进行定位或排序,比如要将某一个列定位到12分之3处(即从第三、四列交界处开始),可以设置left:25%或者right:75%。Bootstrap已经预设好了相应的类名:
col-xs-pull-3 === right: 25%
col-sx-push-3 === left: 25%