前端面试·CSS

1,818 阅读17分钟

关于面试中的一些CSS问题,问题合集请看前端小白的面试问题集

1.CSS样式的优先级

  • CSS 优先规则1: 最近的祖先样式比其他祖先样式优先级高;
  • CSS 优先规则2:"直接样式"比"祖先样式"优先级高;
  • CSS 优先规则3:优先级关系:内联样式 > ID 选择器 > 类选择器 = 属性选择器 = 伪类选择器 > 标签选择器 = 伪元素选择器
  • CSS 优先规则4:计算规则 选择器的特殊性值分为四个等级,如下:
    (1)标签内选择符x,0,0,0
    (2)ID选择符0,x,0,0
    (3)class选择符/属性选择符/伪类选择符 0,0,x,0
    (4)元素和伪元素选择符0,0,0,x
    计算方法:
    (1)每个等级的初始值为0
    (2)每个等级的叠加为选择器出现的次数相加
    (3)不可进位,比如0,99,99,99
    (4)依次表示为:0,0,0,0
    (5)每个等级计数之间没关联
    (6)等级判断从左向右,如果某一位数值相同,则判断下一位数值
    (7)如果两个优先级相同,则最后出现的优先级高,!important也适用
    (8)通配符选择器的特殊性值为:0,0,0,0
    (9)继承样式优先级最低,通配符样式优先级高于继承样式
    (10)!important(权重),它没有特殊性值,但它的优先级是最高的,为了方便记忆,可以认为它的特殊性值为1,0,0,0,0。
    CSS计数规则 计算实例:
    (1)#demoa{color:orange;}/特殊性值:0,1,0,1/
    (2)div#demoa{color:red;}/特殊性值:0,1,0,2/

2.CSS有哪些布局方法?

  • 固定布局
    宽度,高度固定,页面被一个固定网页包裹,容器不能移动,页面的宽高不随页面的变化而变化,这种布局大家比较熟悉,这种方式一度成为页面布局的主流方式,这样布局设计简单,更容易定义,但是由于屏幕尺寸的不同,特别是移动端各个设备的不同,这种布局在灵活性方式可用度不高。
  • 流式布局
    以百分比为主要形式,让屏幕自适应,这种布局方式定义灵活,能够根据屏幕的情况变化,但是这种方式设计的效果不太容易控制,一般移动端结合rem用的比较多,pc端用的不是非常多
  • 弹性布局
    浮动部分和清楚浮动部分主要是兼容添加的一些代码,重点看弹性布局的部分,弹性布局相对前两种出现的比较晚些,但是弹性布局功能还是很强大的,布局也非常方便,但是此布局形式在pc端并不推荐使用,ie9以下浏览器均不支持,另外火狐等一些浏览器也需要做兼容,移动端目前绝大部分浏览器都已经支持弹性布局,在移动端大家可以尝试使用。
  • 浮动布局
    浮动布局关键词,float,可以设置left或者right,他使元素脱离文档流进而达到布局的目的,也是目前一个比较主流的布局方式,但是使用浮动的结束以后,别忘记清除浮动哦。
  • 定位布局
    定位布局也是目前比较常用的一种布局方式,关键词:position: fixed;固定布局,将元素固定在一个位置,不随页面移动而移动,position: relative;相对定位,相对于元素自身定位,不脱离文档流,相当于定义一个参照物,一般和绝对定位结合使用,position: absolute;绝对定位,脱离文档流,一般和相对定位结合使用,如果不定义相对定义,将会相对于整个浏览器定位,所以定位布局,一般情况下都是相对定位和绝对定位结合着来,相当定位相当于划定一个势力范围,制定一个封闭的容器块,然后绝对定位就行对于相对定位来定位,从而达到有效的布局。

3.如何实现垂直水平居中?

一般常见的几种居中的方法有:

对于宽高固定的元素

(1)我们可以利用margin:0 auto来实现元素的水平居中。

(2)利用绝对定位,设置四个方向的值都为0,并将margin设置为auto,由于宽高固定,因此对应方向实现平分,可以实现水 平和垂直方向上的居中。

