CSS世界(txt+pdf+epub+mobi电子书下载)


发布时间:2020-05-09 20:26:23

点击下载

作者:张鑫旭

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

CSS世界

CSS世界试读:

前言

我为什么会写这本书

我是一个利他主义非常明显的人,这多半与小时候都是在他人的帮助下成长有关,帮助我的有亲戚、邻居、老师,以及很多不认识的人。所以,现在的自己总是很乐意帮助他人成长。

我从2007年读大三的时候开始接触并使用CSS,到现在已经整整10年了,在这10年时间里,我从未间断过对CSS的研究和学习。现在想想,能够坚持下来还真是不容易,其核心动力其实就是上面的“帮助他人,成就自我”。

开始的时候,我和大多数人一样,因为CSS简单,一开始成长很快,页面写多了之后还能够总结出一些准则之类的东西,并自我感觉良好,或许是自己运气好,误打误撞走出了庐山幻境,突破了学习CSS的一个又一个瓶颈。但是,在与诸多同行的邮件交流中我发现,很多CSS开发人员感到迷茫,职位得不到重视,技术也无法提高,我感觉邮件的交流一次最多只能帮助一个人,效率实在太低。

人在做抉择的时候是需要有一些指引的。实际上,很多年前,我自己曾犹豫过,是否要继续深入学习CSS,探索每一个边界,因为对于个人而言,这会是一件吃力不讨好的事情,对于CSS这门语言,3年学习80分和10年学习90分对于产品价值的区别其实有限。但那一封封交流邮件坚定了自己的方向,艰苦的路让我一个人走就好了,等我踏遍整个CSS世界,再把完整的地图绘制出来,岂不就能帮助更多人了?

所以,随着自己的不断前行,身边的人越来越少,少到好像就我一个人,无比孤寂的时候,让我坚持下来的就是“日后可以帮助更多人,是很有价值的”的信念。

10年过去了,10年的努力和付出终于开始开花结果,而其中一个果实就是《CSS世界》这本书。

10年风雨积累,踏遍CSS世界的千山万水,哪里有美景,哪里有秘境,哪里是陷阱,哪里是路径,我全了然于心。我这样做为的就是给予清晰明确的指引,拓展对CSS世界的认知,挖掘CSS的潜力,帮助他人突破一个又一个CSS学习的瓶颈。为何需要这本CSS进阶书

大家应该都注意到了,最近行业非常缺前端开发人员,前端开发人员培训机构也如雨后春笋般大量涌现。拨开眼前的面纱,定睛一看,会发现,缺的其实不是前端,而是优秀的、有资历的、技术有深度的前端开发人员。

通过和一些前端同行、某些人力资源接触和我收到的诸多简历我发现,目前的现状是这样的:行业里有很大一拨儿人,也自称为前端开发人员,但他们仅仅是可以根据设计稿写出页面这种水平。换句话说,就是会HTML和CSS以及一点儿JavaScript。环顾四周,这种程度的人实在是太多了,完全没有任何技术上的优势。虽然这些也是前端开发人员,但是公司要抢的前端开发人员并不是这类人。

为什么会这样呢?

因为CSS这门语言入门实在是太简单了,比如说我夫人,完全不懂代码,我手把手教她1个星期,写出一个长得像某某网首页的页面绝对是没问题的,因为CSS常用属性就那么多,且鲜有逻辑,无须算法,熟记各个属性值对应的特性就能上手了。所以,很多没有编程基础的人,就通过HTML和CSS进入了这个圈子。但当他们发现自己可以很愉快地实现页面的时候,就会觉得CSS也就这样,导致困于庐山,止步不前,就算日后听到或见到“CSS深入很难”的言论并打算着手精进,也不知道接下来该怎么走、如何突破现有的瓶颈,于是就产生了迷茫。

这类高不成低不就的前端人员急需本书深入“CSS世界”,突破瓶颈,告别迷茫。

在这个世界上,越是看似简单的东西反而越是难以深入,就好比为何1+1等于2?CSS这门语言也是如此。很多自认为学了CSS有八九成的人,实际上仅仅是熟记CSS手册中的各种属性,或者理解一些CSS概念,再进一步,甚至对某一两个CSS属性有过深入的分析。但是,这些人依然无法理解很多页面上看似简单的现象(我想更多的是根本就没在意这些现象),也无法基于现有的规则创造一些完全创新的CSS实现,仅仅停留在熟练地使用这种程度。

为什么会这样呢?那是因为CSS是一门有别于传统程序语言的语言。绝大多数编程语言,比方说JavaScript,各种字符串、数组、方法,记住一个就是一个,使用的时候,forEach()就是循环,replace()就是替换,不要担心执行replace()的时候字符串突然增加了!很多人就是用这种思路学习CSS的,导致很快就遇到了天花板。为什么呢?这是因为,在CSS的世界里,页面上的任何看似简单的呈现都是由许许多多CSS属性共同作用的结果。例如,对于一个图片浮动,单纯认为只有float在工作是不全面的,实际上,行高、字体、鼠标手形等都在暗地里“搞鬼”,此时如果仅仅套用一两个CSS属性值应有的表现来理解,是根本理解不了的。换句话说,有些人的CSS水平之所以停滞不前,是因为他们没有把所有的CSS当作一个整体,放在一个完整的世界中去看待。所以,没有比“学CSS看看CSS中文手册就够了”更愚蠢的言论了,手册仅仅是表层的、独立的一些特性,每个CSS属性在CSS世界中都是有其存在的原因的,都是和其他多个CSS属性发生着千丝万缕的关系的,这背后的种种远比他们想象得要庞大很多。

而本书完完全全区别于传统教条式的手册或参考书或教程之类,一步一步带领读者接触真正丰富多彩、妙趣横生的CSS世界,一番畅快自在的CSS世界之旅下来,读者一定会得到不一样的“洗礼”,困扰多年的CSS成长瓶颈说不定就会不知不觉地突破了。如何正确认识本书

