一、盒模型
元素的内在盒子是由margin box、border box、padding box、content box组成的,这四个盒子由外到内构成了盒模型。
- content-box,默认值,只计算内容的宽度,border和padding不计算入width之内
- padding-box,padding计算入宽度内
- border-box,border和padding计算入宽度之内
二、CSS基础
1、 CSS 有哪些样式可以给子元素继承!
- 可继承的:
font-size,font-weight,line-height,color,cursor等 - 不可继承的一般是会改变盒子模型的:
display,margin、border、padding、height等
更加全面的可以到引擎找
2、 行内元素有哪些?块级元素有哪些? 空(void)元素有那些?
块级元素是指单独撑满一行的元素,如div、ul、li、table、p、h1等元素。这些元素的display值默认是block、table、list-item等。
内联元素又叫行内元素,指只占据它对应标签的边框所包含的空间的元素,这些元素如果父元素宽度足够则并排在一行显示的,如span、a、em、i、img、td等。这些元素的display值默认是inline、inline-block、inline-table、table-cell等。
实际开发中,我们经常把display计算值为inline inline-block inline-table table-cell的元素叫做内联元素,而把display计算值为block的元素叫做块级元素。
3、width: auto 和 height: auto
width、height的默认值都是auto。
对于块级元素,流体布局之下width: auto自适应撑满父元素宽度。这里的撑满并不同于width: 100%的固定宽度,而是像水一样能够根据margin不同而自适应父元素的宽度。
对于内联元素,width: auto则呈现出包裹性,即由子元素的宽度决定。
无论内联元素还是块级元素,height: auto都是呈现包裹性,即高度由子级元素撑开。
注意父元素height: auto会导致子元素height: 100%百分比失效。
css的属性非常有意思,正常流下,如果块级元素的width是个固定值,margin是auto,则margin会撑满剩下的空间;如果margin是固定值,width是auto,则width会撑满剩下的空间。这就是流体布局的根本所在。
4、消除图片底部间隙的方法
- 图片块状化 - 无基线对齐:
img { display: block; } - 图片底线对齐:
img { vertical-align: bottom; } - 行高足够小 - 基线位置上移:
.box { line-height: 0; }
5、层叠上下文
层叠上下文好像是一个结界,层叠上下文内的元素如果跟层叠上下文外的元素发生层叠,则比较该层叠上下文和外部元素的层叠上下文的层叠水平高低。
创建一个层叠上下文的方法就是给position值为relative/aboslute/fixed的元素设置z-index不为auto的值。
三、CSS3特性
1、CSS 中transition和animate有何区别? animate 如何停留在最后一帧!
这种问题见仁见智,我的回答大体是这样的..待我捋捋.
transition一般用来做过渡的, 没时间轴的概念, 通过事件触发(一次),没中间状态(只有开始和结束)
而animate则是做动效,有时间轴的概念(帧可控),可以重复触发和有中间状态;
过渡的开销比动效小,前者一般用于交互居多,后者用于活动页居多;
至于如何让animate停留在最后一帧也好办,就它自身参数的一个值就可以了
2、word-spacing 空格间隙
不要被表面意思误导,word-spacing指的是字符“空格”的间隙。如果一段文字中没有空格,则该属性无效。下面代码设定空格间隙是20px,也就是说空格现在占据的宽度是原有的空格宽度+20px的宽度:
<p>我有空 格,我该死......</p>
<style>
p {
word-spacing: 20px;
}
</style>
复制代码
3、white-space 空白处理
我们都知道如果在html中输入多个空白符,默认会被当成一个空白符处理,实际上就是这个属性控制的:地址
- normal:合并空白符和换行符;
- nowrap:合并空白符,但不许换行;
- pre:不合并空白符,并且只在有换行符的地方换行;
- pre-wrap:不合并空白符,允许换行符换行和文本自动换行;
四、CSS选择器及其优先级
1、CSS选择器
- !important
- 内联样式style=""
- ID选择器#id
- 类选择器/属性选择器/伪类选择器.class.active[href=""]
- 元素选择器/关系选择器/伪元素选择器html+div>span::after
- 通配符选择器*
2、权重值和选择器
- 1,0,0,0 内联样式:style=""
- 0,1,0,0 ID选择器:
#idName{...} - 0,0,1,0 类、伪类、属性选择器:
.className{...}/:hover{...}/[type="text"] ={...} - 0,0,0,1 标签、伪元素选择器:
div{...}/:after{...} - 0,0,0,0 通用选择器(*)、子选择器(>)、相邻选择器(+)、同胞选择器(~)
当两个权值进行比较的时候,是从高到低逐级将等级位上的权重值来进行比较的,而不是 1000个数 + 100个数 + 10个数 + 1个数 的总和来进行比较的,换句话说,低等级的选择器个数再多也不会超过高等级的选择器的优先级的。
3、!important的权重最高
如果出现了!important,则不管权重如何都取有!important的属性值。但是宽高有例外情况,由于宽高会被max-width/min-width覆盖,所以!important会失效。
4、 !important问题
超越!important:max-width会覆盖width,而且这种覆盖是超级覆盖,比!important的权重还要高
超越最大:min-width覆盖max-width,此规则发生在min-width和max-width冲突的时候,如下:
.container{
min-width:1400px;
max-width:1200px;
}
5、面试题举例
// 假设下面样式都作用于同一个节点元素`span`,判断下面哪个样式会生效
body#god div.dad span.son {width: 200px;}
body#god span#test {width: 250px;}
因此上面那道的面试题比较应该是在第二等级id选择器的比较就结束了:(#god + #test = 0,2,0,0) > (#god = 0,1,0,0);而上图种例子中两个权重分别是:(#test = 0,1,0,0) > (.test....test10 = 0,0,11,0),也是在第二等级id选择器的比较时就结束了。所以以后比较权重,就先比较id选择器个数,如果id一样多,再比较class选择器个数。
五、BFC
BFC(Block Formatting Context)格式化上下文,是Web页面中盒模型布局的CSS渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。
BFC应用
- 防止margin重叠
- 清除内部浮动
- 自适应两(多)栏布局
- 防止字体环绕
触发BFC条件
- 根元素
- float的值不为none
- overflow的值不为visible
- display的值为inline-block、table-cell、table-caption
- position的值为absolute、fixed
BFC的特性
-
内部的Box会在垂直方向上一个接一个的放置。
-
垂直方向上的距离由margin决定
-
bfc的区域不会与float的元素区域重叠。
-
计算bfc的高度时,浮动元素也参与计算
-
bfc就是页面上的一个独立容器,容器里面的子元素不会影响外面元素。
六、水平居中
1、行内元素
.parent {
text-align: center;
}
2、块级元素
.son {
margin: 0 auto;
}
3、flex布局
.parent {
display: flex;
justify-content: center;
}
4、绝对定位定宽
.son {
position: absolute;
width: 宽度;
left: 50%;
margin-left: -0.5*宽度
}
5、绝对定位不定宽
.son {
position: absolute;
left: 50%;
transform: translate(-50%, 0);
}
6、left/right: 0
.son {
position: absolute;
width: 宽度;
left: 0;
right: 0;
margin: 0 auto;
}
七、垂直居中
1、行内元素
.parent {
height: 高度;
}
.son {
line-height: 高度;
}
2、table
.parent {
display: table;
}
.son {
display: table-cell;
vertical-align: middle;
}
3、flex
.parent {
display: flex;
align-items: center;
}
4、绝对定位定高
.son {
position: absolute;
top: 50%;
height: 高度;
margin-top: -0.5高度;
}
5、绝对定位不定高
.son {
position: absolute;
top: 50%;
transform: translate( 0, -50%);
}
6、top/bottom: 0;
.son {
position: absolute;
height: 高度;
top: 0;
bottom: 0;
margin: auto 0;
}
八、CSS 引入的方式有哪些? link 和@import 的区别是?
有四种:内联(元素上的style属性)、内嵌(style标签)、外链(link)、导入(@import) link和@import的区别:
-
link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。 -
link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。 -
link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。 -
link支持使用Javascript控制DOM去改变样式;而@import不支持。
九、flex布局
父项常用属性
- flex-direction:设置主轴的方向
- justify-content:设置主轴上的子元素排列方式
- flex-wrap:设置子元素是否换行
- align-content:设置侧轴上的子元素的排列方式(多行)
- align-items:设置侧轴上的子元素排列方式(单行)
- flex-flow:复合属性,相当于同时设置了 flex-direction 和 flex-wrap
flex-direction
在 flex 布局中,是分为主轴和侧轴两个方向,同样的叫法有 : 行和列、x 轴和y 轴
- 默认主轴方向就是 x 轴方向,水平向右
- 默认侧轴方向就是 y 轴方向,水平向下
: 主轴和侧轴是会变化的,就看 flex-direction 设置谁为主轴,剩下的就是侧轴。而我们的子元素是跟着主轴来排列的
flex-wrap设置是否换行
- 默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,flex布局中默认是不换行的。
- nowrap 不换行
- wrap 换行
justify-content 设置主轴上的子元素排列方式
效果图
: 这里讲下
space-around和space-evenly
- space-around:项目之间的间距为左右两侧项目到容器间距的2倍。
- space-evenly:项目两侧之间的间距与项目与容器两侧的间距相等,相当于除去项目宽度和容器和项目的两侧间距,剩下的平均分配了剩余宽度作为项目左右margin。
**设置侧轴上的子元素排列方式:align-items(单行)/align-content(多行) **
上图写能
设置多行只能用于子项出现 换行 的情况(多行),在单行下是没有效果的。
效果跟上面是一样的只不过是方向换了,上面是元素在主轴上排列,这个是在侧抽上,至于侧轴是不是Y轴就看你的flex-direciton怎么设置的了
子项常见属性
- flex(复合属性): 默认: flex: 0 1 auto;
- flex-grow
- flex-shrink
- flex-basis
- align-self:控制子项自己在侧轴的排列方式
- order:定义子项的排列顺序(前后顺序), 0是第一个
flex-grow
默认0,用于决定项目在有剩余空间的情况下是否放大,默认不放大;注意,即便设置了固定宽度,也会放大。
假设第一个项目默认为0,第二个项目为flex-grow:2,最后一个项目为1,则第二个项目在放大时所占空间是最后项目的两倍。
可以这么理解:
-
flex: 1 => 在剩余的空间里我就占一份
-
flex: 2 => 在剩余的空间里我就占两份
-
flex: 3 => 在剩余的空间里我就占三份
假设三个盒子分别都设置了上面的属性: 那就将剩余空间分成6份, 各占自己的份数
假设前两个没有设置, 就最后一个设置了flex: 3 === flex: 1, 那就将剩余空间都给它 复制代码
flex-shrink
默认1,用于决定项目在空间不足时是否缩小,默认项目都是1,即空间不足时大家一起等比缩小;注意,即便设置了固定宽度,也会缩小。但如果某个项目flex-shrink设置为0,则即便空间不够,自身也不缩小。
上图中第二个项目flex-shrink为0,所以自身不会缩小。
flex-basis
默认auto,用于设置项目宽度,默认auto时,项目会保持默认宽度,或者以width为自身的宽度,但如果设置了flex-basis,权重会width属性高,因此会覆盖widtn属性。
上图中先设置了flex-basis属性,后设置了width属性,但宽度依旧以flex-basis属性为准。
注意⚠: 如果当容器中有多个盒子并且还宽度100%, flex-basis会被影响, 如下图
解决办法就是在我们设置flex-basis宽度时, 最好给他设置flex-shrink为0不缩放
十、grid布局
最强大的 CSS 布局 —— Grid 布局 (juejin.cn)
十一、让元素消失
visibility:hidden、display:none、z-index=-1、opacity:0
-
opacity:0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定了一些事件,如click事件也能触发
-
visibility:hidden,该元素隐藏起来了,但不会改变页面布局,但是不会触发该元素已经绑定的事件
-
display:none, 把元素隐藏起来,并且会改变页面布局,可以理解成在页面中把该元素删掉
-
z-index=-1置于其他元素下面
十二、清除浮动
-
在浮动元素后面添加
clear:both的空 div 元素,<div class="container"> <div class="left"></div> <div class="right"></div> <div style="clear:both"></div> </div> -
给父元素添加
overflow:hidden或者 auto 样式,触发BFC。<div class="container"> <div class="left"></div> <div class="right"></div> </div>.container{ width: 300px; background-color: #aaa; overflow:hidden; zoom:1; /*IE6*/ } -
使用伪元素,也是在元素末尾添加一个点并带有 clear: both 属性的元素实现的。
<div class="container clearfix"> <div class="left"></div> <div class="right"></div> </div>.clearfix{ zoom: 1; /*IE6*/ } .clearfix:after{ content: "."; height: 0; clear: both; display: block; visibility: hidden; }
推荐使用第三种方法,不会在页面新增div,文档结构更加清晰。
十三、calc函数
calc函数是css3新增的功能,可以使用calc()计算border、margin、pading、font-size和width等属性设置动态值。
#div1 {
position: absolute;
left: 50px;
width: calc( 100% / (100px * 2) );
//兼容写法
width: -moz-calc( 100% / (100px * 2) );
width: -webkit-calc( 100% / (100px * 2) );
border: 1px solid black;
}
注意点:
-
需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);
-
calc()函数支持 "+", "-", "*", "/" 运算;
-
对于不支持 calc() 的浏览器,整个属性值表达式将被忽略。不过我们可以对那些不支持 calc()的浏览器,使用一个固定值作为回退。
十四、两边宽度固定中间自适应的三栏布局
圣杯布局和双飞翼布局是前端工程师需要日常掌握的重要布局方式。两者的功能相同,都是为了实现一个两侧宽度固定,中间宽度自适应的三栏布局。
圣杯布局
<style>
body{
min-width: 550px;
}
#container{
padding-left: 200px;
padding-right: 150px;
}
#container .column{
float: left;
}
#center{
width: 100%;
}
#left{
width: 200px;
margin-left: -100%;
position: relative;
right: 200px;
}
#right{
width: 150px;
margin-right: -150px;
}
</style>
<div id="container">
<div id="center" class="column">center</div>
<div id="left" class="column">left</div>
<div id="right" class="column">right</div>
</div>
双飞翼布局
<style>
body {
min-width: 500px;
}
#container {
width: 100%;
}
.column {
float: left;
}
#center {
margin-left: 200px;
margin-right: 150px;
}
#left {
width: 200px;
margin-left: -100%;
}
#right {
width: 150px;
margin-left: -150px;
}
</style>
<div id="container" class="column">
<div id="center">center</div>
</div>
<div id="left" class="column">left</div>
<div id="right" class="column">right</div>
十五、伪类和伪元素
1、伪类
伪类存在的意义是为了通过选择器找到那些不存在DOM树中的信息以及不能被常规CSS选择器获取到的信息。
- 获取不存在与DOM树中的信息。比如a标签的:link、visited等,这些信息不存在与DOM树结构中,只能通过CSS选择器来获取;
- 获取不能被常规CSS选择器获取的信息。比如:要获取第一个子元素,我们无法用常规的CSS选择器获取,但可以通过 :first-child 来获取到。
2、伪元素
伪元素用于创建一些不在文档树中的元素,并为其添加样式。比如说,我们可以通过:before来在一个元素前增加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。常见的伪元素有:::before,::after,::first-line,::first-letter,::selection、::placeholder等
因此,伪类与伪元素的区别在于:有没有创建一个文档树之外的元素。
3、::after和:after的区别
在实际的开发工作中,我们会看到有人把伪元素写成:after,这实际是 CSS2 与 CSS3新旧标准的规定不同而导致的。
CSS2 中的伪元素使用1个冒号,在 CSS3 中,为了区分伪类和伪元素,规定伪元素使用2个冒号。所以,对于 CSS2 标准的老伪元素,比如:first-line,:first-letter,:before,:after,写一个冒号浏览器也能识别,但对于 CSS3 标准的新伪元素,比如::selection,就必须写2个冒号了。
4、基于伪元素的图片内容生成技术
需求:图片还没加载时就把 alt 信息呈现出来。
实现:图片没有 src ,因此,::before和::after 可以生效,我们可以通过 content 属性呈现 alt 属性值。
img::after{
/* 生成 alt 信息 */
content: attr(alt);
/* 尺寸和定位 */
postion:absolute; bottom: 0;
width:100%;
background-color:rgba(0,0,0,.5);
transform: translateY(100%);
transition: transform .2s;
}
img:hover::after{
transform: translateY(0);
}
当我们给图片添加src 属性时图片从普通元素变成替换元素,原本还支持的::before和::after 此时全部无效,此时再hover图片,是不会有任何信息出现的。
5、 轻松实现hover图片变成另外一张图片
img:hover{
content: url(laugh-tear.png);
}
复制代码
content 改变的仅仅是视觉呈现,当我们鼠标右键或其他形式保存这张图片时,所保存的还是原来 src 对应的图片。这种方法还可以用在官网标志上。
由于使用 conetnt 生成图片无法设置图片的尺寸,要想在移动端使用该技术,建议使用SVG图片
十六、流式布局与响应式布局的区别
流式布局 使用非固定像素来定义网页内容,也就是百分比布局,通过盒子的宽度设置成百分比来根据屏幕的宽度来进 行伸缩,不受固定像素的限制,内容向两侧填充。
响应式开发 利用CSS3 中的 Media Query(媒介查询),通过查询 screen 的宽度来指定某个宽度区间的网页布局。
- 超小屏幕(移动设备) 768px 以下
- 小屏设备 768px-992px
- 中等屏幕 992px-1200px
- 宽屏设备 1200px 以上
由于响应式开发显得繁琐些,一般使用第三方响应式框架来完成,比如 bootstrap 来完成一部分工作,当然也 可以自己写响应式
十七、回流和重绘
回流 比如我们增删DOM节点,修改一个元素的宽高,页面布局发生变化,DOM树结构发生变化,那么肯定要重新构建DOM树,而DOM树与渲染树是紧密相连的。DOM树构建完,渲染树也随之对页面再次渲染,这个过程就叫回流。(结构会变)
导致回流的操作:
- 页面首次渲染
- 浏览器窗口大小发生变化
- 元素尺寸发生改变(包括外边距、内边距、边框大小、高度和宽度)
- 元素的位置发生变化
- 元素内容变化(文字数量或图片大小等等)
- 元素字体大小变化
重绘 当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。(结构不变,样式改变)
十八、Sass常用的用法
(1)变量
SASS允许使用变量,所有变量以$开头。
/* 变量声明 */
$fontStack: Helvetica, sans-serif;
$primaryColor: #333;
body {
font-family: $fontStack;
color: $primaryColor;
}
等同于css的写法
body {
font-family: Helvetica, sans-serif;
color: #333;
}
如果变量需要镶嵌在字符串之中,就必须需要写在#{}之中。
$side : left;
#div1 {
margin-#{left}:10px;
}
(2)计算功能
SASS允许在代码中使用算式:
.div2 {
margin: 10px * 2;
padding:(14px / 2);
}
等同于css的写法
.div2 {
margin: 20px;
padding: 7px;
}
(3)嵌套
SASS允许选择器嵌套。比如:
-
选择器嵌套
nav { ul { margin: 0; padding: 0; list-style: none; } li { display: inline-block; } }
等同于css的写法
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav li {
display: inline-block;
}
复制代码
- &的嵌套
在嵌套的代码块内,可以使用&引用父元素。比如a:hover伪类,可以写成:
a {
margin: 10px;
&:hover {
color: #000;
}
}
等同于css的写法
a {
margin: 10px;
}
a:hover {
color: #000;
}
- 属性嵌套(很少用,或者说不用,因为这样写更麻烦)
属性也可以嵌套,比如border-color属性,可以写成:
p{
border: { //注意,border后面必须加上冒号。
color: #000;
}
}
//转化css后
p{
border-color: #000;
}
复制代码
(4)继承
SASS允许一个选择器,继承另一个选择器。比如,现有div3:
.div3 {
margin: 2px;
}
/* .div4继承.div3 */
.div4 {
@extend .div3;
font-size: 10px;
}
等同于css的写法
.div3, .div4 {
margin: 2px;
}
.div4 {
font-size: 10px;
}
(5)Mixin
Mixin有点像C语言的宏(macro),是可以重用的代码块。
-
1、使用@mixin命令,定义一个代码块
-
2、后续可以通过
@include复用@mixin p1 { float: left; } div { /*使用@include命令,调用这个mixin。*/ @include p1; top: 10px; }
等同于css的写法
div {
float: left;
top: 10px;
}
mixin的强大之处,在于可以指定参数和缺省值。这样我们就可以复用一些样式,只需要传递一个参数,就像调用一个函数一样!
-
例子1: 没有默认值
@mixin box-sizing ($sizing) { -webkit-box-sizing:$sizing; -moz-box-sizing:$sizing; box-sizing:$sizing; } .box-border{ border:1px solid #ccc; @include box-sizing(border-box);/*引用*/ }
等同于css的写法
.box-border {
border: 1px solid #ccc;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
-
例子2:有默认值;没有默认值的参数要放在参数列表的前面。
@mixin p2($val1, $val2:20px) { /* 如果不加入参数,就用默认参数 */ float: $val1; top: $val2; } //使用的时候,根据需要加入参数: div { @include p2(left); }
等同于css的写法
div {
float: left;
top: 20px;
}
(6)导入文件
-
@import命令,用来插入外部文件。
-
如果插入的是.css文件,则等同于css的import命令。
@import "path/filename.scss"; @import "foo.css";
(7)注释
SASS共有两种注释风格。
- 标准的CSS注释 /* comment */ ,会保留到编译后的文件。
- 单行注释 // comment,只保留在SASS源文件中,编译后被省略。