(3)利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过margin负值来调整元素的中心点到页面的中心。

(4)利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过translate来调整元素的中心点到页面的中心。

(5)使用flex布局,通过align-items:center和justify-content:center设置容器的垂直和水平方向上为居中对 齐,然后它的子元素也可以实现垂直和水平的居中。

对于宽高不定的元素

(1)可以使用flex布局实现水平垂直居中

(2)利用table,在父元素设置display:table;

子元素设置:display:table-cell;vertical-align:middle;

(3)移动端用:-webkit-transform: translate3d(-50%,-50%,0);

4.说一说flex布局

flex布局是CSS3新增的一种布局方式,我们可以通过将一个元素的display属性值设置为flex从而使它成为一个flex 容器,它的所有子元素都会成为它的项目。

一个容器默认有两条轴,一个是水平的主轴,一个是与主轴垂直的交叉轴。我们可以使用flex-direction来指定主轴的方向。 我们可以使用justify-content来指定元素在主轴上的排列方式,使用align-items来指定元素在交叉轴上的排列方式。还 可以使用flex-wrap来规定当一行排列不下时的换行方式。

对于容器中的项目,我们可以使用order属性来指定项目的排列顺序,还可以使用flex-grow来指定当排列空间有剩余的时候, 项目的放大比例。还可以使用flex-shrink来指定当排列空间不足时,项目的缩小比例。

5.做过哪些移动端适配?

目前只做过h5的一些移动端简单适配,比如弹性布局、ui框架里根据不同屏幕大小进行不同的网格划分。

6.IE的盒模型是什么,标准的盒模型是什么,如何转换?

盒模型都是由四个部分组成的,分别是margin、border、padding和content。

标准盒模型和IE盒模型的区别在于设置width和height时,所对应的范围不同。标准盒模型的width和height属性的 范围只包含了content,而IE盒模型的width和height属性的范围包含了border、padding和content。

一般来说,我们可以通过修改元素的box-sizing属性来改变元素的盒模型。

7.rem,em,px的区别是什么?

px:绝对单位,页面按精确像素展示。

em:相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算(浏览器默认字体是16px),整个页面内1em不是一个固定的值。

rem:相对单位,可理解为”root em”, 相对根节点html的字体大小来计算,CSS3新加属性,chrome/firefox/IE9+支持。

  • px特点:

IE无法调整那些使用px作为单位的7a64e4b893e5b19e31333366306431字体大小;

国外的大部分网站能够调整的原因在于其使用了em或rem作为字体单位;

Firefox能够调整px和em,rem,但是96%以上的中国网民使用IE浏览器(或内核)。

  • em特点 :

em的值并不是固定的;

em会继承父级元素的字体大小。

  • rem特点:

rem是CSS3新增的一个相对单位(root em,根em),这个单位引起了广泛关注。区别在于使用rem为元素设定字体大小时,仍然是相对大小,但相对的只是HTML根元素。

这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。

目前,除了IE8及更早版本外,所有浏览器均已支持rem。对于不支持它的浏览器,应对方法也很简单,就是多写一个绝对单位的声明。这些浏览器会忽略用rem设定的字体大小。

8.如何实现三列布局?

三栏布局一般指的是页面中一共有三栏,左右两栏宽度固定,中间自适应的布局,一共有五种实现方式。

这里以左边宽度固定为100px,右边宽度固定为200px为例。

(1)利用绝对定位的方式,左右两栏设置为绝对定位,中间设置对应方向大小的margin的值。

.left{
    position: absolute;
    left: 0;
    width: 300px;
    background-color: red;
}
.center{
    position: absolute;
    left: 300px;
    right: 300px;
    background-color: blue;
}
.right{
    position: absolute;
    right: 0;
    width: 300px;
    background-color: #3A2CAC;
}

(2)利用flex布局的方式,左右两栏的放大和缩小比例都设置为0,基础大小设置为固定的大小,中间一栏设置为auto。

.main {
    display: flex;
}
.left{
    width: 400px;
    background-color: red;
}
.center{
    background-color: blue;
    word-break: break-word;
}
.right{
    background-color: red;
    width: 400px;
}