首先,大家务必明确这一点,那就是本书的所有内容都是我个人的理解。没错,是人的理解,不是干巴巴的文档。这些理解是我自己多年持之以恒对CSS研究和思考后,经过个人情感润饰和认知提炼加工的产物,完全是我自己所理解和认识的CSS世界,可能是不具有权威性的。写这本书主要是希望通过分享自己的心得给对CSS感兴趣的各个领域的人以启迪,引发其思考,或者使其有不一样的感悟。

从另一方面讲,本书正是因为其内容都是经过人这个个体的加工,并融入了情感化的思维,才能做到有的放矢、通俗易懂。我们大多数人都是感性的,看伤感电影会哭,看综艺节目会笑。所以,与干巴巴的教条式的技术书籍相比,本书的表达方式和语言风格更能给人以心灵的启迪。读完之后,读者可能会有这样的想法:要是所有的技术书都这么写就好了。

另外,本书不是技术文档,也不是参考手册,因此知识点不会面面俱到,也就是说,不少CSS相关的内容我会忽略,例如,选择器这一部分最多提一下。同时,为了保证书的内容足够简练,简单的CSS语法和常规的使用在本书中基本上不会提及,只会重点分析在其他地方看不到的内容。配套网站

我专门为本书制作了一个网站(http://www.cssworld.cn),在这个配套网站读者可以了解更多关于本书或者我个人的一些信息。

最后,由于很多内容都是个人理解,难免会有不准确或者让大家产生怀疑的地方,欢迎去官方论坛http://bbs.cssworld.cn/对应版块进行提问或反馈。特别感谢

衷心感谢人民邮电出版社的每一个人。

感谢人民邮电出版社的编辑杨海玲,她的专业建议对我帮助很大,她对细节的关注令人印象深刻,她使我的工作变得更加轻松。

感谢那些致力于提高整个行业CSS水平而默默努力的优秀人士,感谢那些在我成长路上指出错误的前端同仁,是你们让我在探索边界的道路上可以走得更快、更踏实。

感谢读者,你们的支持给了我工作的动力。

最后,最最感谢我的妻子丹丹,没有她在背后的爱和支持,本书一定不会完成得这么顺利。第1章概述

要深入理解一个事物之前,最好先对其整体有个大概了解,这样才不至于蠡测管窥。如果把CSS比作一座大山,则我们对整体的认知就好比知道这座山的位置、山势、道路状况等,这样,当我们深入其中的时候,就不容易迷路,不会做出错误的决策。

例如,对CSS这门语言特性的描述就有助于对CSS的整体认知。具体表现为:擅长C++或者Java之类的程序员学习CSS往往没有如鱼得水的感觉,其背后的原因是,典型的计算机开发语言看重逻辑思维和抽象能力,但是CSS这门语言本身并无逻辑可言,看重的是特性间的相互联系和具象能力。

具象往往以情感为纽带,无意识不自觉产生,是非常感性的一种能力,这往往是偏理性的程序员所不擅长的。在某些程序员眼中,CSS属性就是干巴巴的属性,无法建立类似“人与人关系”这种很情感化的联系,于是学习CSS总是只得其形、不得其髓。

当然,认知可以从多个角度进行。例如,接下来要介绍的CSS“世界观”以及CSS的历史故事,可以让我们多种角度同时进行认知,对CSS这门语言的理解更为准确和丰满。1.1 CSS世界的“世界观”

对于CSS这门语言,我学习和研究已经有10年之久,在点点滴滴的积累中,逐渐形成了一套完整的体系。在CSS这个世界中,CSS并不是一个机械枯燥的语言,所有属性都是有血有肉、有着不同个性和身世的个体。不同的个体可以碰撞出不同的火花,激荡出异彩纷呈的故事。这里,我们不妨“脑洞大开”一下:如果把CSS世界拍成动漫的话,会是什么样子?首先,动漫名可以叫作《建筑神域》,讲述一群建筑魔法师为国家存亡惊心动魄战斗的故事。然后,出现了“Chrome王国”的几位建筑魔法师日常训练的画面。只见名为width的魔法师手持名叫选择器的法器,准确指向称为

的最普通的块状建筑魔法石,口中念道:“层叠天星,幻化有形,50%,变!”只听见一声清脆的“啪”,
魔法石宽度变成了原来的一半。然而,width却锁眉摇头,口中喃喃念道:“1毫秒,还不够快,还要再练,不然在和‘IE王国’的战斗中很难占得先机!”(如图1-1所示)。图1-1 CSS世界观示意1此时,width突然发现前面1米之处有一块之石,具有class="test"的特殊标记,立即拿出法器,念道:“类名之石,test为名,为我选择,出!”话音刚落,之石蓝色荧光一闪,明眼人都能看出来,width魔法师和魔法石现在处于契约状态。width继续念道:“层叠天星,幻化有形,50%,变!”但魔法石却没有任何变化,此时width一拍自己的脑门,似乎明白了什么,转过头对旁边的display魔法师大声叫道:“小D,这边这边,过来帮个忙……来呀,快点……”只见display迅速结束自己的练习,屁颠屁颠跑过来:“咋啦?”“此为内联之石,我无法驾驭,你帮我重塑一下。”“小问题!正好,魔法师技能委员会刚通过了我的一个新法术,我给你秀一秀?”“哟,不错啊,快让我瞅瞅!”“好嘞!”只见display拿出自己的法器,念道:“类名之石,test为名,为我选择,出!”紧接着,“层叠天星,幻化有形,flex,变!”只听见一声清脆的“啪”,在两人的合作之下,魔法石宽度也变化了(如图1-2所示)。图1-2 CSS世界观示意2“哟,很酷嘛!”width对display竖着大拇指称赞道。只见display腼腆一笑,小手在面前轻轻一挥:“就算你这么夸我,人家也不会开心的啦……”

从上面的描述可以看出,在CSS世界中,HTML是魔法石,选择器就是选择法器,CSS属性就是魔法师,CSS各种属性值就是魔法师的魔法技能,浏览器就是他们所在的“王国”,“王国”会不断更新法律法规(版本升级),决定是否允许使用新的魔法石(HTML5新标签新属性),是否允许新的魔法师入“国籍”(CSS3新属性),或者允许魔法师使用某些新技能(CSS新的属性值),以及是否舍弃某些魔法技能(如display:run-in);操作系统就是他们所在的世界,不同的操作系统代表不同的平行世界,所以,CSS世界有这么几个比较大的平行世界,即Windows世界、OS X世界以及移动端的iOS世界和Android世界。不同世界的浏览器王国的命运不一样,例如,在OS X世界中,IE王国是不存在的,而Safari王国却异常强大,但在Windows世界中,Safari王国却异常落寞。

以上这一切就构成了完整的CSS世界的“世界观”。

下面回答一个很重要的问题:为何要这样认识CSS世界呢?

首先,将抽象的CSS直接和具体的现实世界相对应,更加易于理解。试想一下,对于普通人,理解魔法师和魔法石是不是要比理解CSS代码容易得多?其次,以完整的体系来学习CSS要比单纯关注属性值理解得更加深刻,可以培养从宏观层面认识与理解CSS的习惯。再次,这也方便我们记忆,枯燥的代码总是过目就忘,鲜活的角色总是印象深刻。最后,这样也可以让本书散发出与众不同的气质。1.2 世界都是创造出来的

世界都是创造出来的。很自然,CSS世界也是一点一点创造出来的。这世间上的事情只要发生了,都是有原因的。CSS世界的出现也不例外。

下面我们就来看一下CSS世界出现的历史。虽然我知道,有些人对这些历史可能不感兴趣,但是要想深入理解CSS属性的一些设计原因、表现原理还真离不开当时的历史环境。

大家可能都听说过马云1995年去美国,第一次接触了互联网,在这个时间点,HTML才是第一版且诞生没几年,W3C才刚刚成立,CSS还没出现。那时候的互联网几乎都是文字信息,显示一张图片都是要上天的感觉。

大家可能没意识到,那个时候前端的发展和现在一样快,设计师要求越来越多,HTML也越来越庞杂。急需要其他专门负责样式的语言,据说当时有几个样式表语言,最后是CSS胜出了,为什么呢?它的胜出靠的是“层叠”特性。

CSS全称是Cascading Style Sheets,翻译成中文就是“层叠样式表”。所谓“层叠”,顾名思义,就是样式可以层层累加,比方说页面元素都继承了12像素的大小,某标题就可以设置成14像素进行叠加。发现没?这种层叠策略对于样式的显示是相当的灵活。

于是,从1996年12月17日CSS1诞生后,CSS在样式呈现领域可谓所向披靡,没有遇到任何竞争对手。1998年5月12日CSS2发布,推行内容和表现分离,表格(table)布局开始落寞。

1998年腾讯、新浪和网易成立,当时搜狐则成立1年不到。那个时候是门户的时代,人们更关注的是信息的获取,所以网站的功能主要就是信息展示,信息是什么?在那个时代,在互联网领域,信息就是图片和文字。换句话说,那时候的网站前端技术关心的是图片和文字的呈现,而CSS2(包括9年之后,也就是2007年才出现的CSS2.1)都是为图文展示服务的。

我再重复一遍:CSS世界的诞生就是为图文信息展示服务的。这句话在本书中会非常频繁地出现,知道这一点你就会明白很多事情。

好,下面让我们回到本节开头的那句话——“世界都是创造出来的”!为何我要反复强调这句话呢?如果站在造物主的角度去思考CSS世界的种种表现,很多问题就会迎刃而解。

现在给你机会当一回造物主,让你自己重新构建一个CSS世界,唯一的要求就是,这个世界要非常便于图片和文字的呈现,你会去如何构建呢?1.3 CSS完胜SVG的武器——流

在2003年1月,SVG 1.1被确立为W3C标准。你没看错,是2003年。要知道,CSS 2.1是2007年才发布的。考虑到SVG开始火起来是最近几年,也就是差不多10年的时间,SVG都默默无闻,鲜有人问津,到底是怎么回事呢?

很多人认为SVG的竞争对手是Flash。对,是竞争对手。但是,现在看来,SVG显然要比Flash优秀很多,SVG开放、标准,和CSS和JavaScript都能很方便地进行交互,如果单纯SVG和Flash比,难说谁胜谁负。在我看来,造成SVG被冷落10年的原因不是别的,正是看似毫不相关的CSS,SVG是被CSS给打败的。

正如上面提到的,在很长一段时间里,网站的主要功能都是图片和文字信息的展示,但是,SVG的强项是图形,其文字内容的呈现实在不敢恭维。举个例子,在CSS中写上一段文字,这段文字会自然换行、多行显示,于是,可以像书本一样阅读;但是,在SVG中,文字要自动折行,感觉有点儿赶鸭子上架——强人所难。人家一看,SVG连基本的文字排版都做不好,要SVG何用?于是,SVG被“打入冷宫”,CSS一如既往被重用。

但是,如今技术得到了发展,Web呈现更加复杂和丰富多彩,图文显示仅仅是网页功能的一部分,于是,矢量且图形领域颇有造诣的SVG开始迎来了自己的第一春。

不知大家有没有思考过这样的问题:为什么CSS世界的图文显示能力那么强?为什么它可以抑制SVG这么多年?

答案就是:流!1.3.1 何为“流”

和CSS有过亲密接触的人一定听过“文档流”这个概念,我个人总是习惯把“文档”二字去掉,直接称为“流”(纯粹个人爱好,因为够简洁)。听过它的人很多,但是,深入思考过“何为流?”这个问题的人怕是就没这么多了。

那究竟CSS世界中的“流”指的是什么呢?“流”实际上是CSS世界中的一种基本的定位和布局机制,可以理解为现实世界的一套物理规则,“流”跟现实世界的“水流”有异曲同工的表现。

现实世界中,如果我们让水流入一个容器,水面一定是平整的;我们在水里面放入物体,如普通的木头,此时水位就会上升,木头多半浮在水面上,但只露出一点点头,如图1-3所示。这些现象我们都会认为是理所当然的,因为这就是我们从小接触的一套物理规则。我们知道这套规则,就可以理解现象,并且预知现象。例如,水量超过容器的容积很多,我们就可以预测到水会溢出来。

感谢物理学,它让我们理解CSS世界的“流”就轻松多了。CSS世界的“流”似乎就是按照物理世界的“水流”创造的。

CSS世界构建的基石是HTML,而HTML最具代表的两个基石

正好是CSS世界中块级元素和内联级元素的代表,它们对应的正是图1-3所示的盛水容器中的水和木头,其特性表现也正如现实世界的水和木头,如图1-4所示。图1-3 流图1-4 CSS世界构建的基石HTML

所以,所谓“流”,就是CSS世界中引导元素排列和定位的一条看不见的“水流”。1.3.2 流是如何影响整个CSS世界的

在CSS2.1时代,我们直接称CSS为“流的世界”真是一点儿也不为过,整个CSS世界几乎就是围绕“流”来建立的,那么流是如何影响整个CSS世界的呢?(1)擒贼先擒王。因为CSS世界的基石是HTML,所以只要让HTML默认的表现符合“流”,那么整个CSS世界就可以被“流”统治,而事实就是如此!(2)特殊布局与流的破坏。如果全部都是以默认的“流”来渲染,我们只能实现类似W3C那样的文档网页,但是,实际的网页是有很多复杂的布局的,怎么办?可以通过破坏“流”来实现特殊布局。实际上,还是和“流”打交道。(3)流向的改变。默认的流向是“一江春水向东流”,以及“飞流直下三千尺”。然而,这种流向我们是可以改变的,可以让CSS的展现更为丰富。因此,“文档流从左往右自上而下”这种说法是不严谨的,大家一定要纠正过来。

好了,下面我想反问大家:如果你是造物主,你会想到设计“流”这套机制来实现强大的图文排列功能吗?

好好想一想……是不是觉得目前CSS的设计还是很有智慧的?如果你来重新设计CSS,实现图文排列,你是否还有其他的设计思路,比方说“亲缘机制”之类?

适当地反问这些问题,通过逆向思维,会让我们对CSS世界有另外一个角度的认识。1.3.3 什么是流体布局

所谓“流体布局”,指的是利用元素“流”的特性实现的各类布局效果。因为“流”本身具有自适应特性,所以“流体布局”往往都是具有自适应性的。但是,“流体布局”并不等同于“自适应布局”。“自适应布局”是对凡是具有自适应特性的一类布局的统称,“流体布局”要狭窄得多。例如,表格布局也可以设置为100%自适应,但表格和“流”不是一路的,并不属于“流体布局”。

CSS中最常用的魔法石,也就是最常使用的HTML标签,是

,而
是典型的具有“流”特性的元素,因此,曾经风靡的“div+CSS布局”,实际上指的就是这里的“流体布局”。1.4 CSS世界的开启从IE8开始

本书书名为《CSS世界》,这里的“世界”特指的是CSS2.1的世界,并不包括CSS3,CSS3的世界更为庞杂和宏大,但CSS2.1的世界已经足够我们畅游很多年了。现在前端技术发展迅猛,加上氛围略显浮躁,有必要让广大前端开发人员静下心来认识CSS2.1的世界,否则面对CSS3的真正到来,只能是浅水游弋、搬砖打杂。

对CSS2.1的全面支持是从微软公司的IE8开始的,因此,本书中几乎所有特性、行为表现都是针对IE8以上浏览器的。1.5 table自己的世界

如果我没记错的话,

比CSS还要老,也就是CSS正式诞生之前,
就已经出现了。前面提到了“流影响了整个CSS世界”,其中并不包括
有着自己的世界,“流”的特性对
并不适用,一些CSS属性的表现,如单元格的vertical-align,也和普通的元素不一样。

虽然CSS2.1加强了和

的联系,如对table类别的display属性值的支持等,但是本书并不会对
进行专门的介绍,因为毕竟不是同一个世界的。1.6 CSS新世界——CSS3

时代在变迁,科技在发展,人们对互联网的需求也在变化,以前的以图文展示为主的门户网站已经无法满足用户的需求。技术总是随着需求发展的,正如10年前的图文展示需求缔造了CSS世界一样,如今的移动互联网以及硬件发展也带动CSS进入了新的世界。(1)布局更为丰富。● 移动端的崛起,催生了CSS3媒介查询以及许多响应式布局特性

的出现,如图片元素的srcset属性、CSS的object-fit属性。● 弹性盒子布局(flexible box layout)终于熬出了头。● 格栅布局(grid layout)姗姗来迟。(2)视觉表现长足进步。● 圆角、阴影和渐变让元素更有质感。● transform变换让元素有更多可能。● filter滤镜和混合模式让Web轻松变成在线的Photoshop;● animation让动画变得非常简单。

上面提到的全部都是CSS3的新属性。因为CSS3的设计初衷是为了实现更丰富、更复杂的网页,所以基本上和“流”的关系并不大。可以说,和CSS2相比CSS3就是一个全新的世界,更加丰富,更加规范,更加体系化,也更加复杂。考虑到CSS3尚未完全成型,且自己尚未有足够深入的研究,无法同时驾驭太复杂的内容,因此,本书不会深入CSS3的知识点。第2章需提前了解的术语和概念2.1 务必了解的CSS世界的专业术语

尽管本书内容会用很轻松的方式表达,但还是避免不了会出现一些CSS领域的专业术语。因此,在学习技术内容之前,我们需要先了解一下CSS世界里的一些专业术语。

首先,假设我们现在有如下一段常见的CSS代码:.vocabulary {  height: 99px;  color: transparent;}

下面就针对这段代码,逐一引出其涉及的专业术语。1.属性

属性对应的是平常我们书面或交谈时对CSS的中文称谓。例如,上面示意CSS代码中的height和color就是属性。当我们聊天或者分享时说起CSS的时候,嘴里冒出来的都是“这个元素高度99像素”,或者“这个文字颜色透明”,对吧?这里提到的“高度”和“颜色”就是CSS世界的属性,感觉有点儿像现实世界里人的姓氏。2.值“值”大多与数字挂钩。例如,上面的99px就是典型的值。在CSS世界中,值的分类非常广泛,下面是一些常用的类型。● 整数值,如z-index:1中的1,属于,同时也属于

。● 数值,如line-height:1.5中的1.5,属于。● 百分比值,如padding:50%中的50%,属于。● 长度值,如99px。● 颜色值,如#999。

此外,还有字符串值、位置值等类型。在CSS3新世界中,还有角度值、频率值、时间值等类型,这里就不全部展示了。3.关键字

顾名思义,关键字指的是CSS里面很关键的单词,这里的单词特指英文单词,abc是单词吗?不是,因此,如果CSS中出现它,一定不是关键字。上面示例CSS代码中的transparent就是典型的关键字,还有常见的solid、inherit等都是关键字,其中inherit也称作“泛关键字”,所谓泛关键字,可以理解为“公交车关键字”,就是“所有CSS属性都可以使用的关键字”的意思。4.变量

CSS中目前可以称为变量的比较有限,CSS3中的currentColor就是变量,非常有用。不过,这属于《CSS新世界》的内容,本书不会详细阐述,有兴趣的读者可以访问http://www.zhangxinxu.com/wordpress/?p=4385或者扫右侧的二维码,做简单的了解。5.长度单位

CSS中的单位有时间单位(如s、ms),还有角度单位(如deg、rad等),但最常见的自然还是长度单位(如px、em等)。需要注意的是,诸如2%后面的百分号%不是长度单位。再说一遍,%不是长度单位!因为2%就是一个完整的值,就是一个整体,我想你一定认为0.02是值,没错,2%也同样是值。

有人可能会有疑问,我就认为%是单位,有什么关系,页面还是长那样,有必要这么较真吗?

问的很在理,如果大家平时没有看原始文档的习惯,没必要较真,知道怎么使用就好了。但是,如果经常去MDN或W3C看一些CSS技术文档,搞清楚概念,看文档的时候就不容易犯迷糊,就不会看不懂具体说些什么,尤其都是英文的时候。

可能有人会有疑问,“值”那里提到的,貌似和这里的“长度单位”比较暧昧啊?好眼力!没错,确实暧昧,但暧昧是不好的,我们必须把它们之间的关系搞清楚。一句话: + 长度单位 =

如果继续细分,长度单位又可以分为相对长度单位和绝对长度单位。(1)相对长度单位。相对长度单位又分为相对字体长度单位和相对视区长度单位。● 相对字体长度单位,如em和ex,还有CSS3新世界的rem和

ch(字符0的宽度)。● 相对视区长度单位,如vh、vw、vmin和vmax。(2)绝对长度单位:最常见的就是px,还有pt、cm、mm、pc等了解一下就可以,在我看来,它们实用性近乎零,至少我这么多年一次都没用过。6.功能符

值以函数的形式指定(就是被括号括起来的那种),主要用来表示颜色(rgba和hsla)、背景图片地址(url)、元素属性值、计算(calc)和过渡效果等,如rgba(0,0,0,.5)、url('css-world.png')、attr('href')和scale(-1)。7.属性值

属性冒号后面的所有内容统一称为属性值。例如,1px solid rgb(0,0,0)就可以称为属性值,它是由“值+关键字+功能符”构成的。属性值也可以由单一内容构成。例如,z-index:1的1也是属性值。8.声明

属性名加上属性值就是声明,例如:color: transparent;9.声明块

声明块是花括号({})包裹的一系列声明,例如:{  height: 99px;  color: transparent;}10.规则或规则集

出现了选择器,而且后面还跟着声明块,比如本小节一开始的那个例子,就是一个规则集:.vocabulary {  height: 99px;  color: transparent;}11.选择器

选择器是用来瞄准目标元素的东西,例如,上面的.vocabulary就是一个选择器。● 类选择器:指以“.”这个点号开头的选择器。很多元素可以应用

同一个类选择器。“类”,天生就是被公用的命。● ID选择器:“#”打头,权重相当高。ID一般指向唯一元素。但是,

在CSS中,ID样式出现在多个不同的元素上并不会只渲染第一

个,而是雨露均沾。但显然不推荐这么做。● 属性选择器:指含有[]的选择器,形如[title]{}、[title= "css-world"]

{}、[title~="css-world"]{}、[title^="css-world"]{}和[title$="css-

world"]{}等。● 伪类选择器:一般指前面有个英文冒号(:)的选择器,如:first-

child 或:last-child等。● 伪元素选择器:就是有连续两个冒号的选择器,如::first-

line::first-letter、::before和::after。12.关系选择器

关系选择器是指根据与其他元素的关系选择元素的选择器,常见的符号有空格、>、~,还有+等,这些都是非常常用的选择器。● 后代选择器:选择所有合乎规则的后代元素。空格连接。● 相邻后代选择器:仅仅选择合乎规则的儿子元素,孙子、重孙元

素忽略,因此又称“子选择器”。>连接。适用于IE7以上版本。● 兄弟选择器:选择当前元素后面的所有合乎规则的兄弟元素。~

连接。适用于IE7以上版本。● 相邻兄弟选择器:仅仅选择当前元素相邻的那个合乎规则的兄弟

元素。+连接。适用于IE7以上版本。13.@规则

@规则指的是以@字符开始的一些规则,像@media、@font-face、@page或者@support,诸如此类。2.2 了解CSS世界中的“未定义行为”

当某个浏览器中出现与其他浏览器不一样的行为或样式表现的时候,我们总会习惯把这种不一样的表现认为是浏览器的bug。但在CSS世界,这种认识是狭隘的。

在现实世界中,有法律来约束我们的行为,如果越界,就称为违法;同样地,在CSS世界里,有Web标准来约束元素的行为,如果越界,就称为bug。但是,法律总是人制定的,世间万象是不可能面面俱到的,会存在法律空白;同样地,Web应用场景千变万化,Web标准也是不可能面面俱到的,也会存在规范描述以外的场景,此时,各大浏览器厂家只能根据自己的理解与喜好去实现,一旦个性化就会出现差异,就会遇到“火狐火狐,你怎么啦?平时表现挺好的,今天怎么被IE带坏了?”的情景。实际上,此时遇到的表现差异并不是浏览器的bug,用计算机领域的专业术语描述应该是“未定义行为”(undefined behavior)。

下面我们来看一个“未定义行为”的例子。

CSS世界中有很多伪类,其中一个比较常用的就是:active,在IE8及以上版本的浏览器行为表现非常统一,支持非焦点元素,鼠标按下,执行:active伪类对应的CSS样式,鼠标抬起还原。

通用情况下,:active的表现都是符合预期的,但是,当遭遇其他一些处理的时候,事情就会变得不一样,具体指什么处理呢?

假设我们现在有一个标签模拟的按钮,CSS如下:a:active { background-color: red; }

假设此按钮的DOM对象变量名为button,JavaScript代码如下:button.addEventListener("mousedown", function(event) {  // 此处省略N行  event.preventDefault();});

也就是鼠标按下的时候,阻止按钮的默认行为,这样设置可以让拖动效果更流畅。

看似平淡无奇的一段代码,最后却发生了意想不到的情况:Firefox浏览器的:active阵亡了,鼠标按下去没有UI变化,按钮背景没有变红!其他所有浏览器,如IE和Chrome浏览器,:active正常变红,符合预期。

眼见为实,手动输入http://demo.cssworld.cn/2/2-1.php或者扫下面的二维码。图2-1左图所示为目标效果,右图所示是Firefox浏览器中的效果。图2-1 Firefox浏览器:active的作用效果

这里,Firefox和IE/Chrome浏览器表现不一样,这是Firefox浏览器的bug吗?这可不是bug,而是因为规范上并没有对这种场景的具体描述,所以Firefox认为:active发生在mousedown事件之后,你也不能说它什么,对吧?

像这种规范顾及不到的细枝末节的实现,就称为“未定义行为”。第3章流、元素与基本尺寸

第1章提过了,“流”之所以影响了整个CSS世界,就是因为影响了CSS世界的基石HTML。那具体是如何影响的呢?

HTML常见的标签有

  • 和以及、和等。虽然标签种类繁多,但通常我们就把它们分为两类:块级元素(block-level element)和内联元素(inline element)。
  • 注意,如果按照W3C的CSS规范区分,这里应该分为“块级元素”和“内联级元素” (inline-level element)。但是,在W3C的HTML4规范中,已经明确把HTML元素分成了“块级元素”和“内联元素”,没错,是“内联元素”而不是“内联级元素”。两个规范貌似有微小的冲突。本书中所采用的是“内联元素”这种称谓,原因有两点:第一,这种称谓更亲切、更自然,因为大家平时都是这么叫的;第二,使用“内联元素”这个称谓对我们深入理解与内联相关的概念并没有什么影响。考虑到本书的目的不是为CSS规范做科普,而是以通俗易懂方式展示CSS的精彩世界,所以,采用了更老一点的HTML规范中的叫法。3.1 块级元素“块级元素”对应的英文是block-level element,常见的块级元素有

  • 和等。需要注意是,“块级元素”和“display为block的元素”不是一个概念。例如,
  • 元素默认的display值是list-item,
  • 元素默认的display值是table,但是它们均是“块级元素”,因为它们都符合块级元素的基本特征,也就是一个水平流上只能单独显示一个元素,多个块级元素则换行显示。
  • 正是由于“块级元素”具有换行特性,因此理论上它都可以配合clear属性来清除浮动带来的影响。例如:.clear:after {  content: ''; display: table; // 也可以是block,或者是list-item  clear: both;}

    手动输入http://demo.cssworld.cn/3/1-1.php或者扫右侧的二维码。

    从容器的背景色高度变化我们可以看出清除的效果,如图3-1所示。图3-1 容器的背景色高度变化的效果

    实际开发时,我们要么使用block,要么使用table,并不会使用list-item,主要有3个原因。(1)1个字符的比较多,其他都是5个字符。(2)会出现不需要的项目符号,如图3-2箭头所示。这其实并不是什么大问题,再加一行list-style:none声明就可以了。(3)IE浏览器不支持伪元素的display值为list-item。这是不使用display:list-item清除浮动的主因,兼容性不好。对于IE浏览器(包括IE11),普通元素设置display:list-item有效,但是:before/:after伪元素就不行。图3-2 出现项目符号

    下面是提问环节了。请问,为什么IE浏览器不支持伪元素的display值为list-item呢?

    其实这个问题的答案可以从下面这个问题中找到线索:请问,为什么设置display:list-item,元素会出现项目符号?3.1.1 为什么list-item元素会出现项目符号

    在CSS世界中,很多看似“理所当然”的现象的背后,实际上可能有一整套的体系支撑。挖掘简单现象背后的原因,会让你学到很多别人很难学到的CSS技能和知识。

    回到这个问题。此问题本身并不难,但是,问题所能延伸出来的东西就要吓到诸位了。此问题牵扯到CSS世界中各种盒子。

    由于牵扯名词甚多,所以我尽量以通俗易懂的方式给大家解释。

    创造CSS的造物主原本的想法很简单:我要创造一个世界,就像只有男性和女性一样,这个世界只有块级盒子(block-level box)和内联盒子(inline box)。块级盒子就负责结构,内联盒子就负责内容。事非经过不知难,造物主后来才发现,这世界不止有男性和女性,还有特殊的性别,CSS世界的盒子也是这样。

    原本以为块级盒子一套就够用了,也就是所有“块级元素”就只有一个“块级盒子”,但是,半路杀出个list-item,其默认要显示项目符号的,一个盒子解释不了,怎么办?

    就跟我们写JavaScript组件遇到新功能增加API一样,天神灵机一动:我给list-item再重新命名一个盒子,就叫“附加盒子”。好了,这下顺了,所有的“块级元素”都有一个“主块级盒子”,list-item除此之外还有一个“附加盒子”。

    现在大家知道上面问题的答案了吧!之所以list-item元素会出现项目符号是因为生成了一个附加的盒子,学名“标记盒子”(marker box),专门用来放圆点、数字这些项目符号。IE浏览器下伪元素不支持list-item或许就是无法创建这个“标记盒子”导致的。

    但是,我们的故事还没结束。搞定了list-item,天神本以为可以安安心心睡个午觉,结果碰到了真正的特殊性别的display:inline-block元素。

    穿着inline的皮藏着block的心,现有的几个盒子根本没法解释啊,怎么办?

    造物主再次灵机一动,没错,你猜对了,又新增一个盒子,也就是每个元素都两个盒子,外在盒子和内在盒子。外在盒子负责元素是可以一行显示,还是只能换行显示;内在盒子负责宽高、内容呈现什么的。但是呢,造物主又想了想,叫“内在盒子”虽然容易理解,但是未免有些俗气,难登大雅之堂,于是,又想了一个更专业的名称,叫作“容器盒子”。

    于是,按照display的属性值不同,值为block的元素的盒子实际由外在的“块级盒子”和内在的“块级容器盒子”组成,值为inline-block的元素则由外在的“内联盒子”和内在的“块级容器盒子”组成,值为inline的元素则内外均是“内联盒子”。

    现在,大家应该明白为何display属性值是inline-block的元素既能和图文一行显示,又能直接设置width/height了吧!因为有两个盒子,外面的盒子是inline级别,里面的盒子是block级别。

    实际上,如果遵循这种理解,display:block应该脑补成display:block-block,display:table应该脑补成display:block-table,我们平时的写法实际上是一种简写。

    好了,说了这么多,出个小题测试一下大家的学习成果。请问:display:inline-table的盒子是怎样组成的?3.1.2 display:inline-table的盒子是怎样组成的

    这个问题应该无压力:外面是“内联盒子”,里面是“table盒子”。得到的就是一个可以和文字在一行中显示的表格。

    可以和文字在一行中显示的表格?没错,为了证明我没忽悠大家,我特意做了个演示页面,演示页面中

    元素的相关CSS代码如下:.inline-table {  display: inline-table;  width: 128px;  margin-left: 10px;  border: 1px solid #cad5eb;}

    手动输入http://demo.cssworld.cn/3/1-2.php或者扫下面的二维码。结果该元素和文字一行显示,且行为表现如同真正的表格元素(子元素宽度等分),如图3-3所示。图3-3 表格元素和文字在一行显示

    上面示意的CSS代码表面上看起来很简单,但是,我也说过,简单的背后往往是不简单。这里CSS中有个width:128px,从最终的效果来看,宽度设置是起作用了。如果我们使用display:inline-block也会是同样的宽度表现。下面问题来了:元素都有内外两个盒子,我们平常设置的width/height属性是作用在哪个盒子上的?3.1.3 width/height作用在哪个盒子上

    这个问题也是很简单的,因为在解释内外盒子的时候就已经提到过了:是内在盒子,也就是“容器盒子”。

    不知大家有没有进一步深入思考过:width或height作用的具体细节是什么呢?3.2 width/height作用的具体细节

    因为块级元素的流体特性主要体现在水平方向上,所以我们这里先着重讨论width。

    估计很多人的第一次CSS属性书写就献给了width,就像路边的小草,好常见、好平淡、好简单的样子。如果你有这样的想法,此书你就买对了。3.2.1 深藏不露的width:auto

    我们应该都知道,width的默认值是auto。auto因为是默认值,所以出镜率不高,但是,它却是个深藏不露的家伙,它至少包含了以下4种不同的宽度表现。(1)充分利用可用空间。比方说,

    这些元素的宽度默认是100%于父级容器的。这种充分利用可用空间的行为还有个专有名字,叫作fill-available,大家了解即可。(2)收缩与包裹。典型代表就是浮动、绝对定位、inline-block元素或table元素,英文称为shrink-to-fit,直译为“收缩到合适”,有那么点儿意思,但不够形象,我一直把这种现象称为“包裹性”。CSS3中的fit-content指的就是这种宽度表现。(3)收缩到最小。这个最容易出现在table-layout为auto的表格中,想必有经验的人一定见过图3-4所示的这样一柱擎天的盛况吧!

    眼见为实,有兴趣的读者可以手动输入http://demo.cssworld.cn/3/2-1.php或者扫下面的二维码。图3-4 单元格中的一柱擎天效果

    当每一列空间都不够的时候,文字能断就断,但中文是随便断的,英文单词不能断。于是,第一列被无情地每个字都断掉,形成一柱擎天。这种行为在规范中被描述为“preferred minimum width”或者“minimum content width”。后来还有了一个更加好听的名字min-content。(4)超出容器限制。除非有明确的width相关设置,否则上面3种情况尺寸都不会主动超过父级容器宽度的,但是存在一些特殊情况。例如,内容很长的连续的英文和数字,或者内联元素被设置了white-space:nowrap,则表现为“恰似一江春水向东流,流到断崖也不回头”。

    例如,看一下下面的CSS代码:.father {  width: 150px;  background-color: #cd0000;  white-space: nowrap;}.child {  display: inline-block;  background-color: #f0f3f9;}

    这段代码的结果如图3-5所示。图3-5 文字超出容器也不换行示意

    子元素既保持了inline-block元素的收缩特性,又同时让内容宽度最大,直接无视父级容器的宽度限制。这种现象后来有了专门的属性值描述,这个属性值叫作max-content,这个属于CSS3新世界内容,本书点到为止,不深究。

    眼见为实,若有兴趣,可以手动输入http://demo.cssworld.cn/3/2-2.php或扫右侧的二维码亲自感受一下。

    上面列举的4点就是width:auto在不同场景下的宽度表现的简介。

    在CSS世界中,盒子分“内在盒子”和“外在盒子”,显示也分“内部显示”和“外部显示”,同样地,尺寸也分“内部尺寸”和“外部尺寸”。其中“内部尺寸”英文写作“Intrinsic Sizing”,表示尺寸由内部元素决定;还有一类叫作“外部尺寸”,英文写作“Extrinsic Sizing”,宽度由外部元素决定。现在,考考大家:上面4种尺寸表现,哪个是“外部尺寸”?哪个是“内部尺寸”?

    这里就不卖关子了。就第一个,也就是

    默认宽度100%显示,是“外部尺寸”,其余全部是“内部尺寸”。而这唯一的“外部尺寸”,是“流”的精髓所在。1.外部尺寸与流体特性(1)正常流宽度。当我们在一个容器里倒入足量的水时,水一定会均匀铺满整个容器,如图3-6所示。图3-6 水流自动铺满容器示意

    在页面中随便扔一个

    元素,其尺寸表现就会和这水流一样铺满容器。这就是block容器的流特性。这种特性,所有浏览器的表现都是一致的。因此,我就实在想不通,为何那么多网站或同行会有类似下面的CSS写法。例如,一个垂直导航:a {  display: block;  width: 100%;}

    元素默认diplay是inline,所以,设置display:block使其块状化绝对没有问题,但后面的width:100%就没有任何出现的必要了。

    我很多年前总结过一套“鑫三无准则”,即“无宽度,无图片,无浮动”。为何要“无宽度”?原因很简单,表现为“外部尺寸”的块级元素一旦设置了宽度,流动性就丢失了。

    所谓流动性,并不是看上去的宽度100%显示这么简单,而是一种margin/border/padding和content内容区域自动分配水平空间的机制。

    我们来看一个简单的例子,手动输入http://demo.cssworld.cn/3/2-3.php或者扫右侧的二维码。这是一个对比演示(见图3-7),上下两个导航均有margin和padding,前者无width设置,完全借助流特性,后者宽度width:100%。结果,后者的尺寸超出了外部的容器,完全就不像“水流”那样完全利用容器空间,即所谓的“流动性丢失”。图3-7 设定宽度与流动性缺失

    当然,实际开发的时候,是不会设置宽度 100%的,毕竟有显示问题。此时,可能有人会突然灵光一现,借助流动性来实现……要是这样就好了,然而其基本上采取的策略是,发挥自己天才般的计算能力,通过“容器宽度−水平padding−水平margin=?”重新设定具体的宽度。

    于是,最终的CSS代码如下:.nav {  width: 240px;}.nav-a {  display: block;  /* 200px = 240px - 10px*2 - 10px*2 */  width: 200px;  margin: 0 10px;  padding: 9px 10px;  ...}

    典型的“砌砖头”“搭积木”式思维方式!虽然说最后的效果是一样的,但是,如果模块的宽度变化了,哪怕只变了1像素, width也需要重新计算一遍。但是,如果借助流动性无宽度布局,那么就算外面容器尺寸变化,我们的导航也可以自适应,这就是充分利用浏览器原生流特性的好处。

    因此,记住“无宽度”这条准则,少了代码,少了计算,少了维护,何乐而不为呢?

    你应该还记得前面说过display:block应该脑补成display:block-block,这是我自己想出来的,便于大家理解,CSS世界其实并没有这样的说法。虽有“臆想”成分在里面,但其实也是有理可循的。本节详细讲了块级元素的流体特性,这种特性就是体现在里面的“容器盒子”上的。所以,在CSS3最新的世界中,CSS规范的撰写者们使用了另外一个名词来表示这个内在盒子,就是“flow”,也就是本书的核心“流”。因此,display:block更规范的脑补应该是display:block flow。注意中间是空格。当然,由于规范(草案)2015年10月才发布,因此直到2017年6月为止还没有浏览器支持。好了,这属于比CSS3新世界还要新的世界的知识点,了解即可。(2)格式化宽度。格式化宽度仅出现在“绝对定位模型”中,也就是出现在position属性值为absolute或fixed的元素中。在默认情况下,绝对定位元素的宽度表现是“包裹性”,宽度由内部尺寸决定,但是,有一种情况其宽度是由外部尺寸决定的,是什么情况呢?

    对于非替换元素(见本书第4章),当left/top或top/bottom对立方位的属性值同时存在的时候,元素的宽度表现为“格式化宽度”,其宽度大小相对于最近的具有定位特性(position属性值不是static)的祖先元素计算。

    例如,下面一段CSS代码:div { position: absolute; left: 20px; right: 20px; }

    假设该

    元素最近的具有定位特性的祖先元素的宽度是1000像素,则这个
    元素的宽度是960(即1000−20−20)像素。

    此外,和上面的普通流一样,“格式化宽度”具有完全的流体性,也就是margin、border、 padding和content内容区域同样会自动分配水平(和垂直)空间。

    试读结束[说明:试读内容隐藏了图片]

    下载完整电子书


    相关推荐

    最新文章


    © 2020 txtepub下载