前言
接着上一篇,这篇主要集中对BFC、浮动、定位、负margin和相对定位的区别、伪类和伪元素进行整理。
一、BFC(块级格式化上下文)
1、如何形成BFC
对元素设置以下属性:(嵌套元素时则对父元素设置)
float:left/right
overflow:scroll/hidden/auto;
display:inline-block/table-cell/table-caption
position:absolute/fixed
2、设置BFC能解决的问题
(1)同属一个BFC的两个相邻或嵌套元素,外边距margin的设置会产生合并。
相邻元素垂直外边距合并情况。
这时对两个相邻元素其中一个设置BFC,形成一个新的BFC就可以清除这个问题:
(2)嵌套元素的外边距合并情况
在父元素中使用BFC,让子元素的margin设置生效:
(3)BFC不会重叠浮动元素
如下:浮动元素和文档中正常流的元素重叠
对正常元素设定BFC之后:
(4)BFC解决浮动后的高度坍塌:因为BFC可以包含浮动
看下面例子:子元素全部浮动,父元素高度坍塌,父元素背景颜色设置无效。
对父元素设置BFC之后,父元素能够包裹住两个浮动子元素,背景颜色设置生效
二、浮动
1、重要特性
设置浮动的元素,不在文档的普通流中,文档的普通流中的元素表现的就像浮动元素不存在一样。**
设置浮动,元素漂浮直至碰到边框为止停止。
2、文字环绕特性
注意:跟在浮动元素后面的正常文档流中的元素,会当浮动元素不存在,但该元素中的文字却能感知浮动元素的存在,会移动给浮动框留出空间,所以常见文字环绕浮动元素的现象。
设置浮动后:文字并不会跟随置顶(可以设置BFC,让浮动元素和正常流元素不重叠)
3、浮动引起的高度坍塌问题
如果不清除浮动,那么父容器元素就会出现高度坍塌。
如下,本来父元素的高度是靠子元素的高度来撑开的。
4、清除浮动
(1)使用clear属性:clear:both/left/right/none
记住:clear属性只对自身有效,是作用于自己的。
比如三个竖排的div,都设定右浮动,就会并排为一列,向右靠。
然后想让第二个div向下一行,就需要对第二个设定clear:right,让它的右边不允许出现浮动元素的意思。而不是对第一个元素设定clear,这样是无效的。常见直接了当设置为clear:both
(2)清除浮动方法一:
在子元素后面再添加一个空div,对它设定清除两边浮动。
但这样就增加一个无意义的标签,所以不建议。
(3)清除浮动方法二:BFC清除浮动
根据BFC的特性,可以通过对元素属性设定BFC属性就可以清除浮动。
但是父容器解决了坍塌,父容器的父容器呢?没办法一次解决;
而且因为BFC的形成是需要对元素设置属性的,所以都会产生属性设置带来的影响。有些可能还是我不想要的。而且像display:inline-block的设置,在IE67中是无效的。所以这并不是好办法。
(4)最通用清除浮动方法:(且兼容IE67的方法)
对父容器设置一个class——clearfix,然后对其设置如下属性:
.clearfix{
*zoom:1;
}
.clearfix:after{ /*记得写after,最后一个子元素插入内容*/
content:" "; /*注意是content*/
display:block;
clear:both;
}
这种方法可以清除浮动,且不会增加一个无用的标签
总而言之:清除浮动有两种方法:使用clear属性;让父元素形成BFC,灵活灵用。很多时候,像父容器本身就需要设置position:absolute的时候,刚好也就形成BFC了,所以我们不再需要额外设置什么。
三、定位
1、定位属性
(1)position:inherit,继承父元素的position属性设置
(2)position:static,定位的默认设置,相当于没有设置的效果。元素在文档正常流中。自然top/left/right/bottom/z-index的设置对其都无效
(3)position:relative,相对定位。相对元素在正常文档流中的位置进行定位移动。无论元素是否移动,只要设置了相对定位,元素在文档流中的空间位置还是不变的,只是看上去位置移动了。其他元素还是认定该元素的原有空间位置的。
(4)position:absolute,绝对定位。元素脱离了正常的文档流。
注意:设定绝对定位的元素位置是相对其有设定position属性(除设置static之外)的父元素进行定位。如果父元素没有设置定位属性,则再往上找父元素的父元素,一直往上,直至html的根节点,则相对html根节点的位置进行top/left/right/bottom属性的设置移动
2、验证1:绝对定位是相对html的位置做定位,而不是body
父节点body设置相对定位后,就相对body的位置定位:
3、验证2
如果父元素中有设置padding/border/margin,那么设定绝对定位的子元素的top/left/right/bottom的属性是相对内边距、外边距还是边框呢?受谁影响?
测试可知,设定position:absolute后,如果不设定top/left/right/bottom(则默认为top/left/right/bottom:auto),那么元素就相对内边距padding而定。(如果父元素有设置padding的话),所以一定要记得position:absolute设置后,随手设定top/left/right/bottom,设定为0也行。
这也是为什么要设定“父相子绝”的原因,让子元素可以相对父元素做位置设定,而且不会超出父元素位置,同时父元素设定相对定位,而不设置top/left/right/bottom这些设置的话,父元素位置是不变的
4、绝对定位是脱离文档流的
这点和浮动有点小区别。浮动元素也是脱离文档流,但是相邻元素里的文本还是能感知浮动元素的存在而产生环绕。而绝对定位的设置,其他元素都会完全当这个元素不存在一样。
5、设置z-index来控制叠放顺序
绝对定位因为和文档流无关,所以可以覆盖其他元素,两个绝对定位元素也可以覆盖。可以通过设置z-index来控制叠放顺序。
6、设置绝对定位后宽度也做设置
绝对定位设置后,元素的宽度是会收缩的,默认会根据内容而定,由内容多少来撑开。所以设定绝对定位后,需要把宽度值也一并做设定
7、关于宽度100%
一般如果父子元素都没有特别设置,那么子元素的width:100%,就是子元素的content宽度等于父元素content宽度(这个日常要记住)
如果是子元素设定绝对定位,那么子元素的width:100%,就是子元素的content宽度等于父元素padding+content的宽度
同理的,对于设置绝对定位后,left/top/right/bottom的宽度设置%百分比,也是相对父元素的content宽度而取的。
8、position:fixed,绝对定位
细分叫固定定位。相对浏览器窗口定位,通过top/left/right/bottom属性的设置移动。
9、position:sticky
CSS3的新属性,兼容性差,表现类似position:relative和position:fixed的合体,在目标区域在屏幕中可见时,它的行为就像position:relative; 而当页面滚动超出目标区域时,它的表现就像position:fixed,它会固定在目标位置。IE11、chrome部分支持。手机浏览器不支持。
10、绝对定位的使用场景
重要常见的是:垂直、水平的绝对居中
/*父元素的设置*/
.wrapper{
border:2px solid black;
width:200px;
height:200px;
padding:20px;
position:relative
}
/*子元素的设置*/
.one{
border:2px solid yellow;
width:100px;
height:100px;
position:absolute;
top:50%; /*取父元素content宽度的一半*/
left:50%;
margin-left:-50px; /*取子元素宽度的一半*/
margin-top:-50px; /*取子元素高度的一半*/
}
四、负margin和相对定位的区别:
一个元素设置负margin,它的相邻元素位置也是会受影响,跟随做移动的。
而相对定位的设置,它的相邻元素位置是不受影响的。还是认该元素在文档流中本来的位置而定位
五、伪类和伪元素
1、伪类
伪类用于元素在某种状态下时,进行样式的变化设置。记得是元素的状态变化。
(1)常见的表单类的伪类:
:checked
:disabled
:read-only
:valid,:invalid
(2)对于伪类,常见的知识点就是,区分a链接的状态:
:hover 当鼠标放在元素上时
:link 作为一个a链接元素时
:active 鼠标放在元素上,按下鼠标的时候
:focus 鼠标获取焦点的时候
:visited 链接被访问过后
明白这几个伪类的书写顺序,不至于让有些伪类的状态样式设置失效:记住样式的设置,越往后的权重越高,设置就会保留。
摆放顺序是:
a:link
a:visited
a:hover
a:active
这个顺序可由测试得知,当然要记忆的话,就可以理解来记忆:首先先是个a链接,:link这个伪类设置可设可不设。然后:visited这个伪类,是肯定放在link后面,才点击后的设置生效。然后是:hover,是鼠标略过时候的变化,这个是放在:visited后面,才不会被visited覆盖。然后active这个操作,是鼠标按下之后的操作,相比hover还有进一步动作的,为避免被覆盖,还得放在更后面。
(3)first-child和first-of-type
h1:first-child,意思就是是h1元素下的第一个子元素
h1:first-of-type,意思选择是h1元素,并且它是它父亲元素下的子元素中第一个h1元素的子元素。
5、伪元素
伪元素是很广泛的应用,可以创建不在文档树中的元素,并设置其样式。这样可以省标签。很常见的用法,要学会记得使用。
(1)伪元素常见的伪元素有:
::after/:after,::before/:before,两者写法相同,双冒号是CSS3的写法
::first-letter/:first-letter,就是单词首字母的设置
::first-line/:first-line,就是多行文字中第一行的设置
重点区分,:before和:after伪元素,是分别生成作为所在元素内部创建第一个子元素和最后一个元素,content这一行是一定要有的,即使是content:' ',没有写的话,设置伪元素就失效
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="box">
<p>这是第一段</p>
<p>这是第二段</p>
</div>
<style>
.box:before{
content: 'start'
}
.box:after{
content: 'end'
}
</style>
</body>
</html>
结果:
(2)after和before伪元素的应用
1)生成最后一个或第一个子元素
2)清除浮动
3)小三角的实现:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style>
.bubble{
border:1px solid black;
width:200px;
height:30px;
line-height:30px;
background:#fff;
border-radius:5px;
position:relative;
top:20px;
text-align:center;
}
.bubble:before{
content:'';
display:inline-block;
width:10px;
height:10px;
border-top:1px solid red;
border-left:1px solid red;
transform:rotateZ(45deg);
position:absolute;
top:-6px;
left:20px;
background:#fff;
}
</style>
</head>
<body>
<div class="bubble">hi, 这里是饥人谷</div>
</body>
</html>
实现效果:
3)字体图标的使用:
我们使用审查元素来看一个icon的时候,常看到的是有::before
背后这个icon的显示就是使用了伪元素。当我们打开icon的引用src路径时,可以看到,前面的样式设置都是些兼容的写法,作用于靠before生成的元素,元素的内容也就是这个content就是一个Unicode码。因此字体图标其实都是伪元素来生成的。
(3)其他应用
实现input的默认样式的修改,已经状态值变化后的样式:
修改input的复选框的默认样式的关键:
-webkit-appearance: none;
appearance: none;
关键点就是使用:checked的伪元素:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
今天的心情: <input type="checkbox">
<style>
input[type=checkbox]{
-webkit-appearance: none;
appearance: none;
background: url(http://7xpvnv.com2.z0.glb.qiniucdn.com/b6dcd011-23cc-4d95-9e51-9f10100103bd.png) 0 0 no-repeat;
display: inline-block;
width: 20px;
height: 20px;
background-size: contain;
vertical-align: middle;
outline: none;
}
input[type=checkbox]:checked{
-webkit-appearance: none;
appearance: none;
background: url(http://7xpvnv.com2.z0.glb.qiniucdn.com/538f26f0-6f3e-48d5-91e6-5b5bb730dd19.png) 0 0 no-repeat;
display: inline-block;
width: 20px;
height: 20px;
background-size: contain;
vertical-align: middle;
}
</style>
</body>
</html>
实现效果:
(4)还有下面的常见伪元素,仅能双冒号:
:selection,用于设置被选中的文字的样式
:input-placeholder,这个挺好的。就是用于设置input元素的placeholder的样式
//记住要兼容写法才生效
input::-webkit-input-placeholder{
color: blue
}
input::selection{
color:red;
}