(3)利用浮动的方式,左右两栏设置固定大小,并设置对应方向的浮动。中间一栏设置左右两个方向的margin值,注意这种方式,中间一栏必须放到最后。

.left{
    float: left;
    width: 300px;
    height: 100px;
    background: #631D9F;
}
.right{
    float: right;
    width: 300px;
    height: 100px;
    background: red;
}
.center{
    margin-left: 300px;
    margin-right: 300px;
    background-color: #4990E2;
}

(4)圣杯布局,利用浮动和负边距来实现。父级元素设置左右的padding,三列均设置向左浮动,中间一列放在最前面,宽度设置为父级元素的宽度,因此后面两列都被挤到了下一行,通过设置margin负值将其移动到上一行,再利用相对定位,定位到两边。圣杯布局中间列的宽度不能小于两边任意列的宽度,而双飞翼布局则不存在这个问题。

#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; 
}

(5)双飞翼布局,双飞翼布局相对于圣杯布局来说,左右位置的保留是通过中间列的margin值来实现的,而不是通过父元素的pedding来实现的。本质上来说,也是通过浮动和外边距负值来实现的。

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;
}
        
#footer {
  clear: both;
}

9.CSS3有哪些新特性?

详情参看:个人总结(CSS3新特性)
1.过渡 2.动画 3.形状转换 4.选择器 5.阴影 6.边框 7.背景 8.反射 9.文字 10.颜色
11.渐变 12.滤镜 13.弹性布局 14.栅格布局 15.多列布局 16.盒模型定义 17.媒体查询 18.混合模式

10.CSS3动画

CSS3动画属性animation和CSS3的transition属性一样是一个复合属性,它包含了8个属性:
animation-name,主要用来指定一个关键帧动画的名字,这个动画名必须对应一个@keyframes规则。CSS加载时会应用animation-name指定的动画, 从而执行动画。
animation-duration,主要用来设置动画播放所需时间,一般以秒为单位。
animation-timing- function主要用来设置动画的播放方式,与transition-timing-function类似。
animation-delay、主要用来指定动画开始时间,一般以秒为单位。
animation-iteration- count、主要用来指定动画播放的循环次数。
animation-direction、主要用来指定动画的播放方向。
animation-play- state,主要用来控制动画的播放状态。
animation-fill- mode,主要用来设置动画的时间外属性。

11.CSS3实现loading动画

给一个元素设置宽高相等的数值,border-radius设置成50%使其变成一个圆形,将背景色设置为透明,给元素加上几个像素的边框,并配上自己喜欢的颜色,需要注意的是,这里要将其中一个边的边框设置为透明,使其看起来像是一个只有四分之三的圆环,然后为其设置动画,让它动起来就可以了。给一个定位元素设置transform:translate(-50%, -50%),再配合top和left的50%,可以使元素水平和垂直居中。之所以将translate(-50%, -50%)写在了form和to里面,是因为如果直接在元素上写"transform:translate(-50%, -50%)",在动画里又写"transform: rotate(0deg)"会覆盖掉元素上的transform属性而导致无法居中。 最后在关键帧设置转速:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>css 转圈</title>
  <style>
    .turn{
      width:100px;
      height: 100px;
      background: aqua;
      animation:turn 1s linear infinite;      
      margin: 100px auto;
    }
    /* 
      turn : 定义的动画名称
      1s : 动画时间
      linear : 动画以何种运行轨迹完成一个周期
      infinite :规定动画应该无限次播放
     */
    @keyframes turn{
      0%{-webkit-transform:rotate(0deg);}
      25%{-webkit-transform:rotate(90deg);}
      50%{-webkit-transform:rotate(180deg);}
      75%{-webkit-transform:rotate(270deg);}
      100%{-webkit-transform:rotate(360deg);}
    }
  </style>
</head>
<body>
  <div class="turn"></div>
</body>
</html>

