知识点梳理
- 选择器的权重和优先级
- 盒模型
- 盒⼦⼤⼩计算
- margin 的重叠计算
- 浮动
float
- 浮动布局概念
- 清理浮动
- 定位
position
- ⽂档流概念
- 定位分类
- fixed 定位特点
- 绝对定位计算⽅式
flex
布局- 如何实现居中对⻬?
- 理解语义化
CSS3
动画- 重绘和回流
选择器的权重和优先级
CSS 选择器有很多, 不同的选择器的权重和优先级不⼀样, 对于⼀个元素, 如果存在多个选择器, 那 么就需要根据权重来计算其优先级。
权重分为四级,分别是:
- 代表内联样式,如
style="xxx"
,权值为1000
- 代表
ID
选择器, 如#content
,权值为100
; - 代表类、伪类和属性选择器,如
.content
、:hover
、[attribute]
,权值为10
- 代表元素选择器和伪元素选择器,如
div
、p
,权值为1
需要注意的是: 通⽤选择器(*) 、⼦选择器 ( > ) 和相邻同胞选择器 ( + ) 并不在这四个等级中, 所 以他们的权值都为 0。 权重值⼤的选择器其优先级也⾼, 相同权重的优先级⼜遵循后定义覆盖前⾯定 义的情况。
盒模型
什么是"盒子"
⼀开始学 CSS 基础知识的时候⼀定学过 padding
border
和 margin
,即内边 距、边框和外边距。它们三者就构成了⼀个“ 盒⼦ ” 。 就像我们收到的快递, 本来买了⼀部⼩⼩的⼿ 机, 收到的却是那么⼤⼀个盒⼦。因为⼿机⽩⾊的包装盒和⼿机机器之间有间隔层( 内边距),⼿机 ⽩⾊盒⼦有厚度,虽然很薄 (边框),盒⼦和快递箱⼦之间还有⼀层泡沫板(外边距)。这就是⼀个 典型的盒⼦。
题⽬: 盒⼦模型的宽度如何计算
题⽬: 盒⼦模型的宽度如何计算
```html
```
⽂字内容的宽度 刚好是 300px , 也就是我们设置的宽度。
因此,在盒⼦模型中, 我们设置的宽度都是内容宽度, 不是整个盒⼦的宽度。 ⽽整个盒⼦的宽度是:(内容宽度
+ border
宽度 + padding
宽度 + margin
宽度) 之和 。 这样我们改四个中的其中⼀ 个, 都会导致盒⼦宽度的改变。这对我们来说不友好。
没关系, 这个东⻄不友好早就有⼈发现了,⽽且已经解决。
充满⽗容器的盒⼦
默认情况下,div
是 display:block
,宽度会充满整个⽗容器。如下图: ```html
```
但是别忘记,这个div是个盒⼦模型,它的整个宽度包括(内容宽度+border宽度
+padding宽度
+margin宽度
),整个的宽度充满⽗容器。
问题就在这⾥。如果⽗容器宽度不变,我们⼿动增⼤margin
、border
或 padding
其中⼀项的宽度值,都会导致内容宽度的减少。极端情况下,如果内容的宽度压缩到不能再压缩了(例如⼀个字的宽度),那么浏览器会强迫增加⽗容器的宽度。这可不是我们想要看到的。
包裹内容的盒⼦
这种情况下⽐较简单,内容的宽度按照内容计算,盒⼦的宽度将在内容宽度的基础上再增加(padding
宽度+border
宽度+margin
宽度)之和。
```html
```
box-sizing:border-box
前⾯提到,为盒⼦模型设置宽度,结果只是设置了内容的宽度,这个不合理。如何解决这⼀问题?答案就是为盒⼦指定样式:box-sizing:border-box
。
```html
```
上图中,为div设置了box-sizing:border-box
之后,300px的宽度是内容+padding+边框的宽度(不包括margin),这样就⽐较符合我们的实际要求了。建议⼤家在为系统写CSS时候,第⼀个样式是:
css * { box-sizing: border-box; }
⼤名鼎鼎的Bootstrap也把box-sizing:border-box
加⼊到它的*
选择器中,我们为什么不这样做呢?
纵向margin重叠
这⾥提到margin,就不得不提⼀下margin的这⼀特性——纵向重叠。如<p>
的纵向margin是16px,那么两个<p>
之间纵向的距离是多少?——按常理来说应该是16 + 16 = 32px,但是答案仍然是16px。因为纵向的margin是会重叠的,如果两者不⼀样⼤的话,⼤的会把⼩的“吃掉”。
浮动float
float⽤于⽹⻚布局⽐较多,使⽤起来也⽐较简单,总结了⼀些⽐较重要、需要注意的知识点。
误解和误用
float被设计出来的初衷是⽤于⽂字环绕效果,即⼀个图⽚⼀段⽂字,图⽚float:left
之后,⽂字会环绕图⽚。
```html
![](img/xxx.jpg)
```
但是,后来⼤家发现结合float + div
可以实现之前通过table实现的⽹⻚布局,因此就被“误⽤”于⽹⻚布局了。
题目:为何 float 会导致父元素塌陷?
破坏性
float的破坏性——float破坏了⽗标签的原本结构,使得⽗标签出现了坍塌现象。导致这⼀现象的最根本原因在于:被设置了float的元素会脱离⽂档流。其根本原因在于float的设计初衷是解决⽂字环绕图⽚的问题。
包裹性
包裹性也是float的⼀个⾮常重要的特性,⼤家⽤float时⼀定要熟知这⼀特性。如果给div增float:left
之后,它突然变得紧凑了,宽度发⽣了变化,把内容中的三个字包裹了——这就是包裹性。为div设置了float之后,其宽度会⾃动调整为包裹住内容宽度,⽽不是撑满整个⽗容器。注意,此时div虽然体现了包裹性,但是它的display样式是没有变化的,还是display: block
。float为什么要具有包裹性?其实答案还是得从float的设计初衷来寻找,float是被设计⽤于实现⽂字环绕效果的。⽂字环绕图⽚⽐较好理解,但是如果想要让⽂字环绕⼀个div呢?此时div不被“包裹”起来的话,就⽆法实现环绕效果了。
清空格float
还有⼀个可能不是很熟悉的特性——清空格。
```html
![](1.jpg)
![](2.jpg)
![](3.jpg)
![](4.jpg)
```
加上float:left
之后:
上⾯第⼀张图中,正常的img中间是会有空格的,因为多个img标签会有换⾏,⽽浏览器识别换⾏为空格,这也是很正常的。第⼆张图中,为img增加了float:left
的样式,这就使得img之间没有了空格,4个img紧紧挨着。
如果⼤家之前没注意,现在想想之前写过的程序,是不是有这个特性。为什么float适合⽤于⽹⻚排版(俗称“砌砖头”)?就是因为float排版出来的⽹⻚严丝合缝,中间连个苍蝇都⻜不进去。
“清空格”这⼀特性的根本原因是float会导致节点脱离⽂档流结构。它都不属于⽂档流结构了,那么它身边的什么换⾏、空格就都和它没了关系,它就尽量往⼀边靠拢,能靠多近就靠多近,这就是清空格的本质。
⽬:⼿写clearfix
clearfix
清除浮动的影响,⼀般使⽤的样式如下,统称clearfix
代码。所有float元素的⽗容器,⼀般情况下都应该加clearfix
这个class。
css .clearfix:after { content: ''; display: table; clear: both; } .clearfix { /* 兼容 IE 低版本 */ *zoom : 1; }
```html
![](1.jpg)
![](2.jpg)
```
小结
float的设计初衷是解决⽂字环绕图⽚的问题,后来误打误撞⽤于做布局,因此有许多不合适或者需要注意的地⽅。
圣杯布局 ```html
我是中间
我是左边
我是右边
```
双飞翼布局 ```html
```
定位position
position⽤于⽹⻚元素的定位,可设置static/relative/absolute/fixed这些值,其中static是默认值。
题⽬:relative和absolute有何区别?
relative
相对定位relative可以⽤⼀个例⼦很轻松地演示出来。
然后我们在第三个<p>
上⾯,加上position:relative
并且设置left和top值,看这个<p>
有什么变化。
```html
第一段文字
第一段文字
第一段文字
第一段文字
```
上图中,⼤家应该要识别出两个信息(相信⼤部分⼈会忽略第⼆个信息)
- 第三个
<p>
发⽣了位置变化,分别向右向下移动了10px
; - 其他的三个
<p>
位置没有发⽣变化,这⼀点也很重要。
relative会导致⾃身位置的相对变化,⽽不会影响其他元素的位置、⼤⼩。 这是relative的要点之⼀。还有第⼆个要点,就是relative产⽣⼀个新的定位上下⽂。
absolute
先写⼀个基本的demo。
```html
第一段文字
第一段文字
第一段文字
第一段文字
```
然后,我们把第三个<p>
改为position:absolute;
,看看会发⽣什么变化。
从上⾯的结果中,我们能看出⼏点信息:
absolute元素脱离了⽂档结构。和
relative
不同,其他三个元素的位置重新排列了。只要元素会脱离⽂档结构,它就会产⽣破坏性,导致⽗元素坍塌。(此时你应该能⽴刻想起来,float元素也会脱离⽂档结构。)absolute元素具有“包裹性”。之前
<p>
的宽度是撑满整个屏幕的,⽽此时<p>
的宽度刚好是内容的宽度。absolute元素具有“跟随性”。虽然absolute元素脱离了⽂档结构,但是它的位置并没有发⽣变化,还是⽼⽼实实地呆在它原本的位置,因为我们此时没有设置top、left的值。absolute元素会悬浮在⻚⾯上⽅,会遮挡住下⽅的⻚⾯内容。
最后,通过给absolute元素设置top
、left
值,可⾃定义其内容,这个都是平时⽐较常⽤的了。这⾥需要注意的是,设置了top、left值时,元素是相对于最近的定位上下⽂来定位的,⽽不是相对于浏览器定位。
fixed
其实fixed和absolute是⼀样的,唯⼀的区别在于:absolute元素是根据最近的定位上下⽂确定位置,⽽fixed根据window(或者iframe)确定位置。
题⽬:relative、absolute和fixed分别依据谁来定位?
定位上下文
relative元素的定位永远是相对于元素⾃身位置的,和其他元素没关系,也不会影响其他元素。
fixed元素的定位是相对于window(或者iframe)边界的,和其他元素没有关系。但是它具有破坏性,会导致其他元素位置的变化。
absolute的定位相对于前两者要复杂许多。如果为absolute设置了top、left,浏览器会根据什么去确定它的纵向和横向的偏移量呢?答案是浏览器会递归查找该元素的所有⽗元素,如果找到⼀个设置了position:relative/absolute/fixed
的元素,就以该元素为基准定位,如果没找到,就以浏览器边界定位。
flex
布局
布局的传统解决⽅案基于盒⼦模型,依赖display属性+position属性+float属性。它对于那些特殊布局⾮常不⽅便,⽐如,垂直居中就不容易实现。在⽬前主流的移动端⻚⾯中,使⽤flex布局能更好地完成需求。
基本使用
任何一个容器都可以使用flex布局,代码也很简单,强烈建议学习!!
注意,第三个
```html
```
设计原理
设置了display: flex
的元素,我们称为“容器”(flex container),其所有的⼦节点我们称为“成员”(flex item)。容器默认存在两根轴:⽔平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。项⽬默认沿主轴排列。单个项⽬占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
将以上⽂字和图⽚结合起来,再详细看⼀遍,这样就能理解flex的设计原理,才能更好地实际使⽤。
设置主轴的⽅向
flex-direction
可决定主轴的⽅向,有四个可选值: + row(默认值):主轴为⽔平⽅向,起点在左端。 + row-reverse:主轴为⽔平⽅向,起点在右端。 + column:主轴为垂直⽅向,起点在上沿。 + column-reverse:主轴为垂直⽅向,起点在下沿。
css .box { flex-direction: column-reverse | cocolumn | row | row-reverse; }
设置主轴的对⻬⽅式
justify-content
属性定义了项⽬在主轴上的对⻬⽅式,值如下: + flex-start(默认值):向主轴开始⽅向对⻬。 + flex-end:向主轴结束⽅向对⻬。 + center:居中。space-between:两端对⻬,项⽬之间的间隔都相等。 + space-around:每个项⽬两侧的间隔相等。所以,项⽬之间的间隔⽐项⽬与边框的间隔⼤⼀倍。
css .box { justify-content: flex-start | flex-end | center | space-between |space-around; }
交叉轴的对⻬⽅式
align-items
属性定义项⽬在交叉轴上如何对⻬,值如下:
- flex-start:交叉轴的起点对⻬。
- flex-end:交叉轴的终点对⻬。
- center:交叉轴的中点对⻬。
- baseline:项⽬的第⼀⾏⽂字的基线对⻬。
- stretch(默认值):如果项⽬未设置⾼度或设为auto,将占满整个容器的⾼度。
css .box {align-items: flex-start | flex-end | center | baseline | stretch;}
如何实现居中对⻬?
题⽬:如何实现⽔平居中?
⽔平居中
inline元素⽤text-align: center;
即可,如下: css .container { text-align: center; }
block元素可使⽤margin: auto;
,PC时代的很多⽹站都这么搞。
css .container { text-align: center; } .item { position: relative; width: 500px; }
垂直居中
inline元素可设置line-height
的值等于height值,如单⾏⽂字垂直居中: css .container { height: 50px; line-height: 50; }
绝对定位元素,可结合left
和margin
实现,但是必须知道尺⼨。 + 优点:兼容性好 + 缺点:需要提前知道尺⼨
css .container { position: relative; height: 200px; } .item { width: 80px; height: 40px; position: absolute; left: 50%; top: 50%; margin-top: -20px; margin-left: -40px; }
绝对定位可结合transform
实现居中。
- 优点:不需要提前知道尺⼨
- 缺点:兼容性不好
css .container { position: relative; height: 200px; } .item { width: 80px; height: 40px; position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); background: blue; }
绝对定位结合margin: auto
,不需要提前知道尺⼨,兼容性好。
css .container { position: relative; height: 3px; } .item { width: 100px; height: 300px; position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; }
其他的解决⽅案还有,不过没必要掌握太多..
理解语义化
题⽬:如何理解HTML语义化?
所谓“语义”就是为了更易读懂,这要分两部分: + 让⼈(写程序、读程序)更易读懂 + 让机器(浏览器、搜索引擎)更易读懂
让⼈更易读懂
对于⼈来说,代码可读性、语义化就是⼀个⾮常⼴泛的概念了,例如定义JS变量的时候使⽤更易读懂的名称,定义CSS class的时候也⼀样,例如lengthlist等,⽽不是使⽤ab这种谁都看不懂的名称。
不过我们平常考查的“语义化”并不会考查这么⼴义、这么泛的问题,⽽是考查HTML的语义化,是为了更好地让机器读懂HTML。
让机器更易读懂
HTML符合XML标准,但⼜和XML不⼀样—— HTML不允许像XML那样⾃定义标签名称,HTML有⾃⼰规定的标签名称。问题就在这⾥—— HTML为何要⾃⼰规定那么多标签名称呢,例如p div h1 ul
等——就是为了语义化。其实,如果你精通CSS的话,你完全可以全部⽤
拿搜索引擎来说,爬⾍下载到我们⽹⻚的HTML代码,它如何更好地去理解⽹⻚的内容呢?——就是根据HTML既定的标签。h1
标签就代表是标题;p
⾥⾯的就是段落详细内容,权重肯定没有标题⾼;ul
⾥⾯就是列表;strong
就是加粗的强调的内容……如果我们不按照HTML语义化来写,全部都⽤<div>
标签,那搜索引擎将很难理解我们⽹⻚的内容。
为了加强HTML语义化,HTML5标准中⼜增加了header section article
等标签。因此,书写HTML时,语义化是⾮常重要的,否则W3C也没必要⾟⾟苦苦制定出这些标准来。
CSS3动画
CSS3可以实现动画,代替原来的Flash和JavaScript⽅案。
⾸先,使⽤@keyframes
定义⼀个动画,名称为testAnimation
,如下代码,通过百分⽐来设置不同的CSS样式,规定动画的变化。所有的动画变化都可以这么定义出来。
css @keyframes testAnimation { 0% {background: red; ;left: 0; top: 0} 25% {background: green; ;left: 200px; top: 0} 50% {background: blue; ;left: 200px; top: 200px} 75% {background: yellow; ;left: 0; top: 200px} 100% {background: pink; ;left: 0; top: 0} }
然后,针对⼀个CSS选择器来设置动画,例如针对div元素设置动画,如下:
```css div { width: 100px; height: 50px; position: absolute;
animation-name: myfrist;
animation-duration: 5s;
} ```
animation-name
对应到动画名称,animation-duration
是动画时⻓,还有其他属性:
- animation-timing-function:规定动画的速度曲线。默认是ease
- animation-delay:规定动画何时开始。默认是0
- animation-iteration-count:规定动画被播放的次数。默认是1
- animation-direction:规定动画是否在下⼀周期逆向地播放。默认是normal
- animation-play-state:规定动画是否正在运⾏或暂停。默认是running
- animation-fill-mode:规定动画执⾏之前和之后如何给动画的⽬标应⽤,默认是none,保留在最后⼀帧可以⽤
forwards
题⽬:CSS的
transition
和animation
有何区别?
⾸先transition
和animation
都可以做动效,从语义上来理解,transition是过渡,由⼀个状态过渡到另⼀个状态,⽐如⾼度100px过渡到200px;⽽animation是动画,即更专业做动效的,animation有帧
的概念,可以设置关键帧keyframe
nimation是动画,即更专业做动效的,animation有帧的概念,可以设置关键帧keyframe
,⼀个动画可以由多个关键帧多个状态过渡组成,另外animation也包含上⾯提到的多个属性。
重绘和回流
重绘和回流是⾯试题经常考的题⽬,也是性能优化当中应该注意的点。
重绘:指的是当⻚⾯中的元素不脱离⽂档流,⽽简单地进⾏样式的变化,⽐如修改颜⾊、背景等,浏览器重新绘制样式
回流:指的是处于⽂档流中DOM的尺⼨⼤⼩、位置或者某些属性发⽣变化时,导致浏览器重新渲染部分或全部⽂档的情况
相⽐之下,回流要⽐重绘消耗性能开⽀更⼤。另外,⼀些属性的读取也会引起回流,⽐如读取某个DOM的⾼度和宽度,或者使⽤getComputedStyle⽅法。在写代码的时候要避免回流和重绘。
题⽬:找出下⾯代码的优化点,并且优化它
js var data = ['string1', 'string2', 'string3'] for (var i=0; i < data.length; i++){ var dom = document.getElementById('list') dom.innerHTML += '<li>' + data[i] + '</li>' }
上⾯的代码在循环中每次都获取dom
,然后对其内部的HTML进⾏累加li,每次都会操作DOM结构,可以改成使⽤documentFragment
或者先遍历组成HTML的字符串,最后操作⼀次innerHTML
。
小结
总结了CSS和HTML常考的知识点,包括CSS中⽐较重要的定位、布局的知识,也介绍了⼀些CSS3的知识点概念和题⽬,以及HTML的语义化。