布局
1. 定位
1.1 文档流
单个元素:
- 块级元素:内容宽度是其父元素的宽度的100%,并且与其内容一样高。
- 内联(行内)元素:高宽与他们的内容高宽一样。(所以不能为他们设置宽高)
元素之间的交互:
- 块级元素:在视口中垂直布局——每个都将显示在上一个元素下面的新行上。
- 内联元素:它们互相之间以及任何相邻(或被包裹)的文本内容位于同一行上。如果没有空间,那么溢出的文本或元素将向下移动到新行。
- 外边距折叠:两个外边距接触,则两个外边距中的较大者保留,较小的一个消失。
1.2 介绍定位
1.2.1 静态定位
静态定位是每个元素获取的默认值——它只是意味着将元素放入它在文档布局流中的正常位置。
1.2.2 相对定位
position: relative;
top
, bottom
, left
, 和 right
来精确指定要将定位元素移动到的位置。
PS:描述和实际情况相反,比如你设置【top: 30px;】你将会看到你所选择的元素向下移动了30px,这是相对定位工作的方式。你可以想象一个力作用在这个盒子的顶部,将它向下推了30px。
1.2.3 绝对定位
position: absolute;
绝对定位的元素不再存在于正常文档布局流中。top
,bottom
,left
和right
以不同的方式在绝对定位,它们指定元素应距离每个包含元素的边的距离,而不是指定元素应该移入的方向。
1.2.4 定位上下文
判断绝对定位元素的包含元素的方式:取决于绝对定位元素的父元素的position属性。
- 所有的父元素都没有显式地定义position属性:父元素默认情况下position属性都是static。绝对定位元素会被包含在初始块容器中(和浏览器视口一样的尺寸)。
- 其中一个父元素的position属性是relative:相对于这个父元素进行定位。
1.2.5 z-index
“z-index”是对z轴的参考(无单位)。正值将它们移动到堆栈上方,负值将它们向下移动到堆栈中。默认情况下,定位的元素都具有z-index为auto,实际上为0。
1.2.6 固定定位
fixed:这与绝对定位的工作方式完全相同。绝对定位固定元素是相对于 <html>
元素或其最近的定位祖先,而固定定位固定元素则是相对于浏览器视口本身。
1.2.7 position: sticky
被定位的元素表现得像相对定位一样,直到它滚动到某个阈值点为止,此后它就变得固定了。
2. Flexbox
我们想要将哪些元素设置为Flexbox,就需要给这些flexible元素的父元素display设置为一个特定值——flex。
PS:如果想设置行内元素为flexible box,也可以设置display属性为inline-flex。
2.1 flex模型说明
- 主轴(main axis)是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。该轴的开始和结束被称为 main start 和 main end。
- 交叉轴(cross axis)是垂直于 flex 元素放置方向的轴。该轴的开始和结束被称为 cross start 和 cross end。
- 设置了
display: flex
的父元素被称之为 flex 容器(flex container)。 - 在 flex 容器中表现为柔性的盒子的元素被称之为 flex 项(flex item)。
=> 主轴的方向可以设置,Flexbox提供了flex-direction这个属性:
row(默认值)/ column / row-reverse / column-reverse (reverse为反向排列flex项)
flex是三个属性的缩写:flex-grow/flex-shrink /flex-basis
-
flex-grow:无单位比例
flex-shrink
:指定了从每个 flex 项中取出多少溢出量,以阻止它们溢出它们的容器flex-basis
:最小值
2.2 换行
当在布局中使用了定宽或者定高时,可能会出现flexbox中子元素溢出破坏布局的情况。解决方法如下:
flex-wrap: wrap;
flex: 200px; //表示每个元素的宽度至少是200px
这样就实现了换行操作:任何溢出的元素都会被移到下一行。最后一行如果没有排满,那么最后一行的元素会变得更宽,以便把整个行填满。
PS:flex-direction 和 flex-wrap 可以缩写为 flex-flow 。
flex-direction: row;
flex-wrap: wrap;
//下面这一句是一样的意思
flex-flow: row wrap;
2.3 flex项的动态尺寸
article { flex: 1; } article:nth-of-type(3){ flex: 2; }
我们设置的flex值是一个无单位的比例值,表示每个flex项沿主轴的可用空间大小。只看第一个article,表示每个元素占用的空间是相等的(占用空间是指设置padding和margin之后剩余的空间)。而后面一句表示第三个元素要占用两倍可用宽度。也就是说,前两个元素每个占1/4的空间,第三个元素占1/2。
article { flex: 1 200px; } article:nth-of-type(3){ flex: 2 200px; }
这里的200px是给flex指定了最小值。意味着给每个项首先分出200px可用空间,剩余的空间再根据设置的比例进行分配。
=>flexbox的价值就在于它的响应性。如果调整浏览器窗口的大小或增加一个元素,布局仍然是正确的。
2.4 水平和垂直对齐
- align-items:控制flex项在交叉轴上的位置。
- stretch(默认值):所有的flex项沿着交叉轴的拉伸以填充父容器。如果父容器在交叉轴方向上没有固定宽高,则变为最长的flex项的长度。
- center:这些项保持原有的高度,但在交叉轴居中。
- flex-start / flex-end:使flex项在交叉轴的开始/结束处对齐所有的值。
- justify-content:控制flex项在主轴上的位置。
- flex-start(默认值):所有项都位于主轴的开始处。
- flex-end:所有项都位于结尾处。
- center:让flex项在主轴居中。
- space-around:让所有的flex项在主轴均匀地分布,再任意一段都留有一定的空间。
- space-between:不会在两端留下空间。
PS:align-self属性可以覆盖align-items的行为。
2.5 flex项排序
flexbox可以改变flex项布局位置,且不会影响到源程序。
button:first-child{ order: 1; }
这里设置的order值是用于排序的。
所有flex项的默认order值是0,order值大的比小的显示顺序更加靠后,相同order值的项按照源顺序显示。当然也可以给order设置负值让他们排的更前面。
2.6 flex嵌套
一个元素是flex项,他同样可以成为一个flex容器,它的子节点也表现为flexible box。
3. 网页布局
3.1 一列布局
margin : 0 auto;
3.2 两列布局
1. 双inline-block
.wrapper { font-size: 0; } .left, .right { display: inline-block; vertical-align: top; box-sizing: border-box; } .right { width: calc(100% - 140px); }
2. 双float
.wrapper{ overflow: auto; } .left, .right { float: left; box-sizing: border-box; } .right { width: calc(100% - 140px); }
3. float + margin-left
.wrapper-float { overflow: hidden; } .left { float: left; } .right { margin-left: 150px; }
4. absolute + margin-left
.left { position: absolute; } .right { margin-left: 150px; }
5. float + BFC
.wrapper { overflow: auto; } .left { float: left; margin-right: 20px; } .right { margin-left: 0; overflow: auto; }
6. flex
.wrapper { display: flex; align-items: flex-start; } .left { flex: 0 0 auto; } .right { flex: 1 1 auto; }
3.3 三列布局
三列布局指的是两侧定宽中间自适应。
1. 圣杯布局
为了中间div内容不被遮挡,将中间div设置了左右padding-left和padding-right后,将左右两个div用相对布局position: relative并分别配合right和left属性,以便左右两栏div移动后不遮挡中间div。
2. 双飞翼布局
为了中间div内容不被遮挡,直接在中间div内部创建子div用于放置内容,在该子div里用margin-left和margin-right为左右两栏div留出位置。