CSS面试题

Posted by hdj on January 13, 2019

前言

要换工作了,刷点面试题。

遇到的面试题参考

css 面试题汇总 BAT及各大互联网公司2014前端笔试面试题–Html,Css篇 https://www.jianshu.com/p/34ea504d657d

浏览器内核

  1. IE Trident
  2. Chrome webkit ->Blink
  3. Firfox Gecko
  4. Safari Webkit
  5. 360浏览器、猎豹浏览器内核:IE+Chrome双内核;

CSS盒模型

css 盒模型基本概念:

包括了 content、padding、border、margin

标准模型和 IE 模型的区别:

  1. 标准模型:width:content
  2. IE 模型:width:content+padding+border

js 如何设置获取盒模型对应的宽和高

获取元素 style 属性内的设置的 width/height:

dom.style.width/dom.style.height

IE下获取元素设置的 width/height:

dom.currentStyle.width/height

IE9+ 和大部分主流浏览器获取元素设置的 width/height:

window.getComputedStyle(dom).width/height

CSS样式优先级(权重 + 就近原则 + !important)

参考 CSS 优先级规则

行内样式(style)> ID 选择器 > Class(类),属性选择器和伪类选择器 > 元素和伪元素

style ; #id ; .content , 【attr=value】 , :hover ; P , :before ::selection

1,0,0,0 ; 0,1,0,0 ; 0,0,1,0; 0,0,0,1

例子:

  01. *{}                         ====》0
  02. li{}                        ====》1(一个元素)
  03. li:first-line{}             ====》2(一个元素,一个伪元素)
  04. ul li {}                    ====》2(两个元素)
  05. ul ol+li{}                  ====》3(三个元素)
  06. h1+ *[rel=up] {}            ====》11(一个属性选择器,一个元素)
  07. ul ol li.red{}              ====》13(一个类,三个元素)
  08. li.red.level{}              ====》21(两个类,一个元素)
  09. style=""                    ====》1000(一个行内样式)
  10. p {}                        ====》1(一个元素)
  11. div p {}                    ====》2(两个元素)
  12. .sith {}                    ====》10(一个类)
  13. div p.sith{}                ====》12(一个类,两个元素)
  14. #sith{}                     ====》100(一个ID选择器)
  15. body #darkside .sith p {}   ====》112(1+100+10+1,一个Id选择器,一个类,两个元素)

display: none;与visibility: hidden;的区别

联系: 他们都能让元素不可见

  1. display:none;会让元素完全从渲染树中消失,渲染的时候不占据任何空间;visibility: hidden;不会让元素从渲染树消失,渲染师元素继续占据空间,只是内容不可见
  2. display: none;是非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示;visibility: hidden;是继承属性,子孙节点消失由于继承了hidden,通过设置visibility: visible;可以让子孙节点显式
  3. 修改常规流中元素的display通常会造成文档重排。修改visibility属性只会造成本元素的重绘。
  4. 读屏器不会读取display: none;元素内容;会读取visibility: hidden;元素内容

link与@import的区别

  1. link是HTML方式, @import是CSS方式
  2. link最大限度支持并行下载,@import过多嵌套导致串行下载,出现FOUC
  3. link可以通过rel=”alternate stylesheet”指定候选样式 浏览器对link支持早于@import,可以使用@import对老浏览器隐藏样式 @import必须在样式规则之前,可以在css文件中引用其他文件 总体来说:link优于@import

display: block;和display: inline;的区别

block元素特点:

  1. 处于常规流中时,如果width没有设置,会自动填充满父容器
  2. 可以应用margin/padding
  3. 在没有设置高度的情况下会扩展高度以包含常规流中的子元素
  4. 处于常规流中时布局时在前后元素位置之间(独占一个水平空间)
  5. 忽略vertical-align

inline元素特点

  1. 水平方向上根据direction依次布局
  2. 不会在元素前后进行换行
  3. 受white-space控制
  4. margin/padding在竖直方向上无效,水平方向上有效
  5. width/height属性对非替换行内元素无效,宽度由元素内容决定
  6. 非替换行内元素的行框高由line-height确定,替换行内元素的行框高由height,margin,padding,border决定
  7. 浮动或绝对定位时会转换为block
  8. vertical-align属性生效

CSS有哪些继承属性

关于文字排版的属性如

* font
* word-break
*letter-spacing
* text-align
* text-rendering
* word-spacing
* white-space
* text-indent
* text-transform
* text-shadow

其他属性

  • line-height
  • color
  • visibility
  • cursor

BFC(块级格式化上下文)

块级格式化上下文 (Block Fromatting Context)

W3C对BFC的定义如下

