css布局
一、知识补充
1. 浮动的特性
- 只会影响后面的元素
- 文本不会被浮动元素覆盖(浮动的特性就是图文混合)
- 具备内联盒子特性:宽度由内容决定
- 具备块级盒子特性:支持所有样式
- 浮动放不下,会自动折行
template:
<div class="class"><div></div><div></div><div>图文混合</div></div>
css样式
.class div:nth-of-type(1){width: 50px;height: 50px;background-color: green;
}
.class div:nth-of-type(2){float: left;width: 100px;height: 100px;background-color: blue;
}
.class div:nth-of-type(3){width: 200px;height: 200px;background-color: red;
}
2. 相对定位及特性 (position: relative)
- 相对定位的元素是在文档中的正常位置偏移给定的值
- 不影响其他元素布局
- 相对于自身进行偏移
3. 绝对定位及特性 (positon: absolute)
- 绝对定位的元素脱离了文档流,绝对定位元素不占据空间
- 具备内联盒子特性:宽高由内容决定(float)
- 具备块级盒子特性:支持所有样式(float)
- 绝对定位元素相对于最近非static祖先元素定位。当这样的祖先元素不存在时,则相对于可视区定位
4.固定定位及特性 (positon: fixed)
- 固定定位与绝对定位相似,但是会固定在可视区中
- 具备内联盒子特性:宽高由内容决定(absolute, float)
- 具备块级盒子特性:支持所有样式 (absolute, float)
- 固定定位元素不受祖先元素影响
5. 黏性定位及特性 (position: sticky)
涨知识:
- 黏性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,之后为固定定位。
position: sticky;
top: 0
6. 页面消失方法
1. display:none
元素不存在,不会占据页面位置;会对页面进行重绘,重排,重新绘制元素信息及重新安排页面元素位置
2. visibility:hidden
3. opacity: 0
display:none | visibility: hidden | opacity: 0 | |
---|---|---|---|
页面中 | 不存在 | 存在 | 存在 |
重绘 | 会 | 会 | 不一定 |
重排 | 会 | 不会 | 不会 |
自身绑定事件 | 不触发 | 不触发 | 可触发 |
transition | 不支持 | 支持 | 支持 |
子元素复原 | 不能 | 能 | 不能 |
被遮挡元素触发事件 | 不影响 | 不影响 | 影响 |
二、弹性布局 flex
1. 主轴和交叉轴
2. flex容器与flex子项
flex容器:
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
flex子项
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- align-self
flex-direction 改变主轴的方向
- row 主轴方向五为横向 (默认横向)
- column 主轴方向为竖向
- row-reverse 主轴方向横向 从后面开始排列
- column-reverse 主轴方向竖向 从最下面开始排列
3. 换行与缩写
flex-wrap: 换行属性
- nowrap (默认) 不进行换行
- wrap 换行
- wrap-reverse 反向折行
Tips:
- 不设置换行的话,当子项的总宽大于父容器的宽度,子项会平均的分父容器的宽。
- 当子项不设置宽度时,子项会根据内容获取宽度
- 当子项不设置高度时,子项会获取父容器的高度
- 当换行时,将父容器按所分的列数平分高度,子项会在平分的首行
4. 主轴对齐详解
justify-content 改变主轴的对齐方式
- flex-start (默认) 对齐方式:靠右
- flex-end 对齐方式:靠右
- center 居中
- space-around 平均分配所有空间,中间的空隙是两侧空隙的两倍
- space-between 第一个子项和最后一个子项会贴到父容器的两侧,其余的平均分配空隙
- space-evenly 子项之间的空隙都是等价的,不管最右边和最左边的空隙还是中间的空隙都是等价的
5.交叉轴对齐详解
align-content 交叉轴的整体的对齐方式
- stretch (默认) 拉伸
- flex-start
- flex-end
- center
- space-around
- space-between
- space-evently
Tips:
- align-content 在不设置折行的情况下是不生效的 (flex-wrap)
align-items 针对每一行的对齐方式
- stretch (默认)
- flex-start 在它自身的那一行的容器当中是顶对齐的
- flex-end
- center
- baselind
6. 元素上下左右居中
内联的上下居中方式
template:
<div class="box">测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字
</div>
1. 弹性布局
.box {width: 300px;height: 200px;background: skyblue;display: flex;align-items: center
}
或者
.box {width: 300px;height: 200px;background: skyblue;display: flex;flex-wrap: wrap;align-content: center
}
2. 设置行高的方式
涨知识:
行高的方式上下居中只能适用于单行,多行文字的话不行
.box {width: 300px;height: 200px;background: skyblue;line-height: 200px;
}
3. display: table-cell
.box {width: 300px;height: 200px;background: skyblue;display: table-cell;vertical-align: middle;
}
块级元素的上下左右居中方式
template
<div class="box"><div></div>
</div>
1. 弹性布局
.box {width: 300px;height: 200px;background: skyblue;display: flex;justify-content: center;align-items: center;
}
.box div {width: 100px;height: 100px;background: pink;
}
2. 绝对定位
.box { width: 300px; height: 200px; background: skyblue; position: relative;}.box div { width: 100px; height: 100px; background: pink; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);}
3. margin: auto
.box {width: 300px;height: 200px;background: skyblue;position: relative;display: flex;
}
.box div {width: 100px;height: 100px;background: pink;margin: auto;
}
或
.box {width: 300px;height: 200px;background: skyblue;position: relative;
}
.box div {width: 100px;height: 100px;background: pink; position: absolute;left: 0;top: 0;right: 0;bottom: 0;margin: auto;
}
涨知识:
弹性可以解决margin遗留下来的全部问题,像margin的叠加,传递,auto上下布局中等问题。
不定项居中布局
不定项:不确定元素的个数
7. flex-grow 扩展比例
flex子项的flex-grow : 默认值为 0 ,表示不占用剩余的空白间隙扩展自己的宽度
template :
<div class="main"><div></div>
</div>
css:
.main {width: 500px;height: 300px;background: skyblue;display: flex;
}
.main div {width: 100px;height: 100px;background: pink;flex-grow: 1;
}
flex-grow: 0; 默认值
如果比例值为1,就占满剩余所有空间
如果 0.5 的话 ,按照上面的布局 (500-100) * 0.5 + 100
如果比例值大于等于1时, 都会占满剩余所有空间
如果N个子项(N>1)都有扩展比例时,会把剩余空间以扩展比例等比分配;
8. flex-shrink 收缩比例
与扩展比例 flex-grow 相反;
默认值为1, 自动收缩,跟容器大小相同
9. flex-basis及flex缩写
flex-basis 设置主轴方向的宽度(高度)
主轴方向为从左到右时 ,flex-basis指的就是宽度
主轴方向从上到下时 , flex-basis指的就是高度
template:
<div class="main"><div></div>
</div>
.main {width: 500px;height: 300px;background: skyblue;display: flex;
}
.main div {width: 100px;height: 100px;background: pink;flex-basis: 200px;
}
/* 宽度为200px */
或者
.main {width: 500px;height: 300px;background: skyblue;display: flex;flex-direction: column;
}
.main div {width: 100px;height: 100px;background: pink;flex-basis: 200px;
}
/* 高度为200px */
flex-basis的默认值为auto,会自适应内容定义宽高
如果设置成 0 的话,将会没有宽高,会将内容单行或单列布局
flex
flex 是 flex-grow , flex-shrink及flex-basis的缩写
10. order 及 align-self
涨知识
order : 默认值0,改变某一个flex子项的排序位置
template:
<div class="main"><div>1</div><div>2</div><div>3</div><div>4</div>
</div>
css
.main {width: 500px;height: 300px;background: skyblue;display: flex;
}
.main div {width: 100px;height: 100px;background: pink;
}
.main div:nth-of-type(1) {order: 1;
}
.main div:nth-of-type(4) {order: -1;
}
上面的样式中,第一个div会跳到最后,第四个div会显示在第一
align-self
默认值为auto , 控制单独某一个flex子项的垂直对齐方式
涨知识:
auto 是跟父容器的align-items一样的值
11. 等高布局
弹性默认是拉伸的,所以默认就有等高布局的特性
template:
<div class="main"><div><p>测试内容</p><p>测试内容</p></div><div><p>测试内容</p><p>测试内容</p><p>测试内容</p><p>测试内容</p><p>测试内容</p><p>测试内容</p></div>
</div>
css
.main {width: 500px;background: skyblue;display: flex;justify-content: space-between;
}
.main div{width: 100px;background: pink;
}
三、网格布局grid
grid容器
grid子项
定义网格及fr单位
- grid-template-rows / grid-template-columns 基于网格行和列的维度,定义网格线的名称和网格轨道的尺寸大小
display:grid;
grid-template-columns: 50px 50px 50px;
grid-template-rows: 50px 50px 50px;
上面的是3x3的网格,每格的宽高都为50px , 宽高可以是百分比,px,fr单位。
fr 单位:均分父容器的宽高
- fr 都为 1 的话 均分父容器的宽高
- 其中一个fr 比别的fr 等比大的话 该网格会占据等比大的宽高
- fr 之和小于1 的话 网格百分比占据容器 , 会剩余宽高。
合并网格及网格命名
- grid-template-areas 使用命名方式定义网格区域,需配合子项的
grid-area 斜体样式属性进行使用
父容器
width:300px;
height:300px
display:grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas:
"a1 a1 a2"
"a1 a1 a2"
"a3 a3 a3";
子项
div:nth-of-type(1){grid-area: a1;
}
...
tips: 少命名网格的话,未命名的网格会自动填充到未定义的空隙中,自动填充特性
- grid-template grid-template-rows grid-template-columns grid-template-areas的缩写
grid-template:
"a1 a1 a2" 1fr
"a1 a1 a2" 1fr
"a3 a3 a3" 1fr
/1fr 1fr 1fr;
网格间隙及简写
- grid-row-gap
- grid-column-gap
- grid- gap
为了弹性设置,对应的别的样式的间隙问题,grid去掉的,
- row-gap
- column-gap
- gap
flex布局中也可以使用
网格对齐方式及简写
- justify-items
- align-items
- place-items
- start 开始位置
- center 中间位置
- end 结束位置
默认值 stretch 拉伸的,指定子项在网格中的对齐方式;子项在自己所属的单元格中的对齐方式
当子项的大小 小于 单元格的大小是才会生效。
- justify-content
- align-content
- place-content
- start 开始位置
- center 中间位置
- end 结束位置
- space-between 平分(两边没有空隙)
- space-around 平分(两边有空隙)
- space-evenly 完全均分
默认值 stretch 拉伸的,指定所有单元格(网格)在父容器中的对齐方式;
当父容器大于网格时 才会生效,就是给网格的单元格指定大小后总大小小于父容器的大小
基于线的元素位置
- grid-column-start
- grid-column-end
- grid-row-start
- grid-row-end
表示grid子项所占据的区域的起始位置和终止位置,包括水平和垂直方向
span 表示占据网格数据
在定义网格行列的时候是可以定义线的命名的
grid-template-columns:[col1] 1fr [col2] 1fr [col3] 1fr [col4];
grid-template-rows:[row1] 1fr [row2] 1fr [row3] 1fr [row4];
grid-area: 其实是 grid-row-start grid-column-start grid-row-end grid-column-end属性的缩写,额外支持grid-template-areas设置的网格名称
也可以这样写,也支持span
grid-column: 1/2;
grid-row: 2/3;
repeat() 和 minmax()
当定义行列时大小都一样时,可以用repeat进行简写
grid-template-columns: 100px 100px 100px;
//可以写成
grid-template-columns: repeat(3, 100px);
grid-template-columns: repeat(auto-fill, 100px);
auto-fill 自适应的现象;自动根据父容器的大小决定拆分多少的单元格,比如 grid-template-columns: repeat(autofill, 100px); 不管容器大小多大都是固定的4个网格,当一行放不下时会折到下一行,用autofill的话在一行可承载的情况下会覆盖整个一行。
minmax 定义网格的最大值和最小值
grid-template-columns: 100px 1fr 100px;
grid-template-rows: 100px;
//上面的第二个网格是自适应的宽度,根据拉伸网页变动,当网页的宽度小于等于200px就会消失,这是就可以使用minmiax解决grid-template-columns: 100px minmax(100px,1fr) 100px;
grid-template-rows: 100px;
//这样的话 不管怎么拉伸网格的宽度始终大于100px
例子:需求,在行中的网格的数量根据分辨率的大小改变
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
grid-template-rows: 100px;
grid-auto-rows: 100px;
gap: 20px;
叠加布局
原理:将两个内容通过网格的定义单元格的所属区域的方式,定在同一个单元格中
<div class="main"><img src="../images/map.png" alt=""><span>地球</span></div>
/* 样式 */
<style>.main{height: 6.475rem;width: 6.475rem;display: grid;}.main img{grid-area: 1/1/1/1;}.main span{/* grid-column: 1/2;grid-row: 1/2; */grid-area: 1/1/1/1;justify-self: center;align-self: center;font-size: 40px;color: white;}</style>
四、display: table
1. table标签
<table border="1"><caption>我的标题</caption><thead><tr><th>Month</th><th>Savings</th></tr></thead><tfoot><tr><td>Sum</td><td>$180</td></tr></tfoot><tbody><tr><td>January</td><td>$100</td></tr><tr><td>February</td><td>$80</td></tr></tbody>
</table>
caption标题 thead 表头 ,tbody表身 tfoot 表脚 tr 行 th(用在表头中),td单元格
colgroup和col
- COLGROUP 元素指定表格中一列或一组列的默认属性。
- COL 指定基于列的表格默认属性
template:
<table border="1" width="2500" height="500"><colgroup><col span="2" style="background:pink;"><col width="300"><col style="color:blue;"><col style="width:300px;"><col align="left" ><col align="center" style="text-decoration:underline;"><col align="right" style="font-size:20px;font-family:Courier New"><col align="justify" style="cursor:pointer"><col valign="top"><col valign="middle"><col valign="bottom" style="padding:20px;"><col valign="baseline" ></colgroup><tr><td>span="2"</td><td>span="2"</td><td>width="300"</td><td>color:blue;</td><td>width:300px</td><td>align="left"</td><td>align="center"</td><td>align="right"</td><td>align="justify"</td><td>valign="top"</td><td>valign="middle"</td><td>valign="bottom"</td><td>valign="baseline"</td></tr><tr><td>span="2"</td><td>span="2"</td><td>width="300"</td><td>color:blue;</td><td>width:300px</td><td>align="left"</td><td>align="center"</td><td>align="right"</td><td>align="justify"</td><td>valign="top"</td><td>valign="middle"</td><td>valign="bottom"</td><td>valign="baseline"</td></tr></table>
Tips:
- 只有 width 和 background生效了,尽量不用吧
2. display:table用法
目前,在大多数开发环境中,已经基本不用table元素来做网页布局了,取而代之的是div+css,那么为什么不用table系表格元素呢?
1、用DIV+CSS编写出来的文件k数比用table写出来的要小,不信你在页面中放1000个table和1000个div比比看哪个文件大
2、table必须在页面完全加载后才显示,没有加载完毕前,table为一片空白,也就是说,需要页面完毕才显示,而div是逐行显示,不需要页面完全加载完毕,就可以一边加载一边显示
3、非表格内容用table来装,不符合标签语义化要求,不利于SEO
4、table的嵌套性太多,用DIV代码会比较简洁
display:table系列与之相对应的table系的元素,如下:
display: table | table标签 | 讲义 |
---|---|---|
table | table | 此元素会作为会计表格来显示,表格前后带有换行符 |
inline-table | table | 此元素作为内联表格来显示,表格卡后没有换行符 |
table-row-group | tbody | 此元素会作为一个或多个行的分组来显示 |
tabel-head-group | thead | 此元素会作为一个或多个行的分组来显示 |
table-footer-group | tfoot | 此元素会作为一个或多个行的分组来显示 |
table-row | tr | 此元素会作为一个表格行来显示 |
table-column-group | colgroup | 此元素会作为一个或多个列的分组来显示 |
table-column | col | 此元素会作为一个单元格列显示。 |
table-cell | th , td | 此元素会作为一个表格单元格显示。 |
table-caption | caption | 此元素会作为一个表格标题显示。 |
模拟表格: template
<div class="table"><div class="row"><div class="cell">张三</div><div class="cell">李四</div><div class="cell">王五</div></div><div class="row"><div class="cell">张三</div><div class="cell">李四</div><div class="cell">王五</div></div>
</div>
css
.table {display: table;border: 1px solid #cccccc;margin: 5px;/*display: table时padding会失效*/}.row {display: table-row;border: 1px solid #cccccc;/*display: table-row时margin、padding同时失效*/}.cell {display: table-cell;border: 1px solid #cccccc;padding: 5px;/*display: table-cell时margin会失效*/}
Tips :
- display: table-cell 指让标签元素以表格单元格的形式呈现,使元素类似于 td 标签
- display: table-cell 属性也会被 float,position : absolute 等属性**破坏效果**,应避免同时使用。
table 解决问题:
1. 多行文字居中
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>table</title><style>.parent{display: table;width: 400px;height: 400px;text-align: center;border:1px solid red;margin:0 auto;background: blue; /*背景颜色无效*/}.child{display: table-cell; /*子元素成为表格单元格(类似 <td> 和 <th>)*/height: 200px;background: yellow;vertical-align: middle; /*表格容器可以设置垂直对齐属性*/white-space: pre;}</style>
</head>
<body><div class="parent"><div class="child">display: table-row-group;display: table-header-group;display: table-footer-group;display: table-row;display: table-cell;display: table-column-group;display: table-column;display: table-caption;display: ruby-base;display: ruby-text;display: ruby-base-container;display: ruby-text-container;</div></div>
</body>
</html>
Tips :
设置了display:table-cell的元素:
- 对宽度高度敏感
- 对margin值无反应
- 响应padding属性
- 内容溢出时会自动撑开父元素
2. 制作自适应搜索框
涨知识:white-space 属性详解
我们熟知的是:
- 在开发中,无论我们敲多少空格和回车,显示在页面上的都会合并成一个
- 我们的文字在超过一行的情况下,就会自动换行
属性介绍:
这个古诗是怎么打出来的呢?
床(空格)前(空格)(空格)(空格)(空格)明月光,疑是地上霜
(回车)
举头望明月,低头(Tab)思故乡
下面一个表格来说明一下出现这种情况的原因:
属性 | 效果 | 兼容 |
---|---|---|
normal 默认 | 所有空格、回车、制表符都合并成一个空格,文本自动换行 | IE7\IE6 + |
nowrap | 所有空格、回车、制表符都合并成一个空格,文本不换行 | IE7\IE6 + |
pre | 所有东西原样输出,文本不换行 | IE7\IE6 + |
pre-wrap | 所有东西原样输出,文本换行 | IE8 + |
pre-line | 所有空格,制表符合并成一个空格,回车不变,文本换行 | IE8 + |
inherit | 继承父元素 | IE不支持,不推荐使用 |
属性使用:
- 列表溢出换行处理
同样是320px的手机,iphone4可以在一行显示,但是安卓端就会有错位现象,这个开始让我很头疼,这样的话使用媒体查询也无法处理,所以在这一行的父元素中设置,所有的元素强制一行显示。
ul {white-space: nowrap; /*强制内容在一行显示*/overflow: hidden; /*超出部分隐藏*/
}
- 文字溢出省略处理
文字超出去怎么办?一般都自动换行了,想要文字溢出的部分自动用省略号表示,那么离不开三个属性:
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; /*溢出部分使用省略号*/
- 文字展示
如果是显示诗歌,或者文案之类的,很多情况需要输入什么样子,出来什么样子。
这个时候用pre属性是最合适的(毕竟兼容性最好么):
white-space: pre;
五、媒体查询
1. 媒体查询概念
媒体查询:
- 媒体类型
- all :适用于所有设备
- print :适用于在打印预览模式
- screen :只要用于屏幕
- speech : 主要用于语音合成器
- 媒体特性 :描述了user agent、输出设备,或浏览环境的具体特征
- width: viewport的宽度
- height: viewport的高度
- aspect-ratio: viewport的宽高比
- orientation:viewport的旋转方向 ( landscope 水平方向 portrait 垂直方向 )
- …
- 逻辑操作符
- and
- not
- only
- 逗号 ,(类似或)
- link标签方式 (通过media属性设置媒体查询类型和媒体特性)
写法如下:
template
<div class="box">aaaaaaaaaaaa
</div>
css
@media print {.box {font-size: 60px}
}
/* 上面的样式只会在打印模式下会生效 */@media screen and (min-width: 700px) and ( max-width: 1200px){.box {width: 200px;height: 200px;background: pink;}
}
/* 上面的样式只会在屏幕下宽度大于700px并且小于1200px时会生效 */
2. 响应断点(阈值)设定
- Extra Small < 576px
- Small >= 576px , sm
- medium >= 768px , md
- large >= 992px, lg
- x-large >= 1200px , xl
- xx-large >= 1400px, xxl