浮动,定位,BFC边距合并
1. 浮动元素有什么特征?对父容器、其他浮动元素、普通元素、文字分别有什么影响?
- 浮动元素的特征:CSS设计float属性主要目的和初衷,是为了实现文本绕排图片的效果。但是,这个属性也成了创建多栏布局最简单的方式。 浮动的元素已经脱离了文档流(normal flow正常流),因而无论原先在标记中包含它还是跟随它的元素,其布局都会受到它的影响。 说得形象点,在你浮动一张图片或者其他元素时,你是在要求游览器把它往上方推,直到它碰到父元素的内边界。后面的元素不再认为浮动元素在正常文档流中位于它的前面了,有一个例外,就是还处于文档流中元素的文本内容会围绕浮动元素绕排。
-
对父容器的影响。
浮动元素脱离了文档流, 其父元素也看不到它了,因而也不会包围它,也就是通常所说的父容器塌陷,会对布局造成破坏性影响。 浮动造成父容器塌陷.png
-
对其他浮动元素的影响。
如果几个相邻的元素都具有设定的宽度,都是浮动的,而且水平空间也足以容纳它们,它们就会并列排在一行,创建分栏布局的原理。
同一个父容器下高度不统一的浮动元素会按上下顺序排列,紧随其后的浮动元素还会根据属性值水平排列。
高度不统一的浮动元素会按上下顺序排列,紧随其后的浮动元素还会根据属性值排列.png -
对普通元素和文字的影响。
由于浮动元素脱离了文档流,这句话很重要。处于同一个父容器下常规文档流中的元素,会看不到浮动元素。但是处于常规文档流中的元素如果有文本内容,就会围绕浮动元素绕排。
浮动元素对于在常规文档流中的元素的影响1.png
2. 清除浮动指什么? 如何清除浮动? 两种以上方法。
-
清除浮动的目的就是解决浮动元素对布局造成的一些不利结果。例如: 浮动元素造成的父容器塌陷问题;
不想让常规文档流中的元素围绕浮动元素绕排。 -
如何清除浮动?
- 为父容器添加overflow: hidden。
这种方法很简单,但是不直观。实际上,overflow: hidden声明的真正用途是防止包含元素被超大内容撑大。应用overflow: hidden之后,包含元素依然保持其设定的宽度,而超大的子内容则会被容器剪切掉。除此之外,overflow: hidden还有另外一个作用,即它能可靠地迫使父容器(父元素)包含其浮动的子元素。
为父容器添加overflow_hidden强制父容器包围浮动元素.pngoverflow_hidden真正作用.png
-
同时浮动父容器(父元素),可靠地迫使父容器(父元素)包含其浮动的子元素。
当然,在同一个父容器下,同时使子元素都浮动,可以消除文本绕排的排版效果。
使父容器也浮动.png -
添加非浮动的清除元素。
第三种方法,强制父元素包含其浮动元素的方法,就是给父元素的最后添加一个非浮动的子元素,然后给该非浮动子元素添加clear属性和声明。由于父元素一定会包围非浮动的子元素,而这个非浮动的子元素又处于父容器的最下方,因此,父容器一定会包含这个子元素以及前面的浮动元素。
3.1. 在同一个父容器下的最后面添加一个空的子元素div标签,标签属性clear: both或者其他属性值, 来清除浮动元素造成的父容器塌陷。但是不建议使用这种方法,因为会添加一个无意义的标签。
同一个父容器下最后面添加一个clear属性的标签.png
3.2. 通过CSS样式,给父容器添加clearfix类。
通过给父容器添加clearfix类.png
-
在没有父元素时如何清除。
最简单的办法就是给一个浮动元素应用clear:both或者根据情况添加其他属性值,强迫它定位在前一个浮动元素的下方。
添加clear属性.png
3. 有几种定位方式,分别是如何实现定位的,参考点是什么,使用场景是什么?
-
inherit, 规定应从父元素继承position属性的值。
-
static, 默认值,在这种情况下,每个元素都处于常规文档流中(normal flow),要想突破static定位提供的这种顺序布局元素的方式,必须把盒子的position属性改为其他三个值。
-
position: relative,把position属性设置为relative,生成相对定位。到底是相对于哪里定位呢?相对的是它原来在常规文档流中的位置(或者说是默认位置)。接下来,可以使用top、right、bottom、left属性来改变它的位置。要注意,除了设置了这个position:relative的元素自己相对于原始位置挪动一下之外,没有发生任何变化。换句说,这个元素始终占据的空间没有动,其他元素也没动。 使用相对定位的关键是什么呢?就是要考虑到元素原来的空间。
使用相对定位要考虑元素原来的空间.png -
position: absolute, 绝对定位。绝对定位会把元素彻底从常规文档流中拿出来。绝对定位下,元素会从文档流中被“连根拔起”,然后相对于其他元素定位。既然绝对定位是相对其他元素定位,那么就引出了关于定位一个重要的概念:定位上下文。绝对定位跟相对定位的不同之处在于,绝对定位不是根据它在常规文档流中的位置移动,而是相对于祖先元素在定位。实际上,绝对定位的任何祖先元素都可以成为它的定位上下文,只要你把相应祖先元素的position设定为relative即可。绝对定位的元素可以通过top、right、bottom、left属性来进行位置的设定。
-
position: fixed, 固定定位。从完全移出文档流的角度说,固定定位与绝对定位类似。不同之处在于,固定定位元素上下文是视口(游览器窗口或者手持设备的屏幕),因而它不会随页面滚动而移动。最常见的情况是用它创建不随页面滚动的导航条或者用户登录信息栏,或者弹出视频窗口。
绝对定位.png -
position: sticky。 CSS3新属性,表现类似position:relative和position:fixed的合体。当目标区域在屏幕中可见时,它的行为就像position:relative;而当页面滚动超出目标区域的时,它的表现就像position: fixed,它会固定在目标位置。
position sticky1.png
4. z-index 有什么作用? 如何使用?
z-index 属性设置元素的堆叠顺序。在同一堆叠上下文中,拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。
默认情况下,是按照堆叠顺序来显示元素。
设置了z-index后,在同一堆叠上下文中,拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。 在同一堆叠上下文中,拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。.png
更多内容可以参考这篇博客,关于z-index的总结
5.position:relative和负margin都可以使元素位置发生偏移?二者有什么区别?
二者的区别
-
position:relative相对定位后元素位置发生偏移,只是视觉上显示的位置变化,但是它仍会占据原来在常规文档流中
的空间,不会影响其他文档流元素。 -
负margin会使元素在文档流中位置发生偏移,会影响周边的元素位置变化。
6. BFC 是什么?如何生成 BFC?BFC 有什么作用?举例说明。
-
BFC是Block Formatting Context, 翻译过来即块级格式化上下文。
-
关于如何生成BFC
- float为 left,right。
- overflow为 hidden,auto,scroll。
- display为 table-cell,table-caption,inline-block。
- position为 absolute,fixed。
-
BFC有什么作用?举例说明, 请看图示。
-
BFC会阻止垂直外边距(margin-top、margin-bottom)折叠。
按照BFC的定义,只有同属于一个BFC时,两个元素才有可能发生垂直Margin的重叠,这个包括相邻元素,嵌套元素,只要他们之间没有阻挡(例如边框,非空内容,padding等)就会发生margin重叠。
因此要解决margin重叠问题,只要让它们不在同一个BFC就行了,但是对于两个相邻元素来说,意义不大,没有必要给它们加个外壳,但是对于嵌套元素来说就很有必要了,只要把父元素设为BFC就可以了。这样子元素的margin就不会和父元素的margin发生重叠。
生成BFC阻止上下margin的合并.png -
BFC不会重叠浮动元素。
BFC不会重叠浮动元素.png
-
BFC可以包含浮动。
BFC可以包含浮动.png
7. 在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例。
7.1 在什么场景下会出现外边距合并?
当块处于同一个文档流或者同一个BFC中,两个元素才有可能发生垂直Margin的重叠,这个包括相邻元素,嵌套元素,只要他们之间没有阻挡(例如边框,非空内容,padding等)就会发生margin重叠。对于父子元素,容器没有padding和border内部的margin会导致外边距合并。
7.2 如何合并?
合并规则
- 两个margin都是正值的时候,取两者的最大值。
请看图示, box1 和 box2 处于同一个BFC当中,统一设置了margin:40px;但是box1和box2之间的外边距不是80px而是40px, 就发生外边距合并。
请看图示, box1 和 box2 处于同一个BFC当中,box1的margin-bottom:40px, box2的margin-top: 50px, 但是box1和box2之间的外边距不是90px而是50px, 发生外边距合并。
上下margin都为正值的情况margin取最大值.png
-
当 margin 都是负值的时候,取的是其中绝对值较大的,然后,从0位置,负向位移。
margin都为负值取margin绝对值大的合并.png -
当有正有负的时候,先取出负 margin 中绝对值中最大的,然后和正 margin 值中最大的 margin 相加。
margin都为负值取margin绝对值大的合并.png
7.3 如何不让相邻元素外边距合并?
-
被非空内容、padding、border 或 clear 分隔开。
防止父子间的margin合并加了border.png
-
不在一个普通流中或一个BFC中。
同一父容器下把子元素生成BFC阻止外边距合并.png -
浮动元素、inline-block 元素、绝对定位元素的 margin 不会和垂直方向上其他元素的 margin 折叠(注意这里指的是上下相邻的元素)。
浮动元素不会叠加上下margin.png
7.4 给个父子外边距合并的范例。
处于常规文档流中,给父容器box1设置了margin :20px,里面的子元素标签p也处于常规文档流中,默认的margin值(16px)被合并,所以变成了20px,发生了父子外边距合并。
父子间的上下margin合并.png
如果把父容器转化为一个新的BFC即可解决父子边距合并,还有一些其他方法,在此不一一列举了。
形成新的BFC阻止父子边距合并.png