浮动元素和绝对定位元素,

非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),

以及overflow值不为“visiable”的块级盒子,

都会为他们的内容创建新的BFC(块级格式上下文)。

创建规则

  1. 根元素(html)
  2. 浮动元素(float不是none)
  3. 绝对定位元素(position取值为absolute或fixed)
  4. display取值为inline-block,table-cell, table-caption,flex, inline-flex之一的元素
  5. overflow不是visible的元素

作用

  1. 可以包含浮动元素
  2. 不被浮动元素覆盖
  3. 阻止父子元素的margin折叠

外边距折叠(collapsing margins)

毗邻的两个或多个margin会合并成一个margin,叫做外边距折叠。规则如下:

1. 两个或多个毗邻的普通流中的块元素垂直方向上的margin会折叠

2. 浮动元素/inline-block元素/绝对定位元素的margin不会和垂直方向上的其他元素的margin折叠

3. 创建了块级格式化上下文的元素,不会和它的子元素发生margin折叠

4. 元素自身的margin-bottom和margin-top相邻时也会折叠

折叠结果遵循下列计算规则:

1. 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。

2. 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。

3. 两个外边距一正一负时,折叠结果是两者的相加的和。

水平垂直居中对齐方式

参考10种水平垂直居中对齐方式(史上最全)

 <div class="wp">
     <div class="box">123123</div>
 </div>
  1. PC端有兼容性要求,宽高固定,推荐absolute + 负margin

负margin

       .wp {
           position: relative;
       }
       .box {
           position: absolute;;
           top: 50%;
           left: 50%;
           margin-left: -50px;
           margin-top: -50px;
       }

margin 0 auto

       .wp {
           position: relative;
       }
       .box {
           position: absolute;;
           top: 0;
           left: 0;
           right: 0;
           bottom: 0;
           margin: auto;
       }
  1. PC端有兼容要求,宽高不固定,推荐css-table

a) absolute + transform tips:兼容至IE8

        parent{
            position: relative;
        }
        .child{
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%,-50%);
        } **b) inline-block + table-cell + text-align + vertical-align**


       .wp {
           display: table-cell;
           text-align: center;
           vertical-align: middle;
       }
       .box {
           display: inline-block;
       }
  1. PC端无兼容性要求,推荐flex

       .wp {
           display: flex;
           justify-content: center;
           align-items: center;
       }
    
  2. 移动端推荐使用flex

容器包含若干浮动元素时如何清理(包含)浮动

  1. 容器元素闭合标签前添加额外元素并设置clear: both
  2. 父元素触发块级格式化上下文(见块级可视化上下文部分)
  3. 设置容器元素伪元素进行清理 推荐的清理浮动方法

     /**
     * 在标准浏览器下使用
     * 1 content内容为空格用于修复opera下文档中出现
     *   contenteditable属性时在清理浮动元素上下的空白
     * 2 使用display使用table而不是block:可以防止容器和
     *   子元素top-margin折叠,这样能使清理效果与BFC,IE6/7
     *   zoom: 1;一致
     **/
        
     .clearfix:before,
     .clearfix:after {
        content: " "; /* 1 */
        display: table; /* 2 */
     }
        
     .clearfix:after {
        clear: both;
     }
        
     /**
     * IE 6/7下使用
     * 通过触发hasLayout实现包含浮动
     **/
     .clearfix {
        *zoom: 1;
     }
    

三栏布局

圣杯布局和双飞翼布局

圣杯布局来源于文章In Search of the Holy Grail,而双飞翼布局来源于淘宝UED。虽然两者的实现方法略有差异,不过都遵循了以下要点:

  1. 两侧宽度固定,中间宽度自适应
  2. 中间部分在DOM结构上优先,以便先行渲染
  3. 允许三列中的任意一列成为最高列
  4. 只需要使用一个额外的 <div> 标签

圣杯

dom结构

<div id="header"></div>
<div id="container">
  <div id="center" class="column"></div>
  <div id="left" class="column"></div>
  <div id="right" class="column"></div>
</div>
<div id="footer"></div>

css

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

#footer {
  clear: both;
} 

双飞燕

dom结构

 <body>
   <div id="header"></div>
   <div id="container" class="column">
     <div id="center"></div>
   </div>
   <div id="left" class="column"></div>
   <div id="right" class="column"></div>
   <div id="footer"></div>
 <body>

css代码

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

flex

这里使用flex还是需要与圣杯布局相同的DOM结构,不过在实现上将更加简单:

 <!-- DOM结构 -->
 <div id="container">
   <div id="center"></div>
   <div id="left"></div>
   <div id="right"></div>
 </div>

