布局
在什么默认情况下, 浏览器遵循正常布局流.
块盒自上而下排列.
用这些东西可以脱离正常布局流
- display
- float
- position
- 表格布局
- 多列布局
display
flex
flex通常用来设计横向或者纵向的布局.
flex模型沿着两个轴来布局: 一个主轴(main axis), 一个交叉轴(cross axis). 这两个相互垂直.
设置了display: flex;的父元素一般被称为flex容器, 容器中表现为弹性盒的叫做flex项.
轴的方向
这个属性决定主轴的方向. 默认是row, 这使得主轴是水平的从左到右(至少我们一般接触到的都是从左到右, 部分国家地区可能是从右到左).
如果改成column, 那么主轴是竖直的从上到下.
flex项就沿着主轴依次排列.
处理溢出
当flex项增多时, 且容器定宽/高就有可能发生溢出.
可以使用flex-wrap, 可以设置no-wrap, wrap, wrap-reverse. 初始值是no-wrap, 设置成wrap就可以换行.
启用换行后可能出现子项占据容器的宽/高, 可能是没有设置flex导致的.
flex: 200px可以设置子项占据的最小空间, 浏览器发现达不到200px就会进行换行.
动态尺寸
可用空间指的是主轴空间去除padding和子项的margin, 剩下的空间.
- flex-grow: 声明占用可用空间的比例(初始值是0)
.box1 {
flex-grow: 1;
}
.box2 {
flex-grow: 2;
}假设只有这两个子项, 那么box1就会占据3份中的1份. box2占据3份中的2份.
如果有两个box1和一个box2, 那么box1占据4份中的1份, box2占据4份中的2份.
- flex-shrink: 如果容器空间不足, 缩小几倍以防止溢出(初始值是1)
- flex-basis: 最小值
.box1 {
flex-grow: 1;
flex-basis: 200px;
}
.box2 {
flex-grow: 2;
flex-basis: 200px;
}设置最小宽度, 达到最小宽度后再进行可用空间的分配.
这里子项先分配200px的可用空间, 剩下的按比例分配.
沿轴对齐
- align-items: 控制flex项在交叉轴的位置
- 初始值是stretch, 所有flex项沿着交叉轴的方向填充容器. (如果没有设置宽/高度)
- center: 保留原有高度, 沿交叉轴居中
- flex-start/flex-end: 在交叉轴开始或结束处
可以用align-self来覆盖align-items的行为
- justify-content: 控制flex项在主轴的位置
- flex-start/flex-end
- center
- space-around: 使所有flex沿主轴均匀分布
- space-between: 跟space-around类似, 但是两端不会留下任何空间
排序
使用order属性, 初始值是0.
order值大的排在后面.
grid
grid布局通常用来设计网格布局.
定义一个网格
除了设置display: grid;, 通常还搭配其它属性.
- grid-template-columns/grid-template-rows: 决定一列/一行排多少个, 每个有多宽/高
.container {
display: grid;
grid-templates-columns: 200px 300px 400px;
}这就表示一行排三列, 第一列200px, 第二列300px, 第三列400px.
有一个新单位fr, 按比例分配可用空间.
grid-templates-columns: 1fr 2fr 3fr, 表示把一行的可用空间平均分成六份, 第一列一份, 第二列两份, 第三列三份.
- gap/grid-gap: 项之间的间隔
gap和grid-gap效果一样, MDN推荐两个都写上去.
- grid-auto-rows/grid-auto-columns
一般情况下我们只会使用grid-templates-columns和grid-templates-rows中的一个, 这个grid-auto就是帮助我们设置另一个的.
grid-auto-rows: 100px;将每行的高度设置成100px, 如果不够浏览器就会拉伸. 可以使用auto, 设置成最合适的高度.
以及两个函数
- repeat 我们有时候可能需要很多列/行, 手写太麻烦了就可以用这个函数.
grid-templates-columns: 1fr 1fr 1fr;等价于grid-templates-columns: repeat(3, 1fr)
还可以使用auto-fill, 让浏览器自己决定多少列/行. 不过一般会搭配minmax来使用, 限制宽/高度.
- minmax
设置值的最大和最小, 允许值在区间内变动.
grid-auto-rows: minmax(100px, auto)确保每行至少100px, 高度自动可以防止溢出, 如果100px不够就会伸长到刚好完全展示内容.
grid-templates-columns: repeat(auto-fill, minmax(200px, 1fr));表示每列至少200px, 否则就不排在这一行.
使用这些东西就定义好了一个网格. 接下来就是放置元素到网格里了.
放置元素
默认情况下, 子项会一个一个放进去.
此外, 有基于线的元素放置和基于grid-template-areas的元素放置.
我们的网格可以大致画成一个表的样子, 如果把分隔线和边框画出来的话.
grid-column: 2表示第二列.
grid-column: 1 / 3表示第一条行分割线开始, 到第三条行分隔线结束.
基于grid-template-areas比较直观
.container {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
gap: 20px;
}
header {
grid-area: header;
}
article {
grid-area: content;
}
aside {
grid-area: sidebar;
}
footer {
grid-area: footer;
}float
- left: 将元素浮动到左侧
- right: 将元素浮动到右侧
- none: 初始值, 不浮动
position
- static: 初始值
- relative: 相对正常的自己定位
.box {
position: relative;
top: 10px;
}这就会相对正常参与文档流的自己向下移动10px.
依旧参与正常文档流.
- absolute: 相对包含块或初始块定位
不参与正常文档流
- fixed: 相对视口定位
不参与正常文档流
- sticky: static和fixed的混合.
在正常布局流滚动, 直到出现在设定的最近滚动祖先的位置, 就跟fixed的效果一样了.
定位产生的层叠上下文
使用定位(非static)会产生层叠的能力, 可以覆盖或被覆盖.
我们可以使用z-index来声明在z轴的顺序.