12.display:inline和block的区别?display有哪些值?

  • display:block
    ①block元素会独占一行,多个block元素会各自新起一行。默认情况下,block元素宽度自动填满其父元素宽度。
    ②block元素可以设置width,height属性。块级元素即使设置了宽度,仍然是独占一行。
    ③block元素可以设置margin和padding属性。
  • display:inline
    ①inline元素不会独占一行,多个相邻的行内元素会排列在同一行里,直到一行排列不下,才会新换一行,其宽度随元素的内容而变化。
    ②inline元素设置width,height属性无效
    ③inline元素的margin和padding属性,水平方向的padding-left, padding-right, margin-left, margin-right都产生边距效果;但竖直方向的padding-top, padding-bottom, margin-top, margin-bottom不会产生边距效果
  • display:inline-block
    简单来说就是将对象呈现为inline对象,但是对象的内容作为block对象呈现。之后的内联对象会被排列在同一行内。比如我们可以给一个link(a元素)inline-block属性值,使其既具有block的宽度高度特性又具有inline的同行特性。

13.display:none和visibility:hidden的区别

  • display:none:元素隐藏,会脱离文档流,不占位置,且会引起回流和重绘
  • visibility:hidden:只是隐藏内容,并没有脱离文档流,会占据页面的空间,只会引起重绘

14.flexbox中align-self是做什么用的?

align-items在伸缩容器上使用它,伸缩容器内部所有的元素都一致地受制于align-items的值。 但是有些时候,我们希望伸缩容器内部某个元素在侧轴上的排列方式有所差异。此时就不能使用align-items,因为align-items作用于整体。我们希望作用于部分。这就是align-self的发挥场地。
可取值:align-self:auto|stretch|center|flex-start|flex-end|baseline|initial|inherit;

15.伪类与伪元素有什么区别?

  • 伪类其实是弥补了CSS选择器的不足,用来更方便地获取信息。
//html
<ul>
    <li>11111</li>
    <li>22222</li>
</ul>   
//css
li:first-child {
    color: red;   
}
// 选择器不能直接选取第一个子元素
// 伪类弥补了选择器的不足
  • 伪元素本质上是创建了一个虚拟容器(元素),我们可以在其中添加内容或样式。
//html
<p>
    Hello, World
</p>
//css
p::first-letter {
  color: red;
}
//最终结果:
<p>
    <span class="first-letter">H</span>ello, World
</p>
.first-letter {
  color: red;
}

16.什么是BFC,什么能触发BFC,应用场景

定义:

BFC(Block formatting context) 直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。

触发条件:

1.float的值不为none

2.overflow的值不为visible

3.display的值为table-cell、tabble-caption和inline-block之一

4.position的值不为static或则releative中的任何一个

应用场景:

1.利用BFC避免margin重叠

如果两个行内元素设置margin,会出现margin重叠的问题,如下代码会布置两个margin为30px的元素。

<style>
    p {
        color: #f55;
        background: yellow;
        width: 200px;
        line-height: 100px;
        text-align:center;
        margin: 30px;
    }
</style>
<body>
    <p>看看我的 margin是多少</p>
    <p>看看我的 margin是多少</p>
</body>
</html>

但将其中一个元素用bfc包裹,则两个元素的margin为60px。

<style>
    p {
        color: #f55;
        background: yellow;
        width: 200px;
        line-height: 100px;
        text-align:center;
        margin: 30px;
    }
    div{
        overflow: hidden;
    }
</style>
<body>
    <p>看看我的 margin是多少</p>
    <div>
        <p>看看我的 margin是多少</p>
    </div>
</body>
</html>

2.自适应两栏布局 首先让边栏left脱离文档流,使用流动float,但这样会造成left遮挡right的内容。

<style>
    .left {
        width: 100px;
        height: 150px;
        float: left;
        background: rgb(139, 214, 78);
        text-align: center;
        line-height: 150px;
        font-size: 20px;
    }
 
    .right {
        height: 300px;
        background: rgb(170, 54, 236);
        text-align: center;
        line-height: 300px;
        font-size: 40px;
    }
</style>
<body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
</body>

这时候可以设置right为BFC,BFC的区域不会与float box重叠。

