引入方式
CSS 引入方式有4种 内联、内嵌、外链、导入
通过link 和@import 引入的区别:
- 外链 link 除了可以加载css 之外,还可以定义rss、rel 等属性,是XHTML 标签,没有兼容性问题,支持使用javascript 改变样式
- 导入
@import是css 提供的,只能用于加载css,不支持通过javascript 修改样式 - 页面被加载的时候,link 会被同时加载,而@import 则需等到页面加载完后再加载,可能出现无样式网页
- link 方式的样式的权重高于@import 的权重
【不建议使用内联样式】
- 样式不能复用
- 权重太高,不好覆盖
- 表现层与结构层没有分离
- 不能进行缓存,影响加载效率
【不建议使用@import】
- 导入样式,只能放在 style 标签/css文件的第一行(
charset规则下方也可),放其他行则会无效 - @import 声明的样式表不能充分利用浏览器并发请求资源的行为(link 标签引入的文件会并发请求),其加载行为会在页面全部被加载后才被加载 => CSS 解析延迟 => 阻塞 JS 解析
- 由于 @import 样式表的 延后加载,可能会导致页面样式闪烁
选择器
种类
-
标签选择器/元素选择器 (h1)
-
id 选择器
-
类选择器 (class )
-
通配符选择器(*)
-
后代选择器(li a)
-
子代选择器(ul > li)
-
分组/群组选择器
-
相邻选择器
- 直接相邻元素选择器 (h1 + p)
- 普通相邻元素选择器 (h2 ~ h2)
-
属性选择器(a[rel = "XXX"])
-
伪类选择器(a:link/visited/hover/active :first-child);结构伪类选择器(CSS3:nth-child(n)、nth-of-type(n) );否定伪类选择器(not)
-
伪元素选择器( :before :after …)
【常见选择器用法】
相邻兄弟选择器(+) - 可选择紧接在另一元素后的元素,且二者有相同父元素。特殊情况:循环多个。
h2+p { color: #000; }
兄弟选择器(-),又称匹配选择器 - 查找某一个指定元素的后面的所有兄弟节点。
子选择器(>) - 只能选择作为某元素子元素的元素(直接子元素),不包括孙元素,曾孙元素等。
:first-child - 选择属于其父元素的首个子元素的指定选择器。
E:first-child // 只要E元素是它的父级的第一个子元素就选中。第一个子元素,且这个子元素刚好是E。
:nth-child(n) - 该选择器选取父元素的第N 个子元素,与类型无关。
:nth-of-type(n) - 选择器匹配属于父元素的特定类型的第N个子元素的每个元素,与元素类型有关。
优先级
优先级由高到低 !important > 内联style > ID选择器 > 类选择器 > 标签选择器 > 通配符选择器>继承
优先级算法(权重)
-
元素选择符的权值
- 元素标签(派生选择器)、伪元素:1
- class 选择符、属性选择器、伪类:10
- id 选择符:100
- 内联样式:1000
-
当两个样式都使用
!important时,权重值大的优先级更高 -
如果
!important被用于一个简写的样式属性,那么这条简写的样式属性所代表的子属性都会被应用上!important -
继承得到的样式的优先级最低(0)
-
比较多个权重相同的CSS 选择器优先级,定义的位置决定一切。从位置上由高到低分为六级:
0、内联样式 1、位于<head/>标签里的<style/>中所定义的CSS(内部样式) 2、位于 <style/>标签中的 @import 引入样式表所定义 3、由<link/>标签所引入的样式表定义 4、由<link/>标签所引入的样式表内的 @import 导入样式表定义 5、用户设定 6、浏览器默认 -
同位置情况下样式定义最近者为准(优先级相同,选择最后出现的样式)
继承
CSS 继承特性主要是文本方面。
所有元素可继承:visibility cursor
块级元素可继承:text-indent text-align
列表元素可继承:list-style list-style-type list-style-position list-style-image
内联元素可继承:letter-spacing word-spacing line-height color font font-family font-size font-style font-variant font-weight text-decoration text-transform direction
伪类和伪元素
- 静态伪类(只用于a 标签)
- 动态伪类
【伪类和伪元素的区别】
它们是否创造了新的元素(抽象) 。
如果需要添加新元素加以标识的,就是伪元素,反之,如果只需要在既有元素上添加类别的,就是伪类。
伪元素:在内容元素的前后插入额外的元素或样式,但是这些元素实际上并不在文档中生成。它们只在外部显示可见,但不会在文档的源代码中找到它们,因此称为“伪”元素。
伪类:像真正的类一样发挥着类的作用,没有数量上的限制,只要不是相互排斥的伪类,也可以同时使用在相同的元素上。
伪类用一个冒号表示,伪元素则使用两个冒号表示(为了向下兼容,现在的浏览器中伪元素选择器用单冒号和双冒号都可以)。
CSS 盒模型
怪异模式 => 怪异盒模型
- width = border + padding + content
- 一个盒子的宽度 = width + margin
标准模式 => 标准盒模型
- width = content width
- 一个盒子真正的宽度 = width + 左右padding + 左右border + 左右margin
标准模式:浏览器按照W3C 标准解析执行代码
怪异模式:浏览器根据自己的方式解析执行代码,因为不同浏览器解析执行方式不一样,所以叫怪异模式
【区别】
图片元素的垂直对齐方式对于行内元素和table-cell 元素,标准模式下vertical-align 属性默认值是baseline;而在怪异模式下,table 单元格中的图片的vertical-align 属性默认值是bottom,因此在图片底部会有几像素的空间。
CSS 中的font 的属性都是可以继承的,在怪异模式下,对于table 元素,字体的某些元素不能从其他封装元素继承中得到,特别是font-size 属性。
内联元素的尺寸:标准模式下,non-replaced inline 元素无法自定义大些,怪异模式下,定义元素的宽高会影响元素的尺寸。
元素的百分比高度:当一个元素使用百分比高度时,在标准模式下,高度取决于内容变化,在怪异模式下,百分比会被准确应用。
元素溢出的处理:标准模式下,overflow 取值默认值为visible;在怪异模式下,这个溢出会被当作扩展box 对待,就是元素的大小由内容决定,溢出不会裁剪,元素框自动调整,包含溢出内容。
转换盒模型
CSS 中默认的盒模型是W3C 盒模型,两者间的转换可以通过设置属性box-sizing 来转换
box-sizing: content-box // W3C 盒模型标准
box-sizing: border-box // IE 盒模型标准
盒子相关高度
- clientWidth = width + 左右padding
- offsetWidth = width + 左右padding + 左右boder
- scrollWidth:获取指定标签内容层的真实宽度(可视区域宽度 + 被隐藏区域宽度)
边界重叠
CSS 中存在margin collapsing,即边界塌陷或者外边距合并。
In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.
Adjoining vertical margins collapse, except:
- Margins of the root element's box do not collapse.
- If the top and bottom margins of an element with clearance are adjoining, its margins collapse with the adjoining margins of following siblings but that resulting margin does not collapse with the bottom margin of the parent block.
只有普通文档流中块框的垂直外边距才会发生外边距合并。行内框、浮动框或绝对定位之间的外边距不会合并。
-
块级元素的垂直方向边界塌陷:
对于上下两个并排的 div 块而言,上面 div 的 margin-bottom 和下面 div 的 margin-top 会塌陷。
两个相邻的外边距都是正数时,取较大值;两个相邻的外边距都是负数时,取两者绝对值的较大值;两个外边距一正一负时,取两者相加值。
-
包含元素盒子塌陷:
父级div 中没有border,padding,line boxes,clearance,子级div 的margin 会一直向上找,直到找到某个标签包括border,padding,line boxes,clearance中的其中一个,然后按此div 进行margin。
高度塌陷
当父元素没设置足够大小的时候,而子元素设置了浮动的属性,子元素就会跳出父元素的边界(脱离文档流),尤其是当父元素的高度为auto 时,而父元素中又没有其它非浮动的可见元素时,父盒子的高度就会直接塌陷为0,即 CSS 高度塌陷。
【方法】
1、最简单直接的方法:给父元素单独定义高度
优点:快速简单,代码少
缺点:无法进行响应式布局
2、父级定义overflow: hidden
优点:简单快速、代码少,兼容性高
缺点:超出部分被隐藏,可能会带来内容不可见的问题,布局时要注意
overflow: auto 也行,但内部高度超过父级div 时会出现滚动条
3、在浮动元素后面加一个空标签(div/br/hr):{ clear: both; }
优点:简单快速、代码少,兼容性高
缺点:增加空标签,不利于页面优化
4、after 伪元素(推荐方法)
外部盒子的 after 伪元素设置 clear 属性。
/* 对于低版本 IE 不兼容,具体选择哪种解决方法,可以根据实际情况决定。 */
#parent:after{
clear: both;
content: "";
width: 0;
height: 0;
display: block;
visibility: hidden;
}
clear 属性只有块级元素才有效的,而 ::after 等伪元素默认都是内联,这就是借助伪元素清除浮动影响时需要设置 display 属性值的原因。
CSS 的content 属性专门应用在before/after 伪元素上,用于来插入生成内容。最常见的应用是清除浮动。
BFC(块级格式上下文)
它是一个独立的渲染区域,只有Block-level box 参与,它规定了内部的Block-level Box 如何布局,并且与外部毫不相干。
W3C 对BFC 的定义如下: 浮动元素和绝对定位元素,非块级盒子的块级容器(例如
inline-blocks(内联块), table-cells(表单元格),和table-captions(表标题)),以及overflow 值不为visiable的块级盒子,都会为他们的内容创建新的BFC。
三代布局技术:
正常流
-
Block formatting context(BFC)
- Block container => block-level box
-
Inline formatting context(IFC)
- Line box => inline-level box
- 水平居中:当一个块要在环境中水平居中时,设置其为inline-block 则会在外层产生IFC,通过text-align 则可以使其水平居中。
- 垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align: middle,其他行内元素则可以在此父元素下垂直居中。
弹性布局
-
Flex formatting context(FFC)
- Flex container => flex item
网格布局
-
Grid formatting context(GFC)
- Grid container => grid item
establish 条件
一个HTML 元素要创建BFC,则满足下列的任意一个或多个条件即可(下列方式会创建块格式化上下文)
- 根元素
- 浮动元素(元素的 float 不是 none)
- 绝对定位元素(包含position 为 fixed或sticky)
- 行内块元素(元素的 display 为 inline-block)
- 表格单元格或使用display: table-cell,包括使用display: table-* 属性的所有表格单元格
- 表格标题或使用display: table-caption 的元素
- 块级元素的overflow 属性不为 visible 的块元素
- 元素属性为 display: flow-root 或display: flow-root list-item
- 弹性元素(display为 flex 或 inline-flex元素的直接子元素)
- 网格布局元素(display为 grid 或 inline-grid 元素的直接子元素)
BFC 渲染规则
- 内部的Box 会在垂直方向一个接一个地放置(即块级元素独占一行)
- BFC 的区域不会与浮动元素的box 重叠(两栏式布局)
- Box 垂直方向的距离由margin 决定。属于同一个BFC 的两个相邻Box 的margin 会发生重叠
- 计算BFC 高度的时候浮动元素也会参与计算
- BFC 是一个独立的容器,外面的元素不会影响里面的元素
应用场景
自适应两栏布局
一个左浮动的div,一个是有很多文字的div,正常情况下,文字会围绕浮动元素布局。可以给右边的div 加上overflow: hidden,建立一个BFC 形成自适应两栏布局。
清除内部浮动
<div class="container">
<div class="inner"></div>
</div>
.container {
border: 10px solid red;
}
.inner {
background: #08BDEB;
height: 100px;
width: 100px;
}
// 将inner元素设为浮动,此时container 高度坍塌
.inner {
float: left;
background: #08BDEB;
height: 100px;
width: 100px;
}
// 对父元素设置BFC 可解决坍塌问题,这也是清除浮动的一种方式
.container {
border: 10px solid red;
overflow: hidden;
}
避免外边距折叠
两个块同属于一个BFC 会造成外边距折叠,但如果对这两个块分别设置BFC,那么边距重叠的问题就不存在了。
// 此时三个元素的上下间隔都是10px, 因为三个元素同属于一个BFC
<div class="container">
<div class="inner">1</div>
<div class="inner">2</div>
<div class="inner">3</div>
</div>
.container {
background-color: green;
overflow: hidden;
}
.inner {
background-color: lightblue;
margin: 10px 0;
}
// 此时2 与1 和3 的边距都是20px
<div class="container">
<div class="inner">1</div>
<div class="bfc">
<div class="inner">2</div>
</div>
<div class="inner">3</div>
</div>
.bfc{
overflow: hidden;
}
上下相邻盒子的margin 会重叠
<section class="wrap">
<div class="content1">conten1</div>
<div class="content2">conten2</div>
</section>
/* 解决方案父盒子 flex */
/* 父盒子给 overflow:hidden 是没有用的,BFC也存在相邻盒子外边距合并的现象 */
.wrap {
display: flex;
flex-direction: column;
}
.content1 {
width: 150px;
height: 150px;
margin-bottom: 50px;
background-color: #0D90FC;
}
.content2 {
width: 200px;
height: 200px;
margin-top: 100px;
background-color: #2DCB56;
}
When two or more margins collapse, the resulting margin width is the maximum of the collapsing margins' widths. In the case of negative margins, the maximum of the absolute values of the negative adjoining margins is deducted from the maximum of the positive adjoining margins. If there are no positive margins, the maximum of the absolute values of the adjoining margins is deducted from zero.
IFC
- 内部的盒子一个接着一个地排列,起点是包含块的顶点。
- 如果一行放不下内容,那么会被“拆”开放到下一行。
- 只有水平方向上的 Margin 会在盒子中保留。
- Padding 和 Border 不会撑开行高。