CSS十问——好奇心+刨根问底=CSSer
最近有时间想把酝酿的几篇博客都写出来今天前端小学生带着10个问题跟大家分享一下学习CSS的一些体会我觉得想学好CSS必须保持一颗好奇心和刨根问底的劲头而不是复制粘贴得过且过。本人能力有限这篇文章从构思加完成用了四五天如果你和我一样是前端小白不妨仔细斟酌体会以期领悟到一些东西如果你是业界大牛也请你驻足随意瞄上两眼把言辞内容不妥的地方指出来我们共同讨论。时刻保持好奇心第一问当margin的值为百分比形式时为什么浏览器会根据父容器宽度得出计算值在我之前一篇博客检验你的前端基础——Sit the test中聊到了margin值为percentage时的计算方法。假如有一个父容器宽度400px高度600px其子元素设置margin:20% 20%后的计算值应该为“margin:120px 80px”还是“margin:80px 80px”呢按照那篇博客中的理论第二个是正确答案。但是在今天这篇文章中我给出的答案是第一个肯定错第二个也不一定对。一个符合W3C标准的浏览器会根据父容器的宽度进行计算但是这个仅限于书写模式为横向的时候。因为在横向排版时宽度“有迹可循”可以把浏览器宽度作为参考但是高度是不固定的所以margin百分比值在计算时会参考父容器的宽度。当书写模式改为纵向其计算参考便会变为父容器的高度了。戳我查看DEMO(请在webkit内核或IE下查看)。/*修改书写模式*/ .demo{ -webkit-writing-mode: vertical-rl; /* for browsers of webkit engine */ writing-mode: tb-rl; /* for ie */ }第二问marginauto为什么只能实现水平居中不能垂直居中当一个常规流中块级元素的margin属性左右值设为关键字auto且它拥有固定宽度时它便会平分剩余的水平空间居中显示。然而如果设置上下值为auto浏览器得到的计算值为0并不起任何的效果。那么问题来了为什么垂直方向的auto不生效与上一问类似这与布局相关。网页排版时常规流的块级元素水平方向总是铺满浏览器窗口垂直方向各块级元素按照先后顺序从上往下排列当页面内容过多时网页会出现纵向滚动条因此原理上纵向是可以无限扩展的计算时找不到一个固定的参考值所以纵向的auto无法生效。同样margin:auto会受书写模式的影响。当书写模式为纵向时marginauto垂直方向是可以居中的水平方向仍然可以居中(仅当父元素为body时见下方评论)。不信请自己写个demo试试吧。其实受到书写模式影响的属性除了这些外还有margin折叠、padding百分比值的计算等。第三问可以让一个position:fixed的元素相对于一个容器定位而非浏览器视口吗提到position:fixed很多人都会说这是一个定位属性与absolute的区别是它针对浏览器视口定位。我的博客导航栏就是利用“position:fixed”属性让其始终保持在窗口的最上方。不过还是不要忘记“世事无绝对”CSS实现了一个position:fixed的元素相对于一个容器定位请在FireFox下查看此DEMO。当一个元素应用了CSS3的transform属性后它的后代元素的fixed都将失效。http://www.w3.org/TR/css3-transforms/#issue-ca2c412c。因此可以利用这个Bug模拟出一个相对于某个包含块fixed的效果。关于transform更多的影响可以在张鑫旭的博客中看到CSS3 transform对普通元素的N多渲染影响。第四问可以用CSS实现面板的隐藏和显示吗现在要实现这样一个功能通过CSS切换某个面板的显示或隐藏。当提到CSS我们自然而然想到了控制某个单一元素的样式一旦涉及到多个元素交互我们往往使用JavaScript操作Dom。事实上这个需求不但可以用CSS来实现甚至实现方式不止一种请狂戳DEMO三种CSS方式实现面板隐藏和显示。第一种利用了label和checkbox使控制方和被控制方不需要有特定的HTML结构关系但是需要额外的HTML标签来支持。第二种方式利用了hover和子元素选择器第三种方式利用了focus和兄弟元素选择器后两种都受限于特定的HTML结构。三种方法都只使用CSS实现了面板的隐藏显示。第五问可以用CSS做出一个图标吗比如一个三角形一个小房子一个标签放在HTML中只能代表一种语义。然而一个标签加CSS则可以创造出无限的可能。请看DEMOCSS实现三角形小房子图案。利用border互相覆盖呈现出的斜线可以模拟出多种多样的几何状。在CSS3中每个元素都有::before和::after两个伪元素对同一个标签由CSS可以操控的单位由一个变为三个再加上绝对定位的辅佐各种各样的形状被创造了出来。你能想象吗这些图标都是用CSS画出来的。要想了解更多的CSS3图标可以访问这个网站http://www.uiplayground.in/css3-icons/第六问我想写针对IE67的hack该怎么写呢你可能会这么回答使用 “”“_”“*”等各种各样的符号来写hack。是的这样做没错但是需要记住每个符号分别被哪些浏览器识别并且如果写的太乱将造成代码 阅读起来十分困难。学习CSS必须抱有一种质疑精神有没有一种hack方法可以不写这些乱七八糟的符号并且代码易维护易读呢我们可以看看好搜首页是怎么做的在页面顶端有这样一句话!DOCTYPE html !--[if lt IE 7 ]html classie6![endif]-- !--[if IE 7 ]html classie7![endif]-- !--[if IE 8 ]html classie8![endif]-- !--[if IE 9 ]html classie9![endif]-- !--[if (gt IE 9)|!(IE)]!--html classw3c!--![endif]-- head在页面的CSS中会看到这样的规则.ie7 #hd_usernav:before, .ie8 #hd_usernav:before { display: none } .ie6 .skin_no #hd_nav li, .ie7 .skin_no #hd_nav li, .ie8 .skin_no #hd_nav li { border-right-color: #c5c5c5 } .ie6 .skin_no #hd_nav a, .ie7 .skin_no #hd_nav a, .ie8 .skin_no #hd_nav a { color: #c5c5c5 } ……这样做的优点就是克服了使用特殊符号hack的那些缺点缺点是需要写更多的代码使页面增大。一个前端er对上面这些问题知道与否并不影响他是否可以完成一个项目建设一个网站。但是如果没有好奇心不想追究内在原因仅抱着“我不想知道这么多东西反正我会用就行”这样一种态度那么他充其量算是一个“程序员”而非一位“工程师”。就是要刨根问底第七问行内级元素可以设置宽高吗不会为自身内容形成新的块而让内容分布在多行中的元素叫做行内级元素。此类元素可以与其它行内级元素在同一行中显示而不会另起一行例如spanstrong。在面试时当被问到行内级元素可否设置宽高时根据我们的经验往往会回答不能。但是这样往往着了面试官的道因为有一些特殊的行内元素比如imginputselect等等是可以被设置宽高的。一个内容不受CSS视觉格式化模型控制CSS渲染模型并不考虑对此内容的渲染且元素本身一般拥有固有尺寸宽度高度宽高比的元素被称之为置换元素。比如img是一个置换元素当不对它设置宽高时它会按照本身的宽高进行显示。所以这个问题的正确答案应该是置换元素可以非置换元素不可以。第八问CSS规则根据优先级生效低优先级的规则会被浏览器忽略还是覆盖在我的之前一篇博客中提到了浏览器中CSS优先级的使用规则多个优先级的样式都会被渲染只不过高优先级会覆盖住低优先级元素呈现为高优先级的样式。现在请考虑这样一个问题在一个div应用了两条background-image规则照之前的理论来看两条规则都会渲染那么请问浏览器会请求被覆盖规则的背景图片吗真实情况是浏览器会聪明到只请求当前应用的背景图片。简单理解的话浏览器只会为生效的CSS规则中的图片资源发出http请求。如果深究的话就必须谈谈浏览器的工作原理了。本人目前水平不够以下红色字体为个人理解请选择性阅读。在现代浏览器中一个页面从请求到呈现大致需要经过解析-构建DOM树-构建呈现树框架树-布局重排-绘制等几个步骤。一个页面的展现并不是一蹴而就的而是分步骤有条不紊的进行。众所周知的样式表层叠顺序和特异性计算发生在构造呈现树的过程中就是为了解决规则不止一个时的问题。以上面提到的背景图案为例浏览器计算完优先级后只有后定义的背景图案规则被构建到呈现树上。接下来浏览器会进行重排和绘制浏览器在绘制时才会请求背景图片规则用到的图片文件。这就是为什么只发出一个HTTP请求的原因。了解浏览器的工作原理不仅可以认清CSS解析和渲染过程还可以体会到重排和重绘发生的时机这对我们写出高效的CSS规则和JavaScript Dom操作有着非常深刻的指导意义。这个话题太大目前我的水平也不足以涉猎到此等学有所成后我会再发一篇文章详细谈谈。这里有一篇经典的文章感兴趣的可以看看浏览器的工作原理新式网络浏览器幕后揭秘。如果无法访问查看此国内地址w3ctech浏览器的工作原理。第九问使用margin可以做出圆角按钮的原理是什么当不能使用border-radius时如何制造一个圆角按钮现在有一个制造1px圆角的小技巧button中嵌套span设置span的margin为“margin:1px -1px”。戳我查看DEMO。知道这个小tip的人不在少数那么是什么原理导致这种现象呢学习CSS就需要刨根问底一张图可以把这个问题说明白。图中红色框为span标签蓝色框为a标签。当设置span的左右margin为-1px时其便会在左右各突出1px造成一种1px圆角的视觉效果。同样的道理在实现一些古老浏览器下的圆角与底色渐变的按钮时通常也会利用到多层元素层叠制造视觉误差的原理。