<style>
    .left {
        width: 100px;
        height: 150px;
        float: left;
        background: rgb(139, 214, 78);
        text-align: center;
        line-height: 150px;
        font-size: 20px;
    }
 
    .right {
        overflow: hidden;
        height: 300px;
        background: rgb(170, 54, 236);
        text-align: center;
        line-height: 300px;
        font-size: 40px;
    }
</style>
<body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
</body>

3.清除浮动

  • 额外标签法(在最后一个浮动标签后,新加一个标签,给其设置clear:both;)(不推荐)

    <style>
    .fahter{
        width: 400px;
        border: 1px solid deeppink;
    }
    .big{
        width: 200px;
        height: 200px;
        background: darkorange;
        float: left;
    }
    .small{
        width: 120px;
        height: 120px;
        background: darkmagenta;
        float: left;
    }
    .footer{
        width: 900px;
        height: 100px;
        background: darkslateblue;
    }
    .clear{
        clear:both;
    }
    </style>
<body>
    <div class="fahter">
        <div class="big">big</div>
        <div class="small">small</div>
        <div class="clear">额外标签法</div>
    </div>
    <div class="footer"></div>
  • 父级添加overflow属性(父元素添加overflow:hidden)(不推荐)
 .fahter{
        width: 400px;
        border: 1px solid deeppink;
        overflow: hidden;
    }
  • 使用after伪元素清除浮动(推荐使用)
 .clearfix:after{/*伪元素是行内元素 正常浏览器清除浮动方法*/
        content: "";
        display: block;
        height: 0;
        clear:both;
        visibility: hidden;
    }
    .clearfix{
        *zoom: 1;/*ie6清除浮动的方式 *号只有IE6-IE7执行,其他浏览器不执行*/
    }
 
<body>
    <div class="fahter clearfix">
        <div class="big">big</div>
        <div class="small">small</div>
        <!--<div class="clear">额外标签法</div>-->
    </div>
    <div class="footer"></div>
</body>
  • 使用before和after双伪元素清除浮动(代码更简洁)
 .clearfix:after,.clearfix:before{
        content: "";
        display: table;
    }
    .clearfix:after{
        clear: both;
    }
    .clearfix{
        *zoom: 1;
    }
 
 <div class="fahter clearfix">
        <div class="big">big</div>
        <div class="small">small</div>
    </div>
    <div class="footer"></div>

17.CSS解析顺序

CSS选择器匹配元素是逆向解析

因为所有样式规则可能数量很大,而且绝大多数不会匹配到当前的 DOM 元素(因为数量很大所以一般会建立规则索引树),所以有一个快速的方法来判断「这个 selector 不匹配当前元素」就是极其重要的。

🌰栗子: 如果从【水果】也就是【左】方向开始找,我们就会找3次。但是如果从【橘子】开始找,我们只需要一次就好了。 这是一个最简单的例子,根据这个例子我们也能看出,我们子元素只能有一个父元素,但是父元素可以有一堆子元素,所以还是从子元素,也就是【右】方向找会节约时间。

18.display、visibility和opacity的区别

display: none

  • (1)DOM 结构:浏览器不会渲染 display 属性为 none 的元素,不占据空间;
  • (2)事件监听:无法进行 DOM 事件监听;
  • (3)性能:动态改变此属性时会引起重排,性能较差;
  • (4)继承:不会被子元素继承,毕竟子类也不会被渲染;
  • (5)transition:transition 不支持 display。

visibility: hidden

  • (1)DOM 结构:元素被隐藏,但是会被渲染不会消失,占据空间;
  • (2)事件监听:无法进行 DOM 事件监听;
  • (3)性 能:动态改变此属性时会引起重绘,性能较高;
  • (4)继 承:会被子元素继承,子元素可以通过设置 visibility: visible; 来取消隐藏;
  • (5)transition:transition 支持 visibility。

opacity: 0

  • (1)DOM 结构:透明度为 100%,元素隐藏,占据空间;
  • (2)事件监听:可以进行 DOM 事件监听;
  • (3)性 能:提升为合成层,不会触发重绘,性能较高;
  • (4)继 承:会被子元素继承,且,子元素并不能通过 opacity: 1 来取消隐藏;
  • (5)transition:transition 支持 opacity。