yongquanx 2019-06-30
CSS篇主要从CSS兼容、CSS3新特性、CSS选择器、高频属性、高频布局、高频知识点、性能优化等方面进行归纳。如对HTML知识点感兴趣,可移步至:知识整理之HTML篇
CSS Hack
就是针对不同的浏览器或不同版本浏览器写特定的CSS
样式达到让浏览器兼容的过程。CSS Hack
常见的有三种形式:CSS属性Hack、CSS选择符Hack以及IE条件注释Hack。
color: red; /* 所有浏览器识别 */ _color: red; /* 仅IE6 浏览器识别 */ -color: red; /* 仅IE6 浏览器识别 */ *color: red; /* 仅IE6、IE7 浏览器识别 */ +color: red; /* 仅IE6、IE7 浏览器识别 */ *+color: red; /* 仅IE6、IE7 浏览器识别 */ #color: red; /* 仅IE6、IE7 浏览器识别 */ color: red\0; /* 仅IE8-IE10 浏览器识别 */ color: red\9\0; /* 仅IE9、IE10 浏览器识别 */ color: red!important; /* 仅IE6 浏览器不支持 */
*html #demo { color: red; } /* 仅IE6 浏览器识别 */ *+html #demo { color: red; } /* 仅IE6、IE7 浏览器识别 */ body:nth-of-type(1) #demo { color: red; } /* IE9+、FF3.5+、Chrome、Safari、Opera 可以识别 */ head:first-child+body #demo { color: red; } /* IE7+、FF、Chrome、Safari、Opera 可以识别 */ :root #demo { color: red9; } /* 仅IE9 识别 */
<!--[if IE]>此处内容只有IE可见<![endif]--> <!--[if IE6]>此处内容只有IE6.0可见<![endif]--> <!--[if !IE 7]>此处内容只有IE7不能识别,其他版本都能识别,当然要在IE5以上。<![endif]--> <!--[if gt IE 6]> IE6以上版本可识别,IE6无法识别 <![endif]--> <!--[if gte IE 7]> IE7以及IE7以上版本可识别 <![endif]--> <!--[if lt IE 7]> 低于IE7的版本才能识别,IE7无法识别。 <![endif]--> <!--[if lte IE 7]> IE7以及IE7以下版本可识别<![endif]--> <!--[if !IE]>此处内容只有非IE可见<![endif]-->
padding
和margin
不同问题症状:常用标签,不加样式控制的情况下,各自的margin
、padding
差异较大。
解决方案:
* { margin: 0; padding: 0; }
备注:这个是最常见的也是最易解决的一个浏览器兼容性问题,几乎所有的CSS文件开头都会用通配符*来设置各个标签的margin
、padding
是0。
问题症状:常见症状是IE6中后面的一块被顶到下一行。
解决方案:在float的标签样式中设置
#demo { display: inline }
问题症状:IE6、7和遨游里这个标签的高度不受控制,超出自己设置的高度。
解决方案:给超出高度的标签设置
#demo { overflow: hidden; } /* 或者 */ #demo { line-height: 8px; } /* 假设标签高度为9px */
问题症状:IE6里的间距比超过设置的间距
解决方案:
#demo { display: block; display: inline; display: table; }
备注:行内属性标签,为了设置宽高,我们需要设置display:block;
(除了input标签比较特殊)。在用float布局
并有横向的margin
后,在IE6下,他就具有了块属性float后的横向margin的bug
。不过因为它本身就是行内属性标签,所以我们再加上display:inline
的话,它的高宽就不可设了。这时候我们还需要在display:inline
后面加入display:talbe
。
问题症状:几个img标签放在一起的时候,有些浏览器会有默认的间距,加了问题一中提到的通配符也不起作用
。
解决方案:
img { float: left; }
备注:因为img
标签是行内属性标签,所以只要不超出容器宽度,img
标签都会排在一行里,但是部分浏览器的img
标签之间会有个间距。去掉这个间距使用float是正道。
解决方案:
#demo { opacity: 0.5; filter: alpha(opacity=50); filter: progid:DXImageTransform.Microsoft.Alpha(style = 0, opacity = 50); -moz-opacity: 0.5; -khtml-opacity: 0.5; }
类型: 基础选择器、组合选择器、熟悉选择器、伪类、伪元素
基础选择器包含:通用选择器、元素选择器、类选择器、id选择器
组合选择器包含:多元素选择器、后代选择器、子元素选择器、毗邻选择器、相邻选择器
:
开头,冒号后面是伪类的名称和包含在圆括号中的可选参数。其实第一段话就囊括CSS3伪类的全部定义了,这段话中指出CSS3伪类的功能有两种:
a
链接的:link
、:actived
等,这些信息不存在DOM树结构中,只能通过css选择器来获取。:nth-child(odd)
实现选择偶数行设置背景色,如果不是用伪类,而是用JavaScript
来设置就复杂得多。通过伪类实现了常规CSS
无法实现的逻辑。::
开头,然后是伪元素的名称。::
是为了和伪类(CSS2中并没有区别)做区分。考虑兼容性CSS2
中已存在的伪元素仍可以使用单引号:
语法。但是CSS3
中新增的伪元素必须以使用::
。简单来说,伪元素创建了一个虚拟容器,这个容器不包含任何DOM元素,但是可以包含内容。另外,开发者还可以为伪元素定制样式。
选择器的优先级分为两种:1. 选择器在同一级别时。2. 选择器在不同级别时。
!important
,会覆盖任意位置定义的样式。作为style
属性写在元素内的样式。id
选择器class
选择器总结:!important > id选择器 > class选择器 > 标签选择器 > 通配符选择器 > 浏览器默认属性
同一级别的选择器,后声明的会覆盖之前声明的。
style=''
。权值为1000。id
选择器,如#content
,权值为0100。.content
、:link
、[type=text]
等,权值为0010。!important
(权重),它没有特殊性值,但它的优先级是最高的,为了方便记忆,可以认为它的特殊性值为1,0,0,0,0。font
、font-family
、font-weight
、font-size
、font-style
、font-variant
、font-stretch
、font-size-adjust
lowercase
(仅小写字母)、uppercase
(仅大写字母)、capitalize
(文本中的每个单词以大写字母开头)ltr
(默认,从左到右)、rtl
(从右到左)CSS盒子模型:由四个属性组成的外边距(margin)、内边距(padding)、边界(border)、内容区(width和height)
/* 标准盒模型 */ box-sizing: content-box; /* IE盒模型 */ box-sizing: border-box; /* 继承父元素 */ box-sizing: inherit;
属性值如下:position
: static | relative | absoulte | fixed | sticky | inherit
默认值。没有定位,遵循常规流(忽略 top
, bottom
, left
, right
或者 z-index
声明)。
相对定位,相对于其正常位置进行定位,遵循常规流。并且设置top
,right
,bottom
,left
这4个属性进行偏移时,不会影响常规流中的任何元素。
绝对定位,脱离常规流。此时偏移属性参照的是离自身最近的定位祖先元素,如果没有定位的祖先元素,则一直回溯到body元素。
盒子的偏移位置不影响常规流中的任何元素,其margin不与其他任何margin折叠(触发BFC)。
固定定位,脱离常规流。与absolute一致,但偏移定位是以窗口为参考。当出现滚动条时,对象不会随着滚动。
粘性定位,该定位基于用户滚动的位置。
在常态时,它的行为就像 position:relative
,遵循常规流。
当页面滚动超出目标区域时,它的表现就像 position:fixed
,它会固定在目标位置, 脱离常规流。
从父元素继承 position 属性的值。
display: none | block | inline-block | table | inline-table | flex | inline-flex | grid | inline-grid | inherit
display: table-captoion | table-cell | table-row | table-row-group | table-column | table-column-group | table-header-group | table-footer-group
此元素会作为一个表格标题显示(类似 <caption>)
此元素会作为一个或多个行的分组来显示(类似 <thead>)
此元素会作为一个或多个行的分组来显示(类似 <tfoot>)
此元素会作为一个表格单元格显示(类似 <td> 和 <th>)
此元素会作为一个表格行显示(类似 <tr>)
此元素会作为一个或多个行的分组来显示(类似 <tbody>)
此元素会作为一个单元格列显示(类似 <col>)
此元素会作为一个或多个列的分组来显示(类似 <colgroup>)
display: list-item | run-in
此元素会作为列表显示
此元素会根据上下文作为块级元素或内联元素显示
两者都能让元素不可见。区别在于:
display: none;
,会让元素完全从渲染树中消失,渲染时不占据任何空间。visibility: hidden;
,元素仍存在渲染树中,渲染时仍占据空间,只是内容不可见。display: none;
是非继承属性,子孙节点消失是由于元素从渲染树中消失造成,通过改变子孙节点的display属性无法改变显示状态。visibility: hidden;
是继承属性,子孙节点消失是由于继承hidden属性,通过设置visible
属性可以让子孙节点显示。display
属性通常会引起文档重排。修改visibility
属性只会造成元素的重绘。display: none;
元素内容,但是会读取visibibity: hidden;
元素内容。visibility: hidden;
该属性隐藏元素,单元素在文档流中仍占据空间。display: none;
元素不可见,并且在文档流中不占据空间。opacity: 0;
CSS3属性,设置0可以让元素透明。filter: blur(0);
CSS3属性,将一个元素的模糊度设置为0,从而让元素消失“”在页面上。position: absolute;
设置left值负值定位,使元素在可视范围内。transform: scale(0);
将元素设置无限缩小,元素不可见,元素所在位置被保留。height: 0;
将元素高度设置为0,并消除边框。<div hidden="hidden"></div>
HTML5属性,效果与display: hidden;一样。但这个属性用于记录一个元素的状态。BFC
(Block Formatting Context)即“块级格式化上下文”。常规流(也称标准流、普通流)是一个文档在被显示时最常见的布局形态。一个框在常规流中必须属于一个格式化上下文,你可以把BFC想象成一个大箱子,箱子外边的元素将不与箱子内的元素产生作用。BFC
是W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。比如浮动元素会形成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。也可以说BFC就是一个作用范围。具体特性解释,可移步至CSS中的BFC详解
FOUC:Flash of Unstyled Content,简称为FOUC
,文档样式短暂失效(又称浏览器样式闪烁)。
如果使用import
方法对CSS
进行导入,会导致某些页面在Windows 下的Internet Explorer出现一些奇怪的现象:以无样式显示页面内容的瞬间闪烁。这种现象称之为文档样式短暂失效(Flash of Unstyled Content)
,简称为FOUC
。
import
方法导入样式表原理:当样式表晚于结构性html
加载,当加载到此样式表时,页面将停止之前的渲染。此样式表被下载和解析后,将重新渲染页面,也就出现了短暂的花屏现象。
link
标签将样式表放在文档head
中外边距重叠: margin-collapse
垂直相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。 这种合并外边距的方式被称为折叠,结合而成的外边距称为折叠外边距。更详细介绍可移步至:CSS 框模型( Box module )
<div style="width:50px; height:50px; margin-bottom:50px; background-color: red;">A</div> <!-- 重点: margin-bottom:50px; --> <div style="width:50px; height:50px; margin-top:100px; background-color: green;">B</div> <!-- 重点: margin-top:100px; -->
在 margin
都是正数的情况下,取其中 margin 较大的值为最终 margin 值
示意图:
<div style="width:50px; height:50px; margin-bottom:-75px; background-color: red;">A</div> <!-- 重点: margin-bottom:-75px; --> <div style="width:50px; height:50px; margin-top:-50px; background-color: green;">B</div> <!-- 重点: margin-top:-50px; -->
在 margin
都是负值的时候,取的是其中绝对值较大的,然后从零开始,负向位移
示意图:
<div style="width:50px; height:50px; margin-bottom:-50px; background-color: red;">A</div> <!-- 重点: margin-bottom:-50px; --> <div style="width:50px; height:50px; margin-top:100px; background-color: green;">B</div> <!-- 重点: margin-top:100px; -->
在margin
中有正值有负值的时候,要从所有负值中选出绝对值最大的,所有正值中选择绝对值最大的,二者相加。此例的结果即为: 100px + (-50)px =50px;
示意图:
<div style="margin:50px 0; background-color:red; width:50px; height:50px;"> <div style="margin:-60px 0;"> <div style="margin:150px 0;">A</div> </div> </div> <div style="margin:-100px 0; background-color:green; width:50px; height:50px;"> <div style="margin:-120px 0;"> <div style="margin:200px 0;">B</div> </div> </div>
请注意,多个 margin 相邻折叠成一个 margin,所以计算的时候,应该取所有相关的值一起计算,而不能分开分步来算。
以上例子中,A 和 B 之间的 margin 折叠产生的 margin,是6个相邻 margin 折叠的结果。将其 margin 值分为两组:
正值:50px,150px,200px
负值:-60px,-100px,-120px
根据有正有负时的计算规则,正值的最大值为 200px,负值中绝对值最大的是 -120px,所以,最终折叠后的 margin 应该是 200 + (-120) = 80px。
另外,要注意,自身的margin-botom
和margin-top
相邻时也会发生重叠,只有当自身内容为空,垂直方向上border
,padding
,均为0时,自身的margin-top
与margin-bottom
才会相邻。
示例:
<div style="border:1px solid red; width:100px;"> <div style="margin-top: 100px;margin-bottom: 50px;"></div> </div>
以上代码运行后,我们讲得到的是红色边框的正方形,方框的宽高都应该是 100px,高度不应该是 150px。
示意图:
外边距的重叠只产生在普通流文档的垂直外边距之间,避免块级元素之间产生双倍边距的问题。
inline-block
元素、绝对定位元素的 margin
不会和垂直方向上其他元素的 margin
折叠浮动元素的 margin
在垂直方向上也不会发生 margin
折叠,即使和它相邻的子元素也不会。
<div style="margin-bottom:50px; width:50px; height:50px; background-color:green;">A</div> <div style="margin-top:50px; width:100px; height:100px; background-color:green; float:left;"> <div style="margin-top:50px; background-color:gold;">B</div> </div>
示意图:
两个绿色的块儿之间,相距100px,而若 B 和它的浮动包含块发生 margin 折叠的话,金色的条应该位于绿色块的最上方,显然,没有发生折叠。
以 “overflow : hidden
” 的元素为例:
<div style="margin-top:50px; width:100px; height:100px; background-color:green; overflow:hidden;"> <div style="margin-top:50px; background-color:gold;">B</div> </div>
若 B 和它的 "overflow:hidden
" 包含块发生 margin
折叠的话,金色的条应该位于绿色块的最上方,否则,没有发生。
示意图:
非IE浏览器下,容器不设高度且子元素浮动时,容器高度不能被内容撑开。 此时,内容会溢出到容器外面而影响布局。这种现象被称为浮动(溢出)。
如果一个元素要浮动,那么它的父元素一定要有高度。高度的盒子,才能关住浮动。可以通过直接给父元素设置height,实际应用中我们不大可能给所有的盒子加高度,不仅麻烦,并且不能适应页面的快速变化;另外一种,父容器的高度可以通过内容撑开(比如img图片),实际当中此方法用的比较多。
在最后一个子元素新添加最后一个冗余元素,然后将其设置clear:both,这样就可以清除浮动。这里强调一点,即在父级元素末尾添加的元素必须是一个块级元素,否则无法撑起父级元素高度。
<style> #wrap{ border: 1px solid; } #inner{ float: left; width: 200px; height: 200px; background: pink; } </style> <div id="wrap"> <div id="inner"></div> <div style="clear: both;"></div> </div>
上面那种办法固然可以清除浮动,但是我们不想在页面中添加这些没有意义的冗余元素,此时如何清除浮动吗?
结合 :after 伪元素和 IEhack ,可以完美兼容当前主流的各大浏览器,这里的 IEhack 指的是触发 hasLayout。
<style> #wrap { border: 1px solid; } #inner { float: left; width: 200px; height: 200px; background: pink; } .clearfix { *zoom: 1; } /*ie6 7 不支持伪元素*/ .clearfix:after { content: ''; display: block; clear: both; height: 0; line-height: 0; visibility: hidden; /*允许浏览器渲染它,但是不显示出来*/ } </style> <div id="wrap" class="clearfix"> <div id="inner"></div> </div>
这种方案让父容器形成了BFC(块级格式上下文),而BFC可以包含浮动,通常用来解决浮动父元素高度坍塌的问题。
hasLayout
,清除浮动。zoom
属性是IE浏览器
的专有属性,它可以设置或检索对象的缩放比例。解决ie下比较奇葩的bug。譬如外边距(margin)的重叠,浮动清除,触发ie的haslayout属性等。zoom
的值之后,所设置的元素就会就会扩大或者缩小,高度宽度就会重新计算了,这里一旦改变zoom
值时其实也会发生重新渲染,运用这个原理,也就解决了ie下子元素浮动时候父元素不随着自动扩大的问题。zoom
属是IE浏览器
的专有属性,火狐和老版本的webkit核心的浏览器都不支持这个属性。然而,zoom
现在已经被逐步标准化,出现在CSS 3.0
规范草案中。scale
进行缩放。@import
是CSS
提供的语法规则,只有导入CSS的作用。link
是HTML提供的标签,不仅可以加载 CSS
文件,还可以定义 RSS
、rel
连接属性等。
@import
是CSS2.1的语法,只有在IE5+
才能识别;link
标签作为html
元素,不存在兼容性问题。
加载页面时,link
标签引入的CSS
能被并行加载;@import
引入的CSS
将在页面加载完毕后才加载。
可以通过JS操作DOM,插入link
标签来改变样式;而无法通过JS添加@import
方式来引入样式。
link
引入的样式权重大于@import
引入的样式。
px
,是相对长度单位,它是相对于显示器屏幕分辨率而言的。
优缺点:比较稳定和精确,但在浏览器中放大或缩放浏览页面时会出现页面混乱的情况。
em
,是相对长度单位,em
是相对于父元素来设计字体大小的。如果当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。
优缺点:em
的值并不是固定的,它会继承父级元素的字体大小。
px
和em
的之间的相互转换:任意浏览器的默认字体高都是16px。所有未经调整的浏览器都符合:1em=16px。那么,12px=0.75em,10px=0.625em。
为了使用方便,用em
时,我们通常在CSS
中的body
选择器中声明font-size=62.5%(使em值变为:16px*62.5%=10px),之后,你只需要将你使用的px值除以10,即可得到em值,如:12px=1.2em,10px=1em。
rem是CSS3
新增的一个相对单位,rem
是相对单位,是相对html
根元素。
这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。
目前,除了IE8
及更早版本外,所有浏览器均已支持rem
。
两者都是通过重置样式,保持浏览器样式的一致性。区别在于:
css reset
通过为几乎所有的元素施加默认样式,强行使得元素有相同的视觉效果。相比之下,normailze.css
保持了许多磨人的浏览器样式。这就意味着你不用再为所有公共的排版元素重新设置样式。当一个元素在不同的浏览器中有不同的默认值时,normalize.css
会力求让这些样式保持一致并尽可能与现代标准符合。
它修复了常见的桌面端与移动端浏览器的bug。这往往超出了reset所能做到的范围。关于这一点,normalize.css
修复的问题包含了HTML5
元素的显示设置、预格式化文字的font-size
问题、在IE9
中SVG
的溢出、许多出现在各浏览器和操作系统中的与表单相关的bug。
使用reset css
最让人困扰的地方莫过于在浏览器调试工具中大段大段的继承链,在normalize.css
中就不会有这样的问题,因为在我们的准则中对多选择器的使用是非常谨慎的,我们仅会有目的地对目标元素设置样式。
这个项目已经被拆分为多个相关却又独立的部分,这使得你能够很容易也很清楚地知道哪些元素被设置了特定的值。因此这能让你自己选择性地移除掉某些永远不会用到的部分(比如表单的一般化)。
normalize.css
的代码基于详细而全面的跨浏览器研究与测试。这个文件中拥有详细的代码说明并在Github Wiki中有进一步的说明。这意味着你可以找到每一行代码具体完成了什么工作、为什么要写这句代码、浏览器之间的差异,并且你可以更容易的进行自己的测试。
将多个小图标he拼接到一张图片里,通过background-position
和元素尺寸调节需要显示的背景图案。
CSS继承
,减少代码体积@import
引入CSS
,建议使用link
, 因为后者在页面加载时一起加载,前者是等待页面加载完成之后再进行加载CSS sprite
,减少图片体积的同时,减少HTTP
请求CSS选择符
是从右到左进行匹配的。当使用后代选择器的时候,浏览器会遍历所有子元素来确定是否是指定的元素等等
css reset
,可以选择normolize.cssCSS express
0
时,不加单位(优化)0.**
时,可以省略小数点前的0
(优化)CSS
文件放在页面最上面CSS
代码定义到独立CSS
文件中这部分涉及内容较多,请移步至浏览器的回流和重绘及其优化方式
background-color: blue;background-color: yellow;<input type="button" value="变蓝" @click="changeColorT