CSS代码如下:

 #container {
     display: flex;
 }
 
 #center {
     flex: 1;
 }
 
 #left {
     flex: 0 0 200px;
     order: -1;
 }
 
 #right {
     flex: 0 0 150px;
 }

rgba()和opacity

rgba()和opacity都能实现透明效果,但最大的不同是 opacity作用于元素,以及元素内的所有内容的透明度, 而rgba()只作用于元素的颜色或其背景色。(设置rgba透明的元素的子元素不会继承透明效果!)

px和em的区别

px和em都是长度单位,区别是,px的值是固定的,指定是多少就是多少,计算比较容易。

em得值不是固定的,并且em会继承父级元素的字体大小。

浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em。

CSS reset和normalize.css

重置样式,通常样式是浏览器表现尽量一致

,凡是一个前端开发人员肯定有一个常用的重置CSS文件并知道如何使用它们。他们是盲目的在做还是知道为什么这么做呢?原因是不同的浏览器对一些元素有不同的默认样式,如果你不处理,在不同的浏览器下会存在必要的风险,或者更有戏剧性的性发生。 你可能会用Normalize来代替你的重置样式文件。它没有重置所有的样式风格,但仅提供了一套合理的默认样式值。既能让众多浏览器达到一致和合理,但又不扰乱其他的东西(如粗体的标题)。 在这一方面,无法做每一个复位重置。它也确实有些超过一个重置,它处理了你永远都不用考虑的怪癖,像HTML的audio元素不一致或line-height不一致。

!Doctype的作用?严格模式与混杂模式的区别?

<!DOCTYPE>用于告知浏览器该以何种模式来渲染文档

严格模式下:页面排版及JS解析是以该浏览器支持的最高标准来执行

混杂模式:不严格按照标准执行,主要用来兼容旧的浏览器,向后兼容

PNG,GIF,JPG的区别及如何选

GIF:

  1. 8位像素,256色
  2. 无损压缩
  3. 支持简单动画
  4. 支持boolean透明 5 .适合简单动画

JPEG:

  1. 颜色限于256
  2. 有损压缩
  3. 可控制压缩质量
  4. 不支持透明
  5. 适合照片

PNG:

  1. 有PNG8和truecolor PNG
  2. PNG8类似GIF颜色上限为256,文件小,支持alpha透明度,无动画
  3. 适合图标、背景、按钮

html常见兼容性问题?

  1. 双边距BUG float引起的 使用display
  2. 3像素问题 使用float引起的 使用dislpay:inline -3px
  3. 超链接hover 点击后失效 使用正确的书写顺序 link visited hover active
  4. Ie z-index问题 给父级添加position:relative
  5. Png 透明 使用js代码 改
  6. Min-height 最小高度 !Important 解决’
  7. select 在ie6下遮盖 使用iframe嵌套
  8. 为什么没有办法定义1px左右的宽度容器(IE6默认的行高造成的,使用over:hidden,zoom:0.08 line-height:1px)
  9. IE5-8不支持opacity,解决办法:

     .opacity {
         opacity: 0.4
         filter: alpha(opacity=60); /* for IE5-7 */
         -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; /* for IE 8*/
     }
    
  10. IE6不支持PNG透明背景,解决办法: IE6下使用gif图片

渐进增强和优雅降级之间的不同吗?

渐进增强 progressive enhancement:

针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

优雅降级 graceful degradation:

一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。 区别:优雅降级是从复杂的现状开始,并试图减少用户体验的供给,而渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。

优雅降级

“优雅降级”观点认为应该针对那些最高级、最完善的浏览器来设计网站。而将那些被认为“过时”或有功能缺失的浏览器下的测试工作安排在开发周期的最后阶段,并把测试对象限定为主流浏览器(如 IE、Mozilla 等)的前一个版本。 在这种设计范例下,旧版的浏览器被认为仅能提供“简陋却无妨 (poor, but passable)” 的浏览体验。你可以做一些小的调整来适应某个特定的浏览器。但由于它们并非我们所关注的焦点,因此除了修复较大的错误之外,其它的差异将被直接忽略。

“渐进增强”观点

“渐进增强”观点则认为应关注于内容本身。 内容是我们建立网站的诱因。有的网站展示它,有的则收集它,有的寻求,有的操作,还有的网站甚至会包含以上的种种,但相同点是它们全都涉及到内容。这使得“渐进增强”成为一种更为合理的设计范例。这也是它立即被 Yahoo! 所采纳并用以构建其“分级式浏览器支持 (Graded Browser Support)”策略的原因所在。

CSS单位 px % em rem vw vh vm

  • px:

px是Pixel的缩写,表示像素,所谓像素就是呈现在我们显示器上的一个个小点,每个像素点都是大小等同的,所以像素为计量单位被分在了绝对长度单位中。

  • 百分比%

    百分比%就是相对于父元素尺寸来进行计算的,比如定义两个div元素,div1包含div2,设置父div1的width为100px,子div2的width为50%,则实际上计算的结果就是:子div2的宽度是100px*50% = 50px。

  • em

    相对长度单位。em是相对于当前对象内文本的字体尺寸而计算的。如果当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体(16px)尺寸。也就是1em=16px。

  • rem

    rem和em很像,只不过一个计算的规则是依赖根元素(html)一个是依赖父元素计算。 em是相对于其父元素来设置字体大小的,这样就会存在一个问题,进行任何元素设置,都有可能需要知道他父元素的大小。而rem是相对于根元素html, 这样就意味着,我们只需要在根元素确定一个参考值,从而统一整个页面的长度,只要改动根元素HTML的字体大小就可以统一比例的改动页面中所有使用rem作为长度单位的元素,而不会造成页面内布局错位。        需要注意的是,我们经常用的谷歌浏览器会强制页面的最小字体为12号,即使设置成 10px 最终都会显示成12px。既然html{font-size:62.5%}办不到,那换个思路,将html{font-size:625%}就好了,与html{font-size:62.5%}思路相同,只不是时将1rem = 10px,更正为1rem = 100px而已。

    需要注意的是,我们经常用的谷歌浏览器会强制页面的最小字体为12号,即使设置成 10px 最终都会显示成12px。 既然html{font-size:62.5%}办不到,那换个思路,将html{font-size:625%}就好了,与html{font-size:62.5%}思路相同, 只不是时将1rem = 10px,更正为1rem = 100px而已。

  • vw       

    vw是视窗宽度单位。1vw等于可视区宽度的百分之一。如果浏览器的宽是 500px, 1vw求得的值为 5px 。

  • vh     

  与vw意义相同,同样是将视窗作为参考值,不同的是vh是视窗高度单位。1vh等于可视区高度的百分之一。如果浏览器的高是 800px, 1vh 求得的值为 8px 。

  • vm        严格来说,vm并不是长度单位,他是vmax和vmin这两个长度单位的一个总称

  • vmax vmax是相对于视窗的宽度或高度的百分之一,取决于哪个更大。在宽为500px高为800px分辨率的显示器下1vm=8px。

  • vmin vmin是相对于视窗的宽度或高度的百分之一,取决于哪个更小。在宽为500px高为800px分辨率的显示器下1vm=5px

Q: 为什么给body的CSS样式设置font-size为62.5%?

解决方案:     A: 任意浏览器的默认字体高都是16px。所有未经调整的浏览器都符合: 1em=16px。为了简化font-size的换算,所以需要在css中的body选择器中声明Font-size=62.5%, 这就使em值变为 16px*62.5%=10px, 这样12px=1.2em, 10px=1em, 也就是说只需要将你的原来的px数值除以10,然后换上em作为单位就行了。

  • rpx

如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

CSS优化、提高性能的方法有哪些?

  1. 避免过度约束
  2. 避免后代选择符
  3. 避免链式选择符
  4. 使用紧凑的语法
  5. 避免不必要的命名空间
  6. 避免不必要的重复
  7. 最好使用表示语义的名字。一个好的类名应该是描述他是什么而不是像什么
  8. 避免!important,可以选择其他选择器
  9. 尽可能的精简规则,你可以合并不同类里的重复规则

浏览器是怎样解析CSS选择器的?

CSS选择器的解析是从右向左解析的。若从左向右的匹配,发现不符合规则,
需要进行回溯,会损失很多性能。若从右向左匹配,先找到所有的最右节点,
对于每一个节点,向上寻找其父节点直到找到根元素或满足条件的匹配规则,
则结束这个分支的遍历。两种匹配规则的性能差别很大,
是因为从右向左的匹配在第一步就筛选掉了大量的不符合条件的最右节点(叶子节点),
而从左向右的匹配规则的性能都浪费在了失败的查找上面。
而在 CSS 解析完毕后,需要将解析的结果与 DOM Tree 的内容一起进行分析建立一棵 Render Tree,
最终用来进行绘图。在建立 Render Tree 时(WebKit 中的「Attachment」过程),
浏览器就要为每个 DOM Tree 中的元素根据 CSS 的解析结果(Style Rules)来确定生成怎样的 Render Tree。

在网页中的应该使用奇数还是偶数的字体?为什么呢?

使用偶数字体。偶数字号相对更容易和 web 设计的其他部分构成比例关系。

