Mr. Panda
Tech For Fun

前端面试题集锦(5)

temp-or8

21. 解释下浮动和它的工作原理。

关于浮动我们需要了解,浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。要想使元素浮动,必须为元素设置一个宽度(width)。虽然浮动元素不是文档流之中,但是它浮动后所处的位置依然是在浮动之前的水平方向上。由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样,下面的元素填补原来的位置。有些元素会在浮动元素的下方,但是这些元素的内容并不一定会被浮动的元素所遮盖,对内联元素进行定位时,这些元素会考虑浮动元素的边界,会围绕着浮动元素放置。也可以把浮动元素想象成是被块元素忽略的元素,而内联元素会关注浮动元素的。(被块元素忽略,被内联元素关注)

详细:

浮动元素脱离文档流,不占据空间。浮动元素碰到包含它的边框或者浮动元素的边框停留。

浮动元素引起的问题:

父元素的高度无法被撑开,影响与父元素同级的元素;
与浮动元素同级的非浮动元素(内联元素)会跟随其后
若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构;
解决方法: 使用 CSS 中的 clear:both; 属性来清除元素的浮动可解决 2、3 问题,对于问题 1,添加如下样式,给父元素添加 clearfix 样式:

.clearfix:after{content: ".";display: block;height: 0;clear: both;visibility: hidden;}
.clearfix{display: inline-block;} /* for IE/Mac,触发hasLayout */

清除浮动的几种方法:

1,额外标签法,

<div></div>

(缺点:不过这个办法会增加额外的标签使 HTML 结构看起来不够简洁。)

2,使用 after 伪类

#parent:after{
content:".";
height:0;
visibility:hidden;
display:block;
clear:both;
}

3,设置 `overflow` 为 `hidden` 或者 auto,给包含浮动元素的父标签添加css属性 overflow:auto; zoom:1; zoom:1用于兼容IE6。


22. 列举不同的清除浮动的技巧,并指出它们各自适用的使用场景。

  • 1. 使用空标签清除浮动。这种方法是在所有浮动标签后面添加一个空标签定义 css clear:both. 弊端就是增加了无意义标签。
  • 2. 使用 overflow。给包含浮动元素的父标签添加 css 属性 overflow:auto;zoom:1;zoom:1 用于兼容 IE6。 (触发BFC)
  • 3. 使用 after 伪对象清除浮动。该方法只适用于非 IE
    浏览器。具体写法可参照以下示例。使用中需注意以下几点。一、该方法中必须为需要清除浮动元素的伪对象中设置
    height:0,否则该元素会比实际高出若干像素
    ;二、content 属性是必须的,但其值可以为空,content 属性的值设为”.”,空亦是可以的。

  • 4. 浮动外部元素
  • 此三种方法各有利弊,使用时应择优选择,比较之下第二种方法更为可取。


    23. 解释下 CSS sprites,以及你要如何在页面或网站中使用它。

    CSS Sprites 其实就是把网页中一些背景图片整合到一张图片文件中,再利用 CSS 的
    “background-image”,“background-repeat”,“background-position”
    的组合进行背景定位,background-position 可以用数字能精确的定位出背景图片的位置。


    24. 你最喜欢的图片替换方法是什么,你如何选择使用。

    <h2><span图片丢这里></span>Hello World</h2>
    

    把 span 背景设成文字内容,这样又可以保证 seo,也有图片的效果在上面。一般都是:alttitleonerror

    img 的 alt 属性,在图片不存在的情况下,各浏览器的解析不一样,chrome 下显示的是一张破损的图片,在 ff 下显示的是 alt 的文字,而在 IE 中显示的是破损的图片加文字。

    onerror方法:

    <img src="错误.jpn" alt=""  onerror="showerrimg(this)">
    
    function showerrimg(obj){
          var errorimg = "替换图片.jpg";//替换图片地址
          obj.src = errorimg;
        }

    利用 error 事件捕获来处理(全局判断,动态添加的元素也可以 - 最优解):

    document.addEventListener("error", function (e) {
    
      var elem = e.target;
      if (elem.tagName.toLowerCase() == 'img') {
        elem.src = "../img/img.jpg";
      }
    }, true);
    

    可以监听到动态产生的 img 标签。

    参考:jQuery 图片加载失败替换默认图片方法汇总;


    25. 讨论 CSS hacks,条件引用或者其他。

    为了实现浏览器兼容,主要有以下几种方式:

    1、给<html>标记添加包含User Agent的class属性

    这种方式得到的<html>标记可能会是这样的:<html class="ua-wk ua-wk535">

    2、条件样式表

    <!--[if IE 6]>

    <link href="ie6.css" />

    < ![endif]—>

    这种注释的方式只有IE浏览器支持其他浏览器只会把它当做html注释,不起任何作用。一般使用Javascript或者服务器端程序判断User Agent。

    好处是:HTML和CSS代码可以通过验证;可以很轻松的管理项目中的目标浏览器,并使得CSS补丁文件保持独立自由。更重要的是它帮助我们优化了 CSS样式表,保证了主要样式表的干净,这对于大型网站来说就很重要了。

    缺点是:这些注释需要放在HTML页面中,而不是放在CSS中。这样,当你不需要这些东西,或者有所更改的时候,就需要维护很多的地方。

    注:yahoo的内部编码最佳做法并不建议使用有条件的样式表。它会增加额外的平均1或2个HTTP下载请求

    3、css hack

         http://blog.moocss.com/code-snippets/html-css-code-snippets/1130.html

         http://www.cnblogs.com/wiky/archive/2010/01/07/Browser-CSS-Hacks-assembles.html

       国内解决兼容性问题一般是用CSS Hacks

    #test{
    background-color: black;/* Firefox, Opera, IE8 */
    [;background-color: green;]/* Safari, Chrome */
    *background-color: blue;/* IE7 */
    _background-color: red;/* IE6 */

    }

    属性hacks混写时要注意顺序

    background-color:blue; 各个浏览器都认识,这里给firefox用;
    background-color:red;所有的ie浏览器可识别;
    background-color:yellow
    background-color:blue; 各个浏览器都认识,这里给firefox用;
    background-color:red\9;\9所有的ie浏览器可识别;
    background-color:yellow\0; \0 是留给ie8的

    +background-color:pink; + ie7定了;
    _background-color:orange; _专门留给神奇的ie6;
    :root #test { background-color:purple\9; } :root是给ie9的,
    @media all and (min-width:0px){ #test {background-color:black\0;} } 这个是老是跟ie抢着认\0的神奇的opera,必须加个\0,不然firefox,chrome,safari也都认识。。。
    @media screen and (-webkit-min-device-pixel-ratio:0){ #test {background-color:gray;} }最后这个是浏览器新贵chrome和safari的。
    ;
    background-color:blue; 各个浏览器都认识,这里给firefox用;
    background-color:red\9;\9所有的ie浏览器可识别;
    background-color:yellow\0; \0 是留给ie8的

    +background-color:pink; + ie7定了;
    _background-color:orange; _专门留给神奇的ie6;
    :root #test { background-color:purple\9; } :root是给ie9的,
    @media all and (min-width:0px){ #test {background-color:black\0;} } 这个是老是跟ie抢着认\0的神奇的opera,必须加个\0,不然firefox,chrome,safari也都认识。。。
    @media screen and (-webkit-min-device-pixel-ratio:0){ #test {background-color:gray;} }最后这个是浏览器新贵chrome和safari的。
    是留给ie8的

    +background-color:pink; + ie7定了;
    _background-color:orange; _专门留给神奇的ie6;
    :root #test { background-color:purple; } :root是给ie9的,
    @media all and (min-width:0px){ #test {background-color:black
    background-color:blue; 各个浏览器都认识,这里给firefox用;
    background-color:red\9;\9所有的ie浏览器可识别;
    background-color:yellow\0; \0 是留给ie8的

    +background-color:pink; + ie7定了;
    _background-color:orange; _专门留给神奇的ie6;
    :root #test { background-color:purple\9; } :root是给ie9的,
    @media all and (min-width:0px){ #test {background-color:black\0;} } 这个是老是跟ie抢着认\0的神奇的opera,必须加个\0,不然firefox,chrome,safari也都认识。。。
    @media screen and (-webkit-min-device-pixel-ratio:0){ #test {background-color:gray;} }最后这个是浏览器新贵chrome和safari的。
    ;} } 这个是老是跟ie抢着认
    background-color:blue; 各个浏览器都认识,这里给firefox用;
    background-color:red\9;\9所有的ie浏览器可识别;
    background-color:yellow\0; \0 是留给ie8的

    +background-color:pink; + ie7定了;
    _background-color:orange; _专门留给神奇的ie6;
    :root #test { background-color:purple\9; } :root是给ie9的,
    @media all and (min-width:0px){ #test {background-color:black\0;} } 这个是老是跟ie抢着认\0的神奇的opera,必须加个\0,不然firefox,chrome,safari也都认识。。。
    @media screen and (-webkit-min-device-pixel-ratio:0){ #test {background-color:gray;} }最后这个是浏览器新贵chrome和safari的。
    的神奇的opera,必须加个
    background-color:blue; 各个浏览器都认识,这里给firefox用;
    background-color:red\9;\9所有的ie浏览器可识别;
    background-color:yellow\0; \0 是留给ie8的

    +background-color:pink; + ie7定了;
    _background-color:orange; _专门留给神奇的ie6;
    :root #test { background-color:purple\9; } :root是给ie9的,
    @media all and (min-width:0px){ #test {background-color:black\0;} } 这个是老是跟ie抢着认\0的神奇的opera,必须加个\0,不然firefox,chrome,safari也都认识。。。
    @media screen and (-webkit-min-device-pixel-ratio:0){ #test {background-color:gray;} }最后这个是浏览器新贵chrome和safari的。
    ,不然firefox,chrome,safari也都认识。。。
    @media screen and (-webkit-min-device-pixel-ratio:0){ #test {background-color:gray;} }最后这个是浏览器新贵chrome和safari的。

    CSS条件引用

    方案一: 在HTML文档中使用条件导入,如在HEAD中插入如下代码:

    <!--[if IE]>
       <link type="text/css" media="screen" rel="stylesheet" href="js/colorbox-custom-ie.css" title="Cleanity" />
    <![endif]-->

    方案二: 在CSS文档的开头使用条件导入,如下的代码所示:

    [if SafMob] @import('iphone.css');   
    [if ! SafMob] @import('non-iphone.css');

    通过 @import 最多可以导入31个CSS文件,由于每一次远程获取css文件都会产生http链接,比较耗时间,所以,最好尽量少用@import。

    CSS hack:

    什么是 CSS hack:

    由于不同厂商的流览器或某浏览器的不同版本(如 IE6-IE11,Firefox/Safari/Opera/Chrome 等),对 CSS 的支持、解析不一样导致在不同浏览器的环境中呈现出不一致的页面展现效果。这时,我们为了获得统一的页面效果,就需要针对不同的浏览器或不同版本写特定的 CSS 样式,我们把这个针对不同的浏览器 / 不同版本写相应的 CSS code 的过程,叫做 CSS hack!

    CSS hack 的原理:

    由于不同的浏览器和浏览器各版本对 CSS 的支持及解析结果不一样,以及 CSS 优先级对浏览器展现效果的影响,我们可以据此针对不同的浏览器情景来应用不同的 CSS。

    CSS hack 分类:

    CSS Hack 大致有 3 种表现形式,CSS 属性前缀法、选择器前缀法以及 IE 条件注释法(即 HTML 头部引用 if IE)Hack,实际项目中 CSS Hack 大部分是针对 IE 浏览器不同版本之间的表现差异而引入的。

    • 属性前缀法 (即类内部 Hack):例如 IE6 能识别下划线 "_" 和星号 "*",IE7 能识别星号 "*",但不能识别下划线 "_",IE6~IE10 都认识 "\9",但 firefox 前述三个都不能认识。
    • 在标准模式中

      • “-″减号是 IE6 专有的 hack
      • “\9″ IE6/IE7/IE8/IE9/IE10 都生效
      • “\0″ IE8/IE9/IE10 都生效,是 IE8/9/10 的 hack
      • “\9\0″ 只对 IE9/IE10 生效,是 IE9/10 的 hack
    • 选择器前缀法 (即选择器 Hack):例如 IE6 能识别 * html .class{},IE7 能识别 *+html .class{} 或者 *:first-child+html .class{}。
    • IE 条件注释法 (即 HTML 条件注释 Hack):针对所有 IE(注:IE10 + 已经不再支持条件注释): <!--[if IE]>IE 浏览器显示的内容 <![endif]-->,针对 IE6 及以下版本: <!--[if lt IE 6]> 只在 IE6 - 显示的内容 <![endif]-->。这类 Hack 不仅对 CSS 生效,对写在判断语句里面的所有代码都会生效。

    CSS hack 书写顺序,一般是将适用范围广、被识别能力强的 CSS 定义在前面。

    参考:史上最全的 CSS hack 方式一览

    CSS hack

    CSS hack2


    26. 如何为有功能限制的浏览器提供网页?你会使用哪些技术和处理方法?

    功能限制的浏览器,比如 IE 低版本、手机浏览器、奇葩国内浏览器,会在很多功能上不符合 Web 标准,而应对的方式有这么几种:

    • 只提供符合 Web 标准的页面

    • 提供另一个符合那些浏览器标准的页面

    • 兼容

    兼容:

    这里有两种思路,一个是渐进增强,一个优雅降级

    • 渐进增强的思路就是提供一个可用的原型,后来再为高级浏览器提供优化。
    • 优雅降级的思路是根据高级浏览器提供一个版本,然后有功能限制的浏览器只需要一个刚好能用的版本。

    相关技术:

    • Media Query
    • CSS hack
    • 条件判断 <!--[if !IE]><!--> 除IE外都可识别 <!--<![endif]-->


    27. 如何视觉隐藏网页内容,只让它们在屏幕阅读器中可用?

  • display:none;
    的缺陷搜索引擎可能认为被隐藏的文字属于垃圾信息而被忽略屏幕阅读器(是为视觉上有障碍的人设计的读取屏幕内容的程序)会忽略被隐藏的文字

  • visibility:hidden; 的缺陷就是隐藏的内容会占据他所应该占据物理空间。
  • overflow:hidden;
    一个比较合理的方法
  • . texthidden{

    display:block;/* 统一转化为块级元素
    */

    overflow:hidden;

    width:0;height:0;

    }

    就像上面的一段 CSS 所展示的方法,将宽度和高度设定为
    0,然后超过部分隐藏,就会弥补上述一、二方法中的缺陷,也达到了隐藏内容的目的。


    28. 你用过栅格系统吗?如果使用过,你最喜欢哪种?

    比如:Bootstrap,流式栅格系统,http://960.gs/,栅格系统延续美学。

    Bootstrap 提供了一套响应式、移动设备优先的流式栅格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列。它包含了易于使用的预定义类,还有强大的mixin 用于生成更具语义的布局。

    简介:

    栅格系统用于通过一系列的行(row)与列(column)的组合来创建页面布局,你的内容就可以放入这些创建好的布局中。下面就介绍一下 Bootstrap 栅格系统的工作原理:

    • “行(row)”必须包含在 .container (固定宽度)或 .container-fluid (100% 宽度)中,以便为其赋予合适的排列(aligment)和内补(padding)。
    • 通过“行(row)”在水平方向创建一组“列(column)”。
    • 你的内容应当放置于“列(column)”内,并且,只有“列(column)”可以作为行(row)”的直接子元素。
    • 类似 .row.col-xs-4 这种预定义的类,可以用来快速创建栅格布局。Bootstrap 源码中定义的 mixin 也可以用来创建语义化的布局。
    • 通过为“列(column)”设置 padding 属性,从而创建列与列之间的间隔(gutter)。通过为 .row 元素设置负值 margin 从而抵消掉为 .container 元素设置的 padding,也就间接为“行(row)”所包含的“列(column)”抵消掉了padding
    • 负值的 margin就是下面的示例为什么是向外突出的原因。在栅格列中的内容排成一行。
    • 栅格系统中的列是通过指定1到12的值来表示其跨越的范围。例如,三个等宽的列可以使用三个 .col-xs-4 来创建。
    • 如果一“行(row)”中包含了的“列(column)”大于 12,多余的“列(column)”所在的元素将被作为一个整体另起一行排列。
    • 栅格类适用于与屏幕宽度大于或等于分界点大小的设备 , 并且针对小屏幕设备覆盖栅格类。 因此,在元素上应用任何 .col-md-* 栅格类适用于与屏幕宽度大于或等于分界点大小的设备 , 并且针对小屏幕设备覆盖栅格类。 因此,在元素上应用任何 .col-lg-* 不存在, 也影响大屏幕设备。

    29. 你用过媒体查询,或针对移动端的布局 / CSS 吗?

    媒体查询,就是响应式布局。通过不同的媒介类型和条件定义样式表规则。媒介查询让 CSS 可以更精确作用于不同的媒介类型和同一媒介的不同条件。

    语法结构及用法:@media 设备名 only (选取条件) not (选取条件) and(设备选取条件),设备二 {sRules}。

    示例如下:

     1 /* 当浏览器的可视区域小于980px */
     2 @media screen and (max-width: 980px) {
     3 #wrap {width: 90%; margin:0 auto;}
     4 #content {width: 60%;padding: 5%;}
     5 #sidebar {width: 30%;}
     6 #footer {padding: 8% 5%;margin-bottom: 10px;}
     7 }
     8 /* 当浏览器的可视区域小于650px */
     9 @media screen and (max-width: 650px) {
    10 #header {height: auto;}
    11 #searchform {position: absolute;top: 5px;right: 0;}
    12 #content {width: auto; float: none; margin: 20px 0;}
    13 #sidebar {width: 100%; float: none; margin: 0;}
    14 }
    

    30. 你熟悉 SVG 样式的书写吗?

    SVG 意为可缩放矢量图形Scalable Vector Graphics)。

    什么是 SVG?

  • SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
  • SVG 用来定义用于网络的矢量图
  • SVG 使用 XML 格式定义图形
  • SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失 (无损缩放
  • SVG 是万维网联盟的标准
  • SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体
  • SVG,可伸缩矢量图形 (Scalable Vector Graphics) ,是w3c定义的用于网络的矢量图的一个标准,采用XML格斯定义图形,具有无损缩放的特点。

    书写示例如下:

    <?xml version="1.0" standalone="no"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    <svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
       <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
    </svg>

    常用的SVG形状写法实例:

    线:

    <line x1="10" x2="50" y1="110" y2="150"/>
    
    

    折线:

    <polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>
    

    背景色红色的矩形。

    <svg>
      <rect width="30" height="15" fill="#f00"/>
    </svg>
    
    

    带边框的矩形:

    <svg>
      <rect width="30" height="15" stroke="#f00" stroke-width="2"/>
    </svg>
    
    

    圆角矩形:

    <svg>
      <rect width="30" height="15" rx="5" ry="10"/>
    </svg>
    
    

    多边形:

    <polygon points="10 10, 10 15, 20 30, 40 50"/>
    
    

    圆:

    <circle cx="80" cy="50" r="20"/>
    
    

    (cx, cy) 是圆心座标

    椭圆 :

    <ellipse cx="75" cy="75" rx="20" ry="5"/>
    
    

    (cx, cy) 是椭圆中心座标
    cx 为长轴半径
    cy 为短轴半径


    31. 如何优化网页的打印样式?

    <link rel = "stylesheet" type = "text/css" media = "screen" href = "xxx.css"/>
    

    其中 media 指定的属性就是设备显示器上就是 screen,打印机则是 print,电视是 tv投影仪是 projection。打印样式示例如下:

    <link rel = "stylesheet" type = "text/css" media = "print" href = "yyy.css"/>
    

    但打印样式表也应注意以下事项:

  • 打印样式表中最好不要用背景图片,因为打印机不能打印 CSS 中的背景。如要显示图片,请使用 html 插入到页面中。
  • 最好不要使用像素作为单位,因为打印样式表要打印出来的会是实物,所以建议使用 pt 和 cm
  • 隐藏掉不必要的内容。(@print div{display:none;})
  • 打印样式表中最好少用浮动属性,因为它们会消失。如果想要知道打印样式表的效果如何,直接在浏览器上选择打印预览就可以了。

  • 32. 在书写高效 CSS 时会有哪些问题需要考虑?

  • 1. 样式是:从右向左的解析一个选择器;
  • 2.ID 最快,Universal 最慢有四种类型的 key selector,解析速度由快到慢依次是:ID、class、tag 和 universal

  • 3. 不要 tag-qualify(永远不要这样做 ul#main-navigation{}ID 已经是唯一的,不需要 Tag
    来标识,这样做会让选择器变慢。);

  • 4. 后代选择器最糟糕(换句话说,下面这个选择器是很低效的:html body ul li a{});
  • 5. 想清楚你为什么这样写;
  • 6.CSS3 的效率问题(CSS3 选择器(比如: nth-child)能够漂亮的定位我们想要的元素,又能保证我们的 CSS
    整洁易读
    。但是这些神奇的选择器会浪费很多的浏览器资源。);

  • 7. 我们知道 #ID 速度是最快的,那么我们都用 ID,是不是很快。但是我们不应该为了效率而牺牲可读性和可维护性。

  • 33. 使用 CSS 预处理器的优缺点有哪些?

    常用的CSS预处理器:

    Sass:

    Sass 是对 CSS(层叠样式表)的语法的一种扩充,诞生于 2007 年,最早也是最成熟的一款 CSS 预处理器语言,它可以使用变量、常量、嵌套、混 入、函数等功能,可以更有效有弹性的写出 CSS。Sass 最后还是会编译出合法的 CSS 让浏览器使用,也就是说它本身的语法并不太容易让浏览器识别,因为 它不是标准的 CSS 格式,在它的语法内部可以使用动态变量等,所以它更像一种极简单的动态语言。

    LESS:

    Less 是 CSS 预处理语言,在 css 基础之上增加了诸如变量,混合 (mix),继承,运算,函数等功能,LESS 既可以运行在客户端 (支持 IE10+,firefox,Webkit),也可以借助于 Node.js 在服务器端运行 (支持 IE6+,firefox,Webkit)。

    Stylus:

    Stylus,2010 年产生,来自于 Node.js 社区,主要用来给 Node 项目进行 CSS 预处理支持,在此社区之内有一定支持者,在广泛的意义上人气还完全不如 Sass 和 LESS。

    Stylus 被称为是一种革命性的新语言,提供一个高效、动态、和使用表达方式来生成 CSS,以供浏览器使用。Stylus 同时支持缩进和 CSS 常规样式书写规则。

    Sass 看起来在提供的特性上占有优势,但是 LESS 能够让开发者平滑地从现存 CSS 文件过渡到
    LESS,而不需要像 Sass 那样需要将 CSS 文件转换成 Sass 格式。Stylus 功能上更为强壮,和 js 联系更加紧密。


    优点&缺点:

    缺点:简单来说 CSS 预处理器语言较 CSS 玩法变得更高级了,但同时降低了自己对最终代码的控制力。更致命的是提高了门槛,首先是上手门槛,其次是维护门槛,再来是团队整体水平和规范的门槛。这也造成了初学学习成本的昂贵

    优点:用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。通俗的说,CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供项目使用。CSS 预处理器为 CSS 增加一些编程的特性,无需考虑浏览器的兼容性问题,例如你可以在 CSS 中使用变量、简单的逻辑程序、函数等等在编程语言中的一些基本特性,可以让你的 CSS 更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。


    34. 如果设计中使用了非标准的字体,你该如何去实现?

    所谓的标准字体是多数机器上都会有的,或者即使没有也可以由默认字体替代的字体。

    方法:

  • 用图片代替 (PNG透明图片,SVG矢量图);
  • web fonts 在线字库如 Google Webfonts,Typekit 等等;http://www.chinaz.com/free/2012/0815/269267.shtml
  • @font-faceWebfonts(字体服务例如:Google Webfonts,Typekit ,阿里字体库等等。)

  • 35. 解释下浏览器是如何判断元素是否匹配某个 CSS 选择器?

    从后往前判断。浏览器先产生一个元素集合,这个集合往往由最后一个部分的索引产生(如果没有索引就是所有元素的集合)。然后向上匹配,如果不符合上一个部分,就把元素从集合中删除,直到整个选择器都匹配完,还在集合中的元素就匹配这个选择器了。举个例子,有选择器:
    body.ready   #wrapper   >  .lol233

    先把所有 class 中有 lol233 的元素拿出来组成一个集合,然后上一层,对每一个集合中的元素,如果元素的 parent id 不为
    #wrapper 则把元素从集合中删去。再向上,从这个元素的父元素开始向上找,没有找到一个 tagName 为 body 且 class 中有 ready
    的元素,就把原来的元素从集合中删去。至此这个选择器匹配结束,所有还在集合中的元素满足。大体就是这样,不过浏览器还会有一些奇怪的优化。为什么从后往前匹配因为效率和文档流的解析方向。效率不必说,找元素的父亲和之前的兄弟比遍历所有儿子快而且方便。关于文档流的解析方向,是因为现在的
    CSS,一个元素只要确定了这个元素在文档流之前出现过的所有元素,就能确定他的匹配情况。应用在即使 html
    没有载入完成,浏览器也能根据已经载入的这一部分信息完全确定出现过的元素的属性。为什么是用集合主要也还是效率。基于 CSS Rule
    数量远远小于元素数量的假设和索引的运用
    ,遍历每一条 CSS Rule 通过集合筛选,比遍历每一个元素再遍历每一条 Rule 匹配要快得多。

    CSSRule

    CSSRule 对象是一个基类,用于 定义CSS 样式表中的任何规则,包括规则集(rule sets)和 @ 规则(at-rules)。规则存在若干种类型。所有这些类型在 CSSRule 接口共享的通用属性并不多,大部分类型都拥有专门针对特定规则类型的属性。

    在网页加载过程中, 浏览器将每个css文件解析为样式表对象CSSStyleSheet,每个对象包含css规则对象CSSRule,css规则对象CSSRule包含选择器和声明对象,以及其他一些符合css语法的对象。

    temp-or8

    temp-or8

    参考:cssRules 属性

    浏览器工作原理:

    参考:

    浏览器的工作原理整理

    详细:深入理解浏览器工作原理

    浏览器渲染流程:
    渲染引擎一开始会从网络层获取请求的文档的内容,通常以 8k 分块的方式完成,获取了文档内容之后,渲染引擎开始正式工作
    渲染引擎解析 HTML 文档,并将文档中的标签转化为 dom 节点树,同时,它会解析外部 css 文件以及 style 标签中的样式数据。这些样式信息连同 HTML 中的可见内容一起,被用于构建另一颗树——渲染树(RenderTree)。
    渲染树由一些带有视觉属性(如颜色、大小等)的矩形组成,这些矩形将按照正确的顺序显示在屏幕上。
    渲染树构建完毕之后,将会进入 “布局” 处理阶段,即为每一个节点分配一个屏幕坐标。再下一步就是绘制,即遍历 renderTree,并使用 UI 后端层绘制每个节点。
    注意:这个过程时逐步完成的,为了更好的用户体验,渲染引擎将会尽可能的早的将内容呈现在屏幕上,并不会等到所有的 Html 都解析完成之后再去构建和布局 renderTree。它时解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容。


    36.请解释一下 *{box-sizing:border-box;} 的作用, 并且说明使用它有什么好处?

    说到 IE 的 bug,在 IE6 以前的版本中,IE 对盒模型的解析出现一些问题,跟其它浏览器不同,将 border 与 padding 都包含在
    width 之内。而另外一些浏览器则与它相反,是不包括 border 和 padding 的。

    在我们开发的过程中会发现,有时候,如果对页面中的大区域进行设置时,将 border、padding 计算到 width 和 height
    之内,反而更灵活
    。但 W3C 的 CSS2.1 规范却规定了他们并不能被包含其中。考虑到这个问题,css3 中引入了一个新的属性:box-sizing,它具有
    “content-box” 和”border-box“两个值。

    当我们设置 box-sizing:content-box; 时,浏览器对盒模型的解释遵从W3C 标准,当它定义 width 和
    height 时,它的宽度不包括 border 和 padding。

    当我们设置 box-sizing:border-box; 时,浏览器对盒模型的解释与 IE6 之前的版本相同,当它定义 width 和 height
    时,border 和 padding 则是被包含在宽高之内的。内容的宽和高可以通过定义的 “width” 和“height”减去相应方向的 “padding”
    和“border”的宽度得到。内容的宽和高必须保证不能为负,必要时将自动增大该元素 border box 的尺寸以使其内容的宽或高最小为 0。


    37. 请罗列出你所知道的 display 属性的全部值。

    display 属性的值列表如下:

    temp-or8


    38. 请解释一下 relative、fixed、absolute 和 static 元素的区别?请解释一下 inline 和 inline-block
    的区别?

    标准流:

    浏览器在页面上摆放 HTML 元素时,它是采用文档流(flow)来实现的。就像瀑布一样从最上面的元素开始,自上而下进行元素显示,遇到块元素自动换行,默认每个块元素会占浏览器窗口的整个宽度。而内联元素会在水平方向上自左向右显示,总体上从左上方流向右下方,在垂直方向上扩展外围元素。

    inline: 此元素会被显示为内联元素,元素前后没有换行符。

    inline-block: 行内块元素。

    边距折叠

    浏览器在并排显示两个内联元素时,这两个的外边距是不会重合的,二者边框之间的距离是两者外边距之和;当两个块元素上下放置时,它们挨着的外边距会折叠起来,显示出来的外边距就是二者外边距里的最大值。当元素嵌套时,也会发生外边距折叠问题,其只会合并上边距和下边距,左右外边距并不合并。需要注意的是,如果外面的元素有一个边框,那么这两个元素的外边距就不会碰到一起,也就不可能发生折叠。我们只需要记住:只要两个垂直边距碰到一起,它们就会折叠,即使是嵌套起来的也不例外。浮动元素由于已经不在文档流之中,它们的外边距是不会折叠的(左右上下都不折叠)。

    浮动流:

    浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。要想使元素浮动,必须为元素设置一个宽度(width)。虽然浮动元素不是文档流之中,但是它浮动后所处的位置依然是在浮动之前的水平方向上。由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样,下面的元素填补原来的位置。有些元素会在浮动元素的下方,但是这些元素的内容并不一定会被浮动的元素所遮盖,对内联元素进行定位时,这些元素会考虑浮动元素的边界,会围绕着浮动元素放置。也可以把浮动元素想象成是被块元素忽略的元素,而内联元素会关注浮动元素的。(块元素忽略浮动元素,内联元素关注浮动元素)

    CSS 有三种基本的定位机制普通流(标准流、文档流)、浮动流和定位流。除非专门指定,否则所有框都在普通流中定位。也就是说,普通流中的元素的位置由元素在 (X)HTML 中的位置决定。

    定位流:

    position 属性:

    四种定位方式:静态定位、相对定位、绝对定位和固定定位。

    static:元素框正常生成。块级元素生成一个矩形框,作为文档流的一部分,行内元素则会创建一个或多个行框,置于其父元素中。如果不为元素指定定位方式,会采用默认的静态定位方式。如果是静态定位,那么元素就放在正常的文档流中,由浏览器完全决定元素的摆放。虽然你可以用 float 来浮动元素,但最终还是由浏览器决定元素的最终放置。

    relative:元素框偏移某个距离。相对定位的元素会正常的流入页面,不过在页面上要进行偏移。(标准流、偏移)

    absolute:元素框从文档流完全删除,并相对于其包含块定位。包含块可能是文档中的另一个元素或者是初始包含块。元素原先在正常文档流中所占的空间会关闭,就好像元素原来不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。(display:block)

    绝对定位元素和浮动元素的区别:

    绝对定位(absolute),虽然也是从文档流中删除,但它与浮动是不同的,(1)它不会再和原来位置保持水平而是由 top,right,bottom,left 等属性值(位置属性)确定,这些值都是相对于其父元素的。(2)而且流中的元素无论是块元素还是内联元素都不再关注绝对定位的元素,它们完全不知道页面上有绝对定位元素的存在。所以在布局时为了不被绝对定位元素遮盖文档流中的元素,最好给下面的元素设置恰当的外边距(margin)。绝对定位元素还有一个很意思的特性,那就是可以分层放置,可以用 z-index 属性来分层放置元素,这会指定它在一个虚拟 z 轴(垂直于页面)上的位置,而且越靠近你的元素 z-index 值越大。当然 z-index 属性并不是绝对定位所专属的,相对定位和固定定位的元素也有这个属性。(3)绝对定位时并不需要对元素设置宽度 (width),如果不指定宽度,则块元素会默认的占浏览器的整个宽度(包含 margin-left 和 margin-right,并不仅仅是内容宽度 width)。

    fixed:元素框的表现类似于将 position 设置为 absolute,不过其包含块是视窗本身。也就是说,固定定位会把元素放在相对于浏览器窗口的一个位置上不是相对于页面,html),固定定位的元素是不会随页面滚动而移动的。

    包含块:绝对定位的元素相对来定位的元素。


    39. 你目前在使用哪一套 CSS 框架,或者在产品线上使用过哪一套?(Bootstrap,PureCSS,Foundation 等等)

    如果有,请问是哪一套?如果可以,你如何改善 CSS 框架?

    请问你有使用过 CSS Flexbox 或者 Grid specs 吗?如果有,请问在性能和效率的方面你是怎么看的?

    之前用到ElementUI可以按需加载,我就想着bootstrap要是可以按需加载就好了,因为我有时用到的bootstrap效果并不多,如果全部引入项目的话,编译后项目比较大。Bootstrap框架怎样按需加载?

    Webpack 3.x 通过PurifyCSS Plugin按需加载bootstrap css样式:

    先安装:

    npm i -D purifycss-webpack purify-css

    去webpack.config.js中去配置:

    const glob = require('glob');
    const PurifyCSSPlugin = require('purifycss-webpack');

    再把purifyCSSPlugin添加到plugins对象中:

    new PurifyCSSPlugin({
         // Give paths to parse for rules. These should be absolute!
         paths: glob.sync(path.join(__dirname, './src/*.html')),
    }) //src目录下的所有html模板都会被影响

    如何避免CSS框架造成的污染?

    (1)当你决定引入某个框架的时候,就需要以这个框架的样式表为主,并在此基础上做一些细节调整。

    (2)也可以考虑改 bootstrap 的源文件中的样式,但是不建议改结构,改结构可能引起布局混乱。

    (3)使用bootstrap-iso容器

    1. 引入CSS文件:https://formden.com/static/as...

    2. 使用bootstrap-iso容器把自己编写的Bootstrap代码包起来
      示例:

    <div class="bootstrap-iso">这里是自己编写的bootstrap代码</div>

    使用 css 框架的优缺点?

    使用 css 框架的优点:

    1. 加速开发

    CSS 框架提供通用的代码 (如 reset, 和移动端开发的一些常用设置) 和许多丰富的 UI 组件样式——因此我们不需要从头开始写。

    2. 无兼容性烦恼

    CSS 框架解决了各个浏览器下的兼容性问题, 使用 css 框架做的网站或 web 应用在所有浏览器下的表现都一致。所以我们只需专注创建内容和而不需要处理特定浏览器的样式缺陷

    3. 合理的布局

    CSS 框架建立了基于网格的预定义宽度多列布局。所以我们不需要在布局上花太多心思。我们不需要计算列宽, 精确调整像素确保页面排列整齐

    4. 培养好的样式书写规则

    包括样式的命名, 样式属性的书写顺序, 各种样式语法的灵活与实际应用方法

    5. 保持页面风格的一致性

    团队协作开发, 如果大家都基于 CSS 框架进行开发,所开发的网页和 web 应用的 UI 外观一致性较好。

    使用 CSS 框架的缺点:

    1. 限制自由

    CSS 框架中的网格,选择器和其它样式,限制了我们可以设计的东西: 如布局,网格宽度,UI 样式,以及其它受惠于 CSS 框架的方面。

    2. 添加额外代码覆盖框架样式

    CSS 框架不可避免地存在一些我们不需要的代码。我们不太可能会用到框架中的每一个功能。而我们书写自己的 UI 样式时, CSS 框架可能预置了一些默认样式,而这些样式我们并不需要,因此需要书写额外的代码来覆盖 CSS 框架的预置样式

    3. 强迫使用框架规则

    使用 CSS 框架,我们被迫接受框架规则,如果我们对于 CSS 元素,选择器,ID 和类有自己命名规范,这可能会对我们已经的规范造成冲突

    4、潜在时间损失

    如果我们已经熟悉了特定的设计和开发方式而又被迫去使用不熟悉的 CSS 框架,我们前期会损失一定的开发时间用于学习 CSS 框架。

    选择依据:

    如果 CSS 框架中提供的绝大功能你都能用到的话, 那我建议你采用 CSS 框架, 这会带来开发的便利和设计的精简。如果公司已有成熟的开发规范,只用到框架中的极少部分功能,那么就不需要采用 CSS 框架, 只需从 CSS 框架中摘取出我们所需的那部分代码就可以了

    如何使用 Flexbox 和 CSS Grid,实现高效布局;

    CSS 终极之战:Grid vs Flexbox;


    40. 解释下事件代理。

    JavaScript
    事件代理则是一种简单的技巧,通过它你可以把事件处理器添加到一个父级元素上,这样就避免了把事件处理器添加到多个子级元素上当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数。这主要得益于浏览器的事件冒泡机制(事件冒泡的好处)。事件代理用到了两个在
    JavaSciprt 事件中常被忽略的特性:事件冒泡以及目标元素。

    获取事件对象的兼容性方法:

    function getEventTarget(e) {
         e=e||window.event;
        //标准浏览器用 ev.target,IE 浏览器用 event.srcElement
         return e.target||e.srcElement;
    }
    

    详细:

    什么是事件委托?

    事件委托还有一个名字叫事件代理,JS 高程上讲:事件委托就是利用事件冒泡,只制定一个时间处理程序,就可以管理同类型的所有事件。我用取快递来解释这个现象: 有三个同事预计会在周一收到快递。为签收快递,有两种办法:一是三个人在公司门口等快递;二是委托给前台代为签收。现实当中,我们大都采用委托的方案。前台收到快递后,她会判断收件人是谁,然后按照收件人的要求签收,甚至代为付款。这种方案还有一个优势,那就是即使公司里来了新员工(不管多少),前台也会在收到寄给新员工的快递后核实并代为签收。

    一、背景介绍

    这里其实还有 2 层意思的:

    第一,现在委托前台的同事是可以代为签收的,即程序中的现有的 dom 节点是有事件的

    第二,新员工也是可以被前台代为签收的,即程序中新添加的 dom 节点也是有事件的

    二、知识剖析

    2.1 为什么要用事件委托

    在 JavaScript 中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与 dom 节点进行交互,访问 dom 的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少 DOM 操作的原因每个函数都是一个对象,是对象就会占用内存,对象越多,内存占用率越大,100 个 li 就要占用 100 个内存空间。如果要用事件委托,就会将所有的操作放到 js 程序里面,只对它的父级 (如果只有一个父级) 这一个对象进行操作,与 dom 的操作就只需要交互一次,这样就能大大的减少与 dom 的交互次数,提高性能;

    2.2 事件委托的原理

    事件委托是利用事件的冒泡原理来实现的,何为事件冒泡呢?就是事件从最深的节点开始,然后逐步向上传播事件,举个例子:页面上有这么一个节点树,div>ul>li>a; 比如给最里面的 a 加一个 click 点击事件,那么这个事件就会一层一层的往外执行,执行顺序 a>li>ul>div,有这样一个机制,那么我们给最外面的 div 加点击事件,那么里面的 ul,li,a 做点击事件的时候,都会冒泡到最外层的 div 上,所以都会触发,这就是事件委托,委托它们父级代为执行事件。

    2.3 事件冒泡及捕获

    DOM2.0 模型将事件处理流程分为三个阶段:一、事件捕获阶段,二、事件目标阶段,三、事件起泡阶段。如图:

    事件捕获:当某个元素触发某个事件(如 onclick),顶层对象 document 就会发出一个事件流,随着 DOM 树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。

    事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。

    事件起泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被触发。

    2.4 事件委托的优点

    使用事件委托对于 web 应用程序带来的几个优点:

    1. 管理的函数变少了。不需要为每个元素都添加监听函数。对于同一个父节点下面类似的子元素,可以通过委托给父元素的监听函数来处理事件。

    2. 可以方便地动态添加和修改元素,不需要因为元素的改动而修改事件绑定。

    3.JavaScript 和 DOM 节点之间的关联变少了,这样也就减少了因循环引用而带来的内存泄漏发生的概率。

    什么样的事件可以用事件委托,什么样的事件不可以用呢?

    适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。(所有用到按钮的事件,多数的鼠标事件和键盘事件) 值得注意的是,mouseover 和 mouseout 虽然也有事件冒泡,但是处理它们的时候需要特别的注意,因为需要经常计算它们的位置,处理起来不太容易。 不适合的就有很多了,举个例子,mousemove,每次都要计算它的位置,非常不好把控,在不如说 focus,blur 之类的,本身就没用冒泡的特性,自然就不能用事件委托了。

    参考:简述 JS 中的事件委托和事件代理

    jonsam ng

    jonsam ng

    文章作者

    海阔凭鱼跃,天高任鸟飞。

    前端面试题集锦(5)
    21. 解释下浮动和它的工作原理。 关于浮动我们需要了解,浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。要想使元素浮动,必须为元素设置一个宽度(wid…
    扫描二维码继续阅读
    2019-10-13