前一段时间应聘了一家公司,由于面试前完全没有做准备,面试过程中被问到了一些基础的前端开发问题我没答出来,对方认为"和我们期望的水平还有一定差距"为由拒绝我。
刚好我在github看到一篇很全的前端开发面试题目,所以就尝试自己整理一份答案出来。这篇文章的初衷是希望能够和大家互相讨论交流一下,如果我有错误的地方十分欢迎指出来。
PS: 我不认为单纯通过做题能够成为一名优秀的开发者,但是如果因为没有准备充足错失去机会是一件更糟糕的事(有这种经验的人会认同我的)。
如果元素具有唯一性,就考虑使用id;如果元素会多次出现,就是用class。值得注意的是,id的优先级比class高。
"CSS doesn't care,But Javascript care"
如果id和class用的不恰当,在JavaScript中就会遇到问题。例如getElementById返回一个对象,而getElementByClassName就会返回一个数组。
每个浏览器对于不同元素的css样式的默认值是不一样的,使用reset
可以统一css样式。
常见的reset
方法有:
* {
margin: 0;
padding: 0;
}
期待能够指出它的负面影响,或者提到它的一个替代者normalize
使用reset
方法会有个很大弊端,因为它清除了所有元素的margin和padding。实际上,对于某些元素保留一定的padding和margin是有好处的。
normalize是一个比较理想的解决方案。它统一了css的默认样式,同时对相应的元素初始化了默认值。一些比较流行的库例如bootstrap已经事先引入了normalize
。
如果对一个元素设置浮动,它就会脱离文本流直到碰到框的最左或者最右,普通流的其他元素会取代它原本的位置。
值得注意的是,如果框太窄不足容纳多个浮动元素,多出来的浮动的元素会出现在下一行;如果先前的元素高出其他浮动元素,可能导致下一行的浮动元素被"卡住",接触不到下一行的边框。z-index
和叠加上下文是如何形成的z-index
属性设置元素的堆叠顺序,数值越大的越靠前。注意,z-index
的值可以是负数,并且只在元素设置定位(比如position:absolute)才可形成。
顺便加一句,firefox为web开发者增添了3D视图的功能。pretty neat, huh?
浮动会出现一个问题,由于浮动的元素脱离了文本流,如果框的高度不足以包含浮动元素,浮动的元素就会"溢出"。
在框内设置一个空标签<div class="clear"></div>
, 空标签的CSS样式:
.clear {
clear: both;
}
这个方法的弊端是增加了无意义的标签。
把框架(包含浮动元素的元素)同时设置成浮动,子元素会被完全包含。这种方法的弊端是,下一个元素也会收到这个浮动框架的影响,没有从根本上解决问题。
这个办法其实本质上和设置空标签是一样的,只不过这里是用css样式在框内设置一个伪元素,然后把这个元素设置clear:both
之后隐藏起来(height:0;visibility:hidden;
)。
#parent:after {
content: '.';
height: 0;
visibility: hidden;
display: block;
clear:both;
}
需要注意的是,如果不把伪元素的高度设置为0,框内最底部就会多出几行空白像素。
父级元素设置样式:
#parent {
overflow: hidden;
zoom: 1;
}
zoom: 1;
用于兼容ie浏览器
css sprites就是把网站的一些图片整合到一张图片当中,利用css的background属性把对应的图片需要的部位显示出来,达到减少请求数的目的。
css sprites最大的优点是减少请求数,并且减少图片的字节数。弊端是开发比较繁琐,难以适应高分辨率的图片。
如果只是单纯现在自己的页面添加一些icon,强烈推荐font-awesome。
图片替代就是在使用图片来替换文档中原来的文本内容,达到文本内容无法渲染的视觉效果。图片替代的弊端是增加请求,而且会障碍人士和seo都不是十分友好。一般常用的图片替代方案有:
这种方法是添加一层包裹需要替换的内容,这新添加的一层上面设置background。需要替换的内容设置为display:none;
这种做法是相对比较简便的,也对seo比较有利。弊端是添加了多余的div。
这种方法主要是这是text-indent属性。text-indent属性通常用于这只第一行文本的缩进,可以未负值。所以可以用text-indent: -999px;
把文本内容缩进超出了视图范围以外。这种方法的好处的支持障碍人士的阅读器,是比较常用的替代方案。
不同的浏览器对于不同css样式解释不一样,因此导致生成不同的页面效果。css hacks是针对不同的浏览器的特性,编写在不同浏览器上显示相等的效果;反过来,也可以针对不同浏览器编写出不同的页面效果。
display:none;
display:none;不会为元素保留物理空间,所以某些搜索引擎过滤掉,所以这种做法对于seo不利。
visibility:hidden;
这种做法会占据物理空间,破坏页面结构,不推荐使用。
overflow: hidden;
<p class="hide">hello this will not be display</p>
.hide {
display: block;
overflow: hidden;
width: 0;
height: 0;
}
这是一种比较合理的处理办法,把文本内容设置为块级元素,然后撤销它的高度和宽度,在把超出的部分隐藏起来。既不影响seo,又达到了隐藏的目的。
Bootstrap。Bootstrap是个比较Nice的框架,即使是初学者也很容易掌握。它预定义了大部分比较常用的css样式,除此之外还包含了一堆有很有的组件,你需要做的只不过是给标签添加上适当的class它就会为你完成工作。你还可以利用less/sass更改源码,自定义你需要的样式。
Bootstrap的栅格系统把一行最多分为12列,你可以组合成3x4列,4x3列,2x6列等;然而分成12列是不能完全适应到所有的应用场所。比如,我先把一行平均分为5列,它就无能为力了。
另外,使用Bootstrap还有个比较严重的弊端。如果你的页面很依赖Bootstrap,你在标签上面定义的class会飞涨!如果你再加上AngularJS,项目的html文档很快就会变得无法管理。
<link rel="stylesheet" type="text/css" media="print" href="print.css">
以上为打印样式表,定义打印样式表需要注意的是:
> CSS选择器效率从高外低的排序为:
- id选择器(#header)
通常我们编写组合选择器(如ul li)是从左往右编写的,但是浏览器解析是从右外左的;也就是说,浏览器会从右外左遍历所有选择了的元素,在倒过来从DOM树的最顶端往下解析一次。
正如上面所解析的原理,假设我有```#box a {}```这条规则;浏览器会选中DOM树中所有的a标签,然后再一条一条检查这些a标签是否有一个id为box的父元素,这种做法会耗费太多浏览器资源。
解决办法是给需要选中的a标签添加一些关键词, 例如#box a.item {}
一部分新手会这样写规则:
> html body div#nav ul li a { ... }
不要笑,我是认真的。我以前也认为这种写法可能更加便于浏览器找到我想要的东西,
但是实际上正好相反。我们来还原一下浏览器解析这段规则的过程: 浏览器从右解析,抓去DOM树所有的<a>
标签,一个一个检查它们是不是有一个<li>
的祖先元素;把它们提取出来后,再一个一个检查它们同时有一个拥有<ul>
祖先元素的<li>
元素...好的,你现在知道我不是在开玩笑了。
现在你知道为什么#nav a { ... }
比#nav li a { ... }
高效了吧?
描述一下你使用过的CSS预处理器的优缺点
CSS预处理器是一种语言来增加CSS的"可编程性",一般的预处理器都支持变量,嵌套,Mixin等高级功能。用于提高css样式的编写效率,提高可维护性等。
缺点是,学习成本提高了,无形中会增加了团队的沟通成本。
相比英文字体,中文字体的选择在网页设计中有很大的局限性。原因是中文字体比英文字体字符多太多,一套英文字符顶多是26个字母再加一些符号;一套汉字每个字都是不同的字符,一套完整的字符至少也有几个MB。
国外的网站开发通常会引用一些厂商提供的Web Fonts
(比如Google Fonts),但是这套方案由于上文提到的原因对汉字不适用。
通常,开发者偏向于使用系统自带的字体,这样就可以减少请求了。但是使用操作系统自带的字体会遇到另外的问题。由于操作系统自带的字体本来就不多,相互之间几乎没有交集,针对Mac OS系统写的网站,可能在PC上面显示得很糟糕。
幸好CSS提供了一个比较合理的解决办法。我们可以使用CSS的font-family属性来引用多种字体。font-family属性的规则是:
示例:
font-family: Georgia, "Times New Roman",
"Microsoft YaHei", "微软雅黑",
STXihei, "华文细黑",
serif;
不好意思,好像跑题了。题目问的是『设计中用到了非标准的字体』。如果是这种情况,最好的办法应该是:
如果是英文,可以考虑使用Web Fonts;如果是Logo/Icon等,使用图片替代;文本内容使用font-family尽量做到与设计相近。