当前位置: 首页 > Web前端 > CSS

什么是CSS?

时间:2023-03-30 16:53:51 CSS

前言作为一个程序员,技术的落实和巩固是很有必要的,所以我想到了写一个系列叫做whywhatorhow每篇文章试图把一个问题解释清楚。为什么是什么或如何的第2章,什么是CSS?解释CSS-CascadingStyleSheets,层叠样式表CSS也是一种标记语言,它的内容作为浏览器的输入,浏览器会将其文本内容解析为HTML的附加样式信息,从而修改标签。标记语言是一种以固定形式(通常为纯文本)描述文档结构或数据处理细节的语言,其内容被用作其他程序的输入。每个人都知道样式表。记录样式信息的表以键值对的形式存在。格式如下:p{font-size:10px;}那么什么是层叠呢?级联是什么意思?Cascade,字面意思是:层层叠叠,我们知道HTML的页面结构是树状的,不同标签层层嵌套,最终组合成一个页面。从另一个角度看,页面的结构是一层一层的。如下图,html是底层,body在html层之上,header、nav、article、aside、footer在body之上,section在article之上,标签的堆叠构成了网页结构。CSS呢?先提一个问题:如果article标签代表一篇文章,内部的文字大小、样式、排版是否应该一样?是的!那么层叠样式的意义也在这里。只要我给文章标签一个固定的样式,那么文章里面的标签就会(部分)继承默认的样式信息。层级结构代表了节点之间的关系,所以会有父子层级的区别,也有继承的关系。那么有朋友会问了?这不就是现在的CSS吗?这不是默认行为吗?这对于CSS来说是正确的,但对于最初装饰HTML的样式规则来说却并非如此,CSS只是最终成为标准的众多规则之一。历史从1991年到1993年,各种浏览器相继出现,但各自执行自己的样式规则,网页的呈现由用户控制,没有统一的样式规定。1993年,Mosaic浏览器为了满足设计者的要求,增加了新型的HTML标签来表示样式,等表示样式的标签开始出现。1994年,H?konWLie提出CascadingHTMLStyleSheets,CSS的雏形出现了。1995年,W3C成立。W3C对CSS非常感兴趣并为其组织了一个研讨会。1996年完成了CSS语法,发布了CSS1.0,但是由于当时主流浏览器并不支持(各有各的样式写法),而当时主流的方式是HTML样式标签,所以CSS等了好几年才流行起来。1997年,W3C组织了一个致力于CSS的工作组。1998年,浏览器市场份额被微软的IE4和网景的NetscapeNavigator两大浏览器巨头占据。IE4率先实现了CSS1.0,但由于缺乏重视,规范的实现并不完善,bug较多。由于不同浏览器支持的标准不一致,网页设计者不得不分别为IE和NetscapeNavigator设计一套网页。WebStandardsProject(WaSP)是一群私人设计师,他们发起了一个喷子来宣传W3C的建议作为标准,并批评尚未加入W3C标准的行业供应商。1998年,W3C组织的七名成员发布了CSS2.0网络标准计划,成立了CSSSamurai,指出Opera浏览器和IE浏览器在支持CSS方面存在诸多问题。Opera公司着手解决这个问题,但微软没有。他们还说服其他浏览器开始支持CSS标准。1999年,W3C开始制定CSS3标准。2003年,DaveShea推出了一个名为CSSZenGarden(“CSSZenGarden”)的网站,旨在向人们展示只需应用不同的页面样式规则,就可以实现网页艺术风格的全新面貌。从2006年到2009年,DIV+CSS布局逐渐取代死板的传统表格布局,无表格网页设计成为网页内容布局的主流方案。2009年——至今,CSS3标准已经部分公布,但尚未完全制定,浏览器厂商正在逐步跟进。W3C官方将这些不同的特性归为模块,并且不再使用CSS3.0的版本号,而是将各个模块单独命名,每个模块也有不同的版本号。...CSS从被制定为标准并最终被浏览器实施以来,至少已经有5年的时间了。CSS的上层地位也得到了民间组织的推动,最终被浏览器厂商采纳。直到现在,我们仍然可以在HTML中使用这样的代表样式的标签,这也是历史遗留下来的产物。但是HTML5的引入,规范了HTML标签作为网页的结构,CSS规范了网页的结构。样式信息,所以那些代表样式的标签已经被规范去掉了,我们应该少用甚至不用。CSS在众多样式规则中脱颖而出,这与IE4的成功有很大关系。IE系列率先实现了CSS1.0标准,可以说是与NetscapeNavigator的战争中获胜的因素之一,甚至很多CSS3属性的背后也有IE的影子,但是苍凉的IE系列很大程度上是因为它的无所作为。语法或结构CSS规则的结构如下:┌────────选择规则──────┐┌──────────────声明块──────────────┐p+p>span:first-child{┌────────CSS属性────────┐font-size:10px;└─属性名─┘└─属性值─┘}由两部分组成Composition,选择器和声明块。选择规则:用于匹配特定HTML中符合要求的标签声明块:用于设置所需标签的样式选择规则由两部分组成,选择器和连接器。上例中,p、span、:first-child属于选择器,+、>等符号属于连接器。一个声明块由多个CSS属性组成。该属性分为两部分。属性名和属性值以:分隔,以;结尾。属性指定标签的样式。选择规则选择规则,顾名思义,就是用来选择HTML文档中的标签的,那么如何进行选择呢?选择规则分为两部分,我们分别介绍选择器。选择器用于选择存在于HTML页面中的标签。选择器分为几类,如下:选择器类型含义元素选择器(elementname)选择对应的标签类选择器(.classname)选择对应类名的标签ID选择器(#idname)选择对应ID的标签通配符selector(*)选择所有标签属性选择器([attributename=value])选择具有相应规则属性的标签Pseudo-classselector选择伪类指定标签属性选择器有多种写法,如下:写法的含义[attr]选择有attr属性的标签[attr=value]选择有attr属性值为value的标签[attr~=value]选择attr属性中有valuewords(不与其他字母相连的词)的标签[attr|=value]选择标签whoseattrattributeisvalueorstartwithvalue-[attr^=value]选择attr属性以value开头的标签[attr$=value]选择attr属性以value结尾的标签[attr*=value]选择attr标签w属性中的第i个值注意:属性选择器的写法,比如[attr=value]后面可以跟i,比如[attr=valuei]表示匹配时忽略value的大小写。常用的伪类,写法如下含义:active选择用户激活的标签:hover选择鼠标悬停的标签:visited选择已经访问过的链接:focus选择获得焦点的标签:first-child选择一组兄弟标签第一个标签:last-child选择一组兄弟标签中的最后一个标签:first-of-type选择一组兄弟标签中其类型的第一个标签:last-of-type选择firsttaginagroupofsiblingtags最后一个标签类型:not(X)选择所有没有被X选择器选中的标签:nth-??child(an+b)ab是固定值,n是任意自然数,选中一组兄弟标签中的第an+b个元素:nth-??last-child(an+b)同上规则,从后往前匹配:nth-??of-type(an+b)同上以上规则,从前向后查找,匹配同类型标签:nth-??last-of-type(an+b)同上规则,从后向前匹配:only-child如果只有一个child父标签中的元素,然后选择子标签:only-of-type如果父标签中只有一个该类型的子元素,则选择子标签连接器(符号用引号括起来)。连接器指定选择器应该如何组合。为了方便说明,我给符号起个名字。最终选择规则的含义只需要按照顺序从前往后读就可以了。符号名称含义''(无)和选择器堆叠','或选择器共享''(空格)内部后代选择'>'内部一级子元素选择'+'第一个相邻兄弟选择'~之后的所有兄弟'choosetogiveafewexamplesp.class1p,divp.class1p>.class1p+.class1p~.class1让我们一起阅读:选择p并让标签带有class1的类名。选择p标签或div标签。选择p标签内带有类名的标签。在p标签内的第一层选择带有类名的标签。选择p标签后具有类名的第一个标签。选择p标签后带有类名的所有标签。对于复杂的选择规则的写法,比如bootstrap中有这么一段:.btn-group>.btn-group:not(:first-child):not(:last-of-type)>.btn{border-radius:0;}是什么意思?按顺序读取:选择btn-group类名第一层标签中btn-group类名标签而不是第一个子元素而不是最后一个子元素标签第一层btn类名标签.对应的html如下:Button1Button2按钮3按钮4按钮5>选中的标签是button2/3/4。我们从这个规则的意思来理解这个规则:btn-group中btn-group下的btn不应该有圆角(在中间的时候)。因为普通的按钮都是圆角的,而放在按钮组中的按钮其实只需要左右两侧的按钮都圆角即可。这时候就需要特殊的手段了。选择并删除圆角。然后我们看看我们翻译的内容,是不是很绕口?最后提一下bootstrap中的一个样式规则。一起翻译吧。左半径:0;border-top-left-radius:0;}选择器的内容到此结束,接下来要说的是声明块中的CSS属性。样式类(property)CSS中有很多样式,可以根据样式效果来区分。大致可以分为以下几类。角色代表属性。字体控制字体的显示效果。font-*colortext-transformtext-decorationtext-shadowtextText-aligntext-align-lasttext-indenttext-overflowline-heightword-spacingletter-spacingbackgroundcontrolelementbackgrounddisplaybackground-*layout控制元素布局行为flexseriesattributegridseriesattributedocumentflowPosition相关控制元素在文档流中的位置topleftbottomrightz-indexfloatclearlistcontrollistbehaviorlist-*boxmodelcontrolelementsizewidthheightpaddingbordermarginbox-sizinganimation&transitioncontrolelementanimationtransition-*transformanimation-*@keyframes本文只介绍什么是css,并没有解释什么是css,所以我不想太深究这些属性的具体内容,大家可以去了解一下通过查看CSS参考。我们在属性的继承开头提到过,CSS是层叠样式表,层叠就是属性的继承。这种继承可以简单的用一句话来概括:父标签的字体样式和文章排版样式都会被子标签继承,也就是说子标签有这些属性,不用写这些属性。几个特殊值CSS中有几个特殊的属性值,需要特别注意:unset——如果该属性是继承属性,则使用继承值,如果不是,则使用浏览器默认值initial——使用初始化值,即浏览器默认值inherit——使用继承值权重由于同一个标签可以被不同的选择规则选中,那么这时候就有一种情况,如果多个选择规则同时选择同一个元素,并设置同时显示相同的属性,那么根据定义的属性标签最终应该显示什么规则呢?不同的CSS规则在同一个标??签上设置相同的属性,权重最高的CSS选择规则将覆盖权重较低的样式设置。什么是重量?经过上面的介绍,CSS设置标签的样式如下:直接写在标签的style属性上ID选择器类名选择器伪类标签选择器通配符从上到下,选择器的权重依次递减,就可以了就像同一张钞票,100的钞票代表比10元的钞票更大的钞票,但与钞票不同的是,无论有多少低权重选择器,较高权重的总是比较低权重的优先级更高。在去除样式的方式中,我们使用一个数组来表示选择规则的权重。[0,0,0,0,0]从左到右:ID选择器、类名选择器、伪类、标签选择器、通配符,数组初始值全为0,我们可以改变选择规则来确定最终数组,例如非常复杂的btn选择:.btn-group>.btn-group:not(:first-child):not(:last-of-type)>.btn{border-radius:0;}来自从左到右,每出现一个选择器,就在对应数组中的数组中加一个,那么之前规则的最终数组如下:[0,3,2,0,0]这时候可能有朋友会我问,有4个伪类可以选择,为什么是2个?这里需要注意的是::not伪类只有否定的意思,并没有增加权重。那么权重如何比较呢?简单的说,从前到后,谁比谁大,权重就高。相信大家写个比较程序就明白了:functioncompare(weight1,weight2){for(leti=0;i<5;i++){if(weight1[i]!==weight2[i]){if(weight1[i]>weight2[i]){console.log('第一个引用的权重是重的');}else{console.log('第二个引用的权重很重');}返回;}}}那么style指定的样式权重如何呢?样式style指定的权重高于ID选择器的权重。那么我们要修改CSS文件中style指定的样式怎么办呢?使用!important修改特定样本。如下图p{color:red!important;}那么p标签的字体颜色是红色的,即使设置了样式也没用。总结一下:权重级别从高到低依次为:!important>style>selectionrules。就好比大哥有话小弟不敢说,轻重绝对服从上级。所以为了避免尴尬的情况,请谨慎使用!important。自从预编译CSS发展起来,人们发现CSS虽然包含层叠的意思,但是它是一维写的,比如一个网页,文档结构如下:

这是一段文字

我们要在article和p标签上设置样式,如下所示:article{font-size:14px;}articlep{color:red;}由于样式规则是通过一,看起来像One-dimensional,标签的层级结构体现不出来,这样写就更好了:article{font-size:14px;p{颜色:红色;}}层级结构从样式写法上解释,通过p标签继承样式清晰,但是浏览器只能识别一维样式写法,那么如何让浏览器理解结构呢?预编译器就是因为这种情况而诞生的。常用的css预编译器包括:sass、less、stylus等,这些预编译器需要特定的语法,但都支持二维书写。那么这些预编译器做了什么?很简单的一句话,将符合预编译器语法的文件转换成css文件。这些相同的预编译器的语法这里就不介绍了,提供几个网站供大家参考:sass/scsslessstylusCSSModules这篇文章是我2019年写的,为什么要特地声明时间因为一件事:CSSModules的出现,我们需要了解它。什么是CSSModules,官方解释如下:CSSfileswhichallclassnamesandanimationnamesaredefaultlocallyscoped.翻译过来就是:CSS类名和动画名在同一个命名空间下。不知道?写一个例子。以下是伪源代码://test.css.box{color:red;}importstylefrom'test.css'functionTest(){return()}以下是伪输出:
_styles__box_34682763478是添加命名空间后的类名,这样构建的代码就不会出现同名类名被覆盖的问题。一般来说,CSS模块所做的一件事就是混合类名、id和动画名称。这时候有开发站站出来说,这东西不错,不用再考虑类名怎么选才不会引起冲突了。先冷静下来考虑一下这些问题:虽然不会有冲突,但是如果要覆盖类名怎么办?编译慢能接受吗?样式名称会随着文件位置或文件内容的变化而变化,这种变化是否可以接受?页面是否需要使用大量的JavaScriptDOMAPI?如果是这样,那么按款式名称挑选就变得不可靠了。使用CSSModules后,项目中是不是出现了很多:global?如果是这样,那么请仔细考虑。不使用CSS模块会更便宜吗?下面是问题1对应的一些场景:你引用了团队里其他人写的组件,但是你需要自己修改(覆盖)一些样式,其他人也用CSSModules写样式,所以他们的类namesarenotfixed是的,你如何覆盖这个组件中标签的样式?通知组件作者样式更改?通用组件呢?让他用固定的风格?那么使用CSS模块有什么意义呢?问题三、问题四:当你的程序需要使用DOMAPI,而CSSModules生成的样式名称会随着文件的位置或内容发生变化,程序变得不可靠。当然,这个问题是有办法解决的。js中也使用了CSSModules命名,但是调试变得有点困难。js中使用的样式名是为了区别于CSSModules。js和CSS模块使用两种不同的样式。那我说说我的经历,或者说我觉得好的经历。CSSModules与项目中的原始CSS一起使用。CSSModules仅在组件内部使用,项目中仍然使用公共样式。CSSModules只用在与结构无关但又不好命名的标签上,而这些标签一般不会被js选中。CSS模块混淆使用相对于文件位置而非文件内容的命名空间生成。某个样式一旦跨组件通用,就不再使用CSSModules,而是通过项目指定的命名空间在原始CSS文件中定义。在没有CSS模块的情况下开发UI库或通用组件。一般来说,CSSModules用在不共享、不关心命名、跨组件不通用的标签上是一个原则。这些标签可以认为是组件的内部状态,不会被外界影响或修改。不知道多年后CSSModules是否真的解决了编译慢的问题(至少在我的电脑上)。CSSModules原则上还是传统的CSS写法,只是混淆了名字,加了映射,但是以后会怎么样呢?我不知道,但我会密切关注它。总结惯例以一个问题开始,以一个问题结束CSS的级联在哪里?CSS选择规则由哪两部分组成,每部分是如何组成的?列出一个选择器列表并将它们分门别类?有哪些共同属性?预编译器是做什么用的?什么是CSS模块?让我们谈谈CSS模块。最后,其实这篇文章也想说一下布局和文档流的内容,但是太长了,而且还涉及到HTML,所以打算把布局分开来。以后会有单篇文章介绍如何布局网页,已记录。希望大家多多关注。请参阅MDN-什么是CSS?WIKICascadingStyleSheetsCSS二十年发展简史MDN-CSS参考CSS所有属性分类CSS优先级和权重最后最后本系列所有问题都是minimo提出的,爱你~~~