Windows 自带的点阵宋体(中易宋体)从 Vista 开始只提供 12、14、16 px 这三个大小的点阵,

而 13、15、17 px时用的是小一号的点。(即每个字占的空间大了 1 px,但点阵没变),于是略显稀疏。

margin和padding分别适合什么场景使用?

何时使用margin:

  1. 需要在border外侧添加空白
  2. 空白处不需要背景色
  3. 上下相连的两个盒子之间的空白,需要相互抵消时。

何时使用padding

  1. 需要在border内侧添加空白
  2. 空白处需要背景颜色
  3. 上下相连的两个盒子的空白,希望为两者之和。
  4. 兼容性的问题:在IE5 IE6中,为float的盒子指定margin时,
  5. 左侧的margin可能会变成两倍的宽度。通过改变padding或者指定盒子的display:inline解决

元素竖向的百分比设定是相对于容器的高度吗?

当按百分比设定一个元素的宽度时,它是相对于父容器的宽度计算的, 但是,对于一些表示竖向距离的属性,例如 padding-top , padding-bottom , margin-top , margin-bottom 等,当按百分比设定它们时,依据的也是父容器的宽度,而不是高度。

::before 和 :after中双冒号和单冒号有什么区别?解释一下这2个伪元素的作用

单冒号(:)用于CSS3伪类,双冒号(::)用于CSS3伪元素。

::before就是以一个子元素的存在,定义在元素主体内容之前的一个伪元素。并不存在于dom之中,只存在在页面之中。

:before 和 :after 这两个伪元素,是在CSS2.1里新出现的。

起初,伪元素的前缀使用的是单冒号语法,但随着Web的进化,

在CSS3的规范里,伪元素的语法被修改成使用双冒号,成为::before ::after

你对line-height是如何理解的?

 行高是指一行文字的高度,具体说是两行文字间基线的距离。
 CSS中起高度作用的是height和line-height,没有定义height属性,
 最终其表现作用一定是line-height。
 单行文本垂直居中:把line-height值设置为height一样大小的值可以实现单行文字的垂直居中,
 其实也可以把height删除。
 多行文本垂直居中:需要设置display属性为inline-block。

position:fixed;在android下无效怎么处理?

   <meta name="viewport" content="width=device-width, initial-scale=1.0, 
   maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>

如果需要手动写动画,你认为最小时间间隔是多久,为什么?

多数显示器默认频率是60Hz,即1秒刷新60次,所以理论上最小间隔为1/60*1000ms = 16.7ms。

li与li之间有看不见的空白间隔是什么原因引起的?有什么解决办法?

  行框的排列会受到中间空白(回车空格)等的影响,因为空格也属于字符,
  这些空白也会被应用样式,占据空间,所以会有间隔,把字符大小设为0,就没有空格了。
  解决方法:
  
  可以将<li>代码全部写在一排
  浮动li中float:left
  在ul中用font-size:0(谷歌不支持);可以使用letter-space:-3px

display:inline-block 什么时候会显示间隙?

有空格时候会有间隙 解决:移除空格

margin正值的时候 解决:margin使用负值

使用font-size时候 解决:font-size:0、letter-spacing、word-spacing

style标签写在body后与body前有什么区别?

 页面加载自上而下 当然是先加载样式。
 写在body标签后由于浏览器以逐行方式对HTML文档进行解析,
 当解析到写在尾部的样式表(外联或写在style标签)会导致浏览器停止之前的渲染,
 等待加载且解析样式表完成之后重新渲染,在windows的IE下可能会出现FOUC现象
 (即样式失效导致的页面闪烁问题) ####  CSS属性overflow属性定义溢出元素内容区的内容会如何处理?
 
 
 参数是scroll时候,必会出现滚动条。
 参数是auto时候,子元素内容大于父元素时出现滚动条。
 参数是visible时候,溢出的内容出现在父元素之外。
 参数是hidden时候,溢出隐藏。    #### fontSize: 0px的作用

display:inline-block的元素之间会有一个字符的间隙,这个间隙导致了最后一个会掉下来。 父元素很有必要设置font-size:0,避免莫名其妙的间距。

CSS3新增伪类举例:

     p:first-of-type 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。
     p:last-of-type  选择属于其父元素的最后 <p> 元素的每个 <p> 元素。
     p:only-of-type  选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。
     p:only-child    选择属于其父元素的唯一子元素的每个 <p> 元素。
     p:nth-child(2)  选择属于其父元素的第二个子元素的每个 <p> 元素。
     :enabled、:disabled 控制表单控件的禁用状态。
     :checked,单选框或复选框被选中。