当前位置: 首页 > 科技观察

CSS十问——好奇心+探究=CSSer

时间:2023-03-12 10:45:16 科技观察

最近有空,想把酝酿中的几篇博客写出来。今天前端小学生带来10道题,跟大家分享一些学习CSS的心得。我觉得要想学好CSS,就必须保持一颗好奇心和一探究竟的动力,而不是复制粘贴,得过且过。本人能力有限,这篇文章从构思到完成用了四五天的时间。如果你和我一样是前端小白,不妨仔细考虑和体验一下,才能有所了解;如果您是业内大牛,请停下来,随意多看两眼,指出不当之处,一起讨论。永远好奇***问题:当margin的值是百分比形式时,为什么浏览器会根据父容器的宽度来计算该值?在我之前的博客考你的前端基础——坐考中,讲到了margin值为时的计算方法。如果有一个宽为400px,高为600px的父容器,设置margin:20%20%后,其子元素的计算值应该是“margin:120px80px”还是“margin:80px80px”?根据该博文中的理论,第二个是正确答案。但是在今天的文章中,我给出的答案是第一个肯定是错的,第二个也不一定是对的。符合W3C标准的浏览器将根据父容器的宽度计算它,但仅当书写模式为横向时。因为在水平排版中,宽度是“可追溯的”,浏览器的宽度可以作为参考,而高度是不固定的,所以边距百分比值在计算时会参考父容器的宽度。当书写模式更改为纵向时,其计算参考将成为父容器的高度。戳我查看DEMO(请在webkit内核或IE下查看)。/*修改书写模式*/.demo{-webkit-writing-mode:vertical-rl;/*forbrowsersofwebkitengine*/  writing-mode:tb-rl;/*forie*/}第二问:margin:auto为什么只能实现水平居中,不能实现垂直居中?当常规流中的块级元素的margin属性的左右值设置为关键字auto,并且它有固定的宽度时,它会将剩余的水平空间平分并居中显示。但是,如果你把upper和lower的值设置为auto,那么浏览器得到的计算值是0,没有任何作用。那么问题来了,为什么垂直方向的auto没有生效呢?与上一个问题类似,这与布局有关。网页排版时,常规流的块级元素水平方向总是充满浏览器窗口,垂直方向的块级元素从上到下依次排列。当页面内容过多时,网页会出现垂直滚动条,所以原则上垂直方向可以自由扩展,计算时找不到固定的参考值,所以verticalauto不能生效。同样,margin:auto受书写模式的影响。当书写模式为纵向时,margin:auto可以垂直居中,水平方向仍然可以居中。不相信?请写个demo自己试试看。其实除了这些受书写方式影响的属性外,还有margin折叠,padding百分比计算等。说到position:fixed,很多人会说这是一个定位属性。与absolute的区别在于它是针对浏览器视口定位的。我博客的导航栏使用了“position:fixed”属性,让它始终保持在窗口的顶部。但别忘了“世界上没有绝对”,CSS实现了一个相对于容器的position:fixed元素,请在FireFox下查看这个DEMO。当一个元素应用了CSS3的transform属性时,其后代元素的fixed将失效。http://www.w3.org/TR/css3-transforms/#issue-ca2c412c。因此,这个bug可以用来模拟一个相对于某个包含块的固定效果。更多transform的效果可以看张新旭的博客:CSS3transformN种常见元素的多重渲染效果。问题四:CSS可以用来隐藏和显示面板吗?现在要实现这样一个功能,通过CSS切换某个面板的显示或隐藏。提到CSS,我们自然而然会想到控制单个元素的样式。一旦涉及到多个元素的交互,我们往往会使用JavaScript来操作Dom。其实这个需求不仅可以用CSS来实现,还可以有多种方式。DEMO请戳:隐藏和显示面板的三种CSS方式。第一种使用标签和复选框,这样控制方和受控方不需要有特定的HTML结构关系,但是需要额外的HTML标签来支持。第二种方法利用悬停和子元素选择器,第三种方法利用焦点和兄弟元素选择器,这两种方法都限于特定的HTML结构。三种方法都只使用CSS来实现面板的隐藏显示。问题5:图标可以用CSS制作吗?像三角形?atinyhouse一个标签,放在HTML中,只能表示一种语义。然而,标签加上CSS可以创造独特的可能性。请看DEMO:CSS实现三角形和小房子图案。使用边界相互重叠的斜线可以模拟出各种几何形状。在CSS3中,每个元素都有两个伪元素:::before和::after。对于同一个标签,CSS可以操纵的单位从一个变成了三个,并且借助于绝对定位,创造出了各种这样的形状。你可以想象?这些图标是用CSS绘制的。想了解更多关于CSS3图标的知识,可以访问这个网站:http://www.uiplayground.in/css3-icons/第六个问题:我想为IE6和7写一个hack,应该怎么写?你可能会这样回答:用“>”、“_”、“*”等各种符号来写hack。是的,这是正确的,但是你需要记住每个符号都有哪些浏览器识别,如果你写得太乱,会让代码很难阅读。学习CSS一定要有怀疑的精神。有没有hack方法可以避免写这些乱七八糟的符号,让代码易于维护和阅读呢?我们可以看看好搜的首页是怎么做的:在页面最上方有这样一句话:在页面的CSS中,你会看到这样的规则:.ie7#hd_usernav:before,.ie8#hd_usernav:before{display:none}.ie6.skin_no#hd_navli,.ie7.skin_no#hd_navli,.ie8.skin_no#hd_navli{border-right-color:#c5c5c5}.ie6.skin_no#hd_nava,.ie7.skin_no#hd_nava,.ie8.skin_no#hd_nava{color:#c5c5c5}….这样做的好处是它克服了使用特殊符号hack的缺点。缺点是需要写更多的代码来增加页面的大小。一个前端er知不知道以上这些问题,并不影响他能否完成一个项目,建一个网站。但如果他没有好奇心,不想追究其内在原因,只是抱着“我不想知道那么多,反正我会用”的态度,那他充其量就是一个“程序员”而不是“工程师”。只为一探究竟!问题七:行内级元素的宽高可以设置吗?不为自己的内容形成新块,而是将其内容分散到多行的元素称为行内级元素。此类元素可以与其他行内级元素显示在同一行,而无需换行,例如span、strong。在面试中,当被问到行内级元素的宽高是否可以设置时,根据我们的经验,我们往往会回答不能。但这往往是面试官的套路,因为有些特殊的内联元素,比如img、input、select等,是可以设置width和height的。一个内容不受CSS视觉格式化模型的控制,CSS渲染模型不考虑这个内容的渲染,元素本身一般都有一个固有的尺寸(宽、高、纵横比)元素,称为替换元素。例如,img是替换元素。当没有为其设置宽高时,会按照自身的宽高显示。所以这道题的正确答案应该是替换元素可以,非替换元素不行。问题8:CSS规则按照优先级生效。优先级低的规则会不会被浏览器忽略或覆盖?在我之前的博客中提到了CSS优先级在浏览器中的使用规则:多个优先级的样式都会被渲染,但是高优先级会覆盖低优先级,元素会被渲染为高优先级样式。现在请思考这样一个问题,两个background-image规则应用到一个div上,按照前面的理论,两个规则都会被渲染,那么浏览器会不会请求覆盖规则的背景图片呢?事实上,浏览器足够聪明,只请求当前应用程序的背景图像。简单理解,浏览器只会在有效的CSS规则中发送对图片资源的http请求。深究的话,一定要说说浏览器的工作原理。本人目前水平不够,以下红色字体为个人理解,请选择性阅读。在现代浏览器中,一个页面从请求到呈现,大致需要经过解析-构建DOM树-构建渲染树(frametree)-布局(重排)-绘制等几个步骤。一个页面的展示不是一蹴而就的,而是一步步有条不紊地完成的。众所周知的样式表级联顺序和特异性计算发生在构建表示树的过程中,就是为了解决规则多于一条时的问题。以上面提到的背景图案为例,浏览器在计算优先级后,只会将最后定义的背景图案规则构建到渲染树中。接下来浏览器会重新排列绘制,浏览器在绘制时会请求背景图片规则使用的图片文件。这就是为什么只发出一个HTTP请求的原因。了解浏览器的工作原理,不仅可以认识CSS的解析和渲染过程,还可以实现重排重绘的时机,这对于我们编写高效的CSS规则和JavaScriptDom操作有着非常深刻的指导意义。这个话题太大了,我现在的水平还不够涉猎。等我有所了解之后再发一篇文章详细说一下。对于那些感兴趣的人来说,这是一篇经典文章:浏览器的工作原理:新Web浏览器的幕后花絮。如果访问不了,查看这个国内地址:w3ctech:Howthebrowserworks。第九问:使用margin做圆角按钮的原理是什么?不能使用border-radius时如何制作圆角按钮?现在制作1px的圆角有一个小技巧:span嵌套在button中,span的边距设置为:“margin:1px-1px”。戳我看DEMO。知道这个小技巧的人不在少数,那么造成这种现象的原理是什么呢?学CSS,要追根究底,一张图就能把这个问题说清楚。图中红框是span标签,蓝框是a标签。当span的左右外边距设置为-1px时,会向左右两边突出1px,从而产生1px圆角的视觉效果。出于同样的原因,在一些古老的浏览器下实现带有圆角和背景颜色渐变的按钮时,通常会使用层叠多层元素的原理来制造视觉错误。问题10:清除浮动的方式有N种,它们的共同点是什么?所谓清浮动,一般是为了解决子元素浮动导致父容器高度塌陷的问题。目前解决这个问题的方法有很多,最常见的有after伪元素,在父元素上设置“overflow:hidden”等,详见DEMO:清除浮动的七种方法。其实按照原理,这些方法可以归纳为两种:clear:both方法和构造BFC方法。在方法分类float的末尾添加一个新的标签,设置样式为clear:bothclear:both在float的末尾添加一个
标签clear:both使用::after伪元素clear:bothparentelementsetdisplay:tableconstructBFCparentelementsetoverflow:AutoConstructBFCParentelementsetoverflow:hidden构造BFC让父元素也浮动ConstructBFC使用"clear:both"清除浮动自然不用说了,那什么是BFC的构造方法?块格式化内容xts(BFC),块级格式化上下文是CSS2.1中提出的一个概念。在布局上,BFC是自包含的,负责自己的内部元素,不会和浮动元素重叠。相邻BFC的上下边距也是不会重叠的,所以我们构造一个BFC来防止边距重叠,清除浮动或者实现双列布局。那么如何构建BFC呢?1.float设置为non-none;2.overflow设置为不可见;3.display设置为table-cell,table-caption,inline-block;4.position设置为absolute或fixed。这些方法恰好对应于上述构造BFC清除浮动的方法。需要特别注意的是,IE6、7下没有BFC的概念,但是有一个本质上和BFC类似的概念:layout。IE6、7遇到的很多BUG都可以通过让元素有布局来解决,比如floatingmargin双面间距、peek-a-boo、3像素间距等等。有些元素比如table,input本身就有布局,那么一个普通的元素如何实现布局呢?包括但不限于以下方法:1.position:absolute;2.float不是没有;3.显示:内联块;4.height:除auto之外的任意值;5.width:除auto之外的任意值;6.zoom:除normal以外的任意值;7.overflow不可见(仅限IE7)。这也是我们在IEhack中经常看到“height:1%”、“zoom:1”、“display:inline-block”、“overflow:hidden”这些词的主要原因,其实就是让元素有布局嘛!所以在IE6-7下,除了用clear:both清除浮动(不能用::after伪元素),还有一个方法就是让父元素有layout。更多关于清花车的讨论可以在一个很酷的博客中找到:那些年我们一起清过的花车。综上所述,学习任何一门语言或一件事都不能糊里糊涂,抱着前人播种,后人收获的想法。尽管站在巨人的肩膀上可以少走很多弯路,但个人还是需要保持好奇心、求知欲和质疑精神。多思考“为什么”,少思考“应该这样做”,这在CSS的学习中尤为重要。CSS很简单,她的出现只是为了排版。CSS很复杂,一个简单的排版往往有N种解决方案。我希望你能分享你的鼓励。