网站制作多少钱一年,wordpress 404更改,wordpress ping服务器,深圳一医疗公司给员工放假10个月英文#xff1a;Peter Jang 编译#xff1a;缪斯segmentfault.com/a/1190000013191860CSS一直被web开发者认为是最简单也是最难的一门奇葩语言。它的入门确实非常简单——你只需为元素定义好样式属性和值#xff0c;看起来似乎需要做的工作也就这样嘛#xff01;然而在一些… 英文Peter Jang 编译缪斯segmentfault.com/a/1190000013191860CSS一直被web开发者认为是最简单也是最难的一门奇葩语言。它的入门确实非常简单——你只需为元素定义好样式属性和值看起来似乎需要做的工作也就这样嘛然而在一些大型工程中CSS的组织是一件复杂和凌乱的事情你更改页面上任意一个元素的一行CSS样式都有可能影响到其他页面上的元素。为了解决CSS错综复杂的继承问题开发者建立了各种不同的最佳实践问题是哪一个最佳实践是最好的目前尚无定论而且有些实践相互之间是完全矛盾的。如果你第一次尝试学习CSS这对于你来说是相当迷惑的。这篇文章的目的是通过回顾CSS的历史背景介绍下时至2018年的今天CSS发展过程中的一些设计模式和工具的演变。通过对这些背景的理解你将会更轻松的理解每个设计思想并且学以致用。接下来让我们开始吧CSS基本样式使用我们从一个最简单的网页index.html 开始这个文件中包含一个独立的样式文件index.css: !DOCTYPE html html langen head meta charsetUTF-8 titleModern CSS/title link relstylesheet hrefindex.css /head body headerThis is the header./header main h1This is the main content./h1 p.../p /main nav h4This is the navigation section./h4 p.../p /nav aside h4This is an aside section./h4 p.../p /aside footerThis is the footer./footer /body /html上面的HTML标签中没用使用任何class或者id。在没有任何CSS样式的情况下我们的网站看起来是这个样子功能可用但看起来不好看我们可以继续在index.css加点CSS美化下排版 /* BASIC TYPOGRAPHY */ /* from https://github.com/oxalorg/sakura */ html { font-size: 62.5%; font-family: serif; } body { font-size: 1.8rem; line-height: 1.618; max-width: 38em; margin: auto; color: #4a4a4a; background-color: #f9f9f9; padding: 13px; } media (max-width: 684px) { body { font-size: 1.53rem; } } media (max-width: 382px) { body { font-size: 1.35rem; } } h1, h2, h3, h4, h5, h6 { line-height: 1.1; font-family: Verdana, Geneva, sans-serif; font-weight: 700; overflow-wrap: break-word; word-wrap: break-word; -ms-word-break: break-all; word-break: break-word; -ms-hyphens: auto; -moz-hyphens: auto; -webkit-hyphens: auto; hyphens: auto; } h1 { font-size: 2.35em; } h2 { font-size: 2em; } h3 { font-size: 1.75em; } h4 { font-size: 1.5em; } h5 { font-size: 1.25em; } h6 { font-size: 1em; }这地方大部分都是关于排版字体、行高等样式的定义也包含一些颜色和一个layout居中设置。为了让每个属性有个合理的值你需要学习点设计理论但是这个地方我们用到的CSS本身并不复杂你可以直接定义结果如下所示有所变化了吧正如CSS许诺的一样——用一种简单的方式给文档添加上样式不需要编程或者复杂的业务逻辑。不幸的是实际情况会复杂的很多我们不单单使用的是CSS的排版和颜色这种简单的样式定义。CSS的布局使用在20世纪90年代CSS还未广泛普及之前对于页面的布局没有太多的选择。HTML最初是被设计为创建纯文本的一门语言并不是包含侧边栏、列等布局的动态页面。早期的时候页面布局通常使用的是HTML表格在行和列中组织内容这种方式虽然有效但是把内容和表现杂糅在一块了如果你想改变网页的布局就得需要修改大量的HTML代码。CSS的出现推动了内容写在HTML中和表现写在CSS中的分离人们开始把所有的布局代码从HTML中移除放入到CSS中需要注意的是和HTML一样CSS的设计也不是用来做网页内容布局的所以早期的时候试图解决这种分离设计是很困难的。我们来用个实际例子来看下如何实现布局在我们定义CSS布局前先重置下padding和margin会影响布局的计算不同的区域我们定义不同的颜色不要太在意好看不好看只要不同区域间足够醒目就可以 /* RESET LAYOUT AND ADD COLORS */ body { margin: 0; padding: 0; max-width: inherit; background: #fff; color: #4a4a4a; } header, footer { font-size: large; text-align: center; padding: 0.3em 0; background-color: #4a4a4a; color: #f9f9f9; } nav { background: #eee; } main { background: #f9f9f9; } aside { background: #eee; }现在页面应该看起来如下接下来我们用CSS来布局下页面内容我们将按照时间顺序采用三种不同的方式先从最经典的浮动布局开始吧。基于浮动的布局CSS浮动属性最初是为了将图片浮动在一列文本的左侧或者右侧报纸上经常看到。早在21世纪初web开发者将这个属性的优势扩展到了任意的元素这意味着你可以通过div的内容浮动创建出行和列的错觉。同样浮动也不是基于这样的目的设计的所以兼容性上会有很多问题。2006年A List Apart上发表了一篇热门文章In Search of the Holy Grail文章概述了实现圣杯布局的详细方法——一个头部、三列内容和一个底部你一定觉得一个简单的布局被称为圣杯布局很疯狂吧但是在当时纯CSS的时代这的确很难实现。下面是一个基于浮动布局的例子用到了我们文章中提到的一些技术点 /* FLOAT-BASED LAYOUT */ body { padding-left: 200px; padding-right: 190px; min-width: 240px; } header, footer { margin-left: -200px; margin-right: -190px; } main, nav, aside { position: relative; float: left; } main { padding: 0 20px; width: 100%; } nav { width: 180px; padding: 0 10px; right: 240px; margin-left: -100%; } aside { width: 130px; padding: 0 10px; margin-right: -100%; } footer { clear: both; } * html nav { left: 150px; }仔细看下CSS代码这里面为了让它工作包含一些必须的hack方式负边距、clear: both、硬编码的宽度计算等稍后我们会对这些细节做详细的解释。最终的结果如下看起来不错了但是通过三列的颜色可以看出来他们的高度不一样页面的高度也没有填充满屏幕。这些问题是浮动布局导致的所有的浮动只是将内容放在某一区块的左边或者右边但是没法知道其他区块的高度。这个问题一直没有个好的解决方案直到Flexbox布局的出现。基于Flexbox的布局flexbox CSS属性实在2009年第一次提出来的但直到2015年才得到浏览器的广泛支持。Flexbox被设计为定义一个空间在行或者列上如何分布的这让它比浮动更适合用来做布局这意味在使用浮动布局十多年后web开发者终于不再使用带有hack的浮动布局方式了。下面是一个基于Flexbox布局的例子。注意为了让flexbox生效我们需要在三列的外面额外包装一个div: !DOCTYPE html html langen head meta charsetUTF-8 titleModern CSS/title link relstylesheet hrefindex.css /head body headerThis is the header./header div classcontainer main h1This is the main content./h1 p.../p /main nav h4This is the navigation section./h4 p.../p /nav aside h4This is an aside section./h4 p.../p /aside /div footerThis is the footer./footer /body /html下面是flexbox布局的CSS代码 /* FLEXBOX-BASED LAYOUT */ body { min-height: 100vh; display: flex; flex-direction: column; } .container { display: flex; flex: 1; } main { flex: 1; padding: 0 20px; } nav { flex: 0 0 180px; padding: 0 10px; order: -1; } aside { flex: 0 0 130px; padding: 0 10px; }这种方式和浮动布局相比更加紧凑了虽然flexbox一些属性和值初看起来有些困惑但是好歹不需要像浮动布局那样负边距的hack方案了这是个巨大的进步。最终结果如下效果好多了所有的列高度都相同并且占据了整个页面的高度。从某种意义上来说这似乎是完美的了但是这个方式也有些小问题其中一个就是浏览器的兼容性——主流的现代浏览器都支持flexbox但是一些旧的浏览器不兼容。幸运的是浏览器厂商也正在尽最大努力终止对旧版本浏览器的支持为web开发者提供更一致的开发体验。另一个问题是我们需要 divclasscontainer包裹HTML内容标签如果能避免会更完美。理想状态下任何CSS布局都不需要改变HTML标签的。最大的缺点是CSS代码本身——flexbox虽然去掉了浮动的Hack但是代码的可读性上变得更差了。你很难去理解flexbox的CSS并且不知道页面上是如何去布局所有元素的。在写flexbox布局代码的时有很多时候靠的是大量的猜测和尝试。特别需要注意的是flexbox被设计用来在单行或者单列中分割元素的——它不是设计用来给整个页面做布局的尽管它能很好的实现相对于浮动布局好很多。另一种不同的规范是用来处理多行或者多列布局的我们称之为CSS 网格。基于Grid的布局CSS网格最早在2011年提出的比flexbox提案晚不了多久但是花了好长时间才在浏览器上普及起来。截止2018年初大多数现代浏览器都已经支持CSS grid这比一两年前有巨大的进步了。下面我们看一下基于网格布局的例子注意在这个例子中我们摆脱了flexbox布局中必须使用 divclasscontainer的限制我们可以简单的使用原始的HTML先看下CSS文件 /* GRID-BASED LAYOUT */ body { display: grid; min-height: 100vh; grid-template-columns: 200px 1fr 150px; grid-template-rows: min-content 1fr min-content; } header { grid-row: 1; grid-column: 1 / 4; } nav { grid-row: 2; grid-column: 1 / 2; padding: 0 10px; } main { grid-row: 2; grid-column: 2 / 3; padding: 0 20px; } aside { grid-row: 2; grid-column: 3 / 4; padding: 0 10px; } footer { grid-row: 3; grid-column: 1 / 4; }虽然结果看起来和基于flexbox的布局一样但是CSS在很大程度上得到了改进它清晰地表达出了期望的布局方式。行和列的大小和形状在body选择器中定义每一项item直接通过他们所在行和列的位置定义。grid-column 这个属性你可能觉得不太好理解它定义了列的起点和终点。这个地方让你觉得困惑的可能是明明有3列却为什么定义的范围是1到4通过下面的图片你就能理解了第一列是从1到2第二列是从2到3第三列从3到4所以头部的 grid-column是从1到4占据整个页面导航的 grid-column是从1到2占据第一列等等一旦你习惯了grid语法你会觉得它是一种非常理想的CSS布局方式。唯一缺点就是浏览器支持幸运的是过去一年中浏览器的支持又得到了进一步的提高。作为专为CSS设计的第一款真正的布局工具很难描绘它的重要性从某种意义上来说由于现有的工具需要太多的hack和变通方式去实现因此web设计者过去对于布局的创意上一直很保守CSS网格的出现有可能会激发出一批从未有过的创意布局设计——想想还是挺激动人心的使用CSS预处理器扩展CSS语法到目前为止我们介绍了CSS的基本样式和布局现在我们再来看下那些帮助CSS提升语言本身体验的工具先从CSS预处理器开始吧。CSS预处理器允许你使用不同的语言来定义样式最终会帮你转换为浏览器可以解释的CSS这一点在当今浏览器对新特性支持缓慢的情况下很有价值。第一个主流的CSS预处理器是2006年发布的Sass它提供了一个新的更简洁的语法缩进代替大括号没有分号等等同时增加了一些CSS缺失的高级特性像变量、工具方法还有计算。下面我们使用Sass变量实现下前面例子中带颜色的区域定义 $dark-color: #4a4a4a $light-color: #f9f9f9 $side-color: #eee body color: $dark-color header, footer background-color: $dark-color color: $light-color main background: $light-color nav, aside background: $side-color注意我们用 $定义了可复用的变量省略了大括号和分号语法看起来更加清晰了。简洁的语法让Sass看起来很棒但变量这样的特性出现在当时来说意义更大这为编写整洁可维护的CSS代码开辟了新的可能性。使用Sass你需要安装Ruby(Ruby)这门语言主要是让Sass编译成正常的CSS同时你需要安装Sass gem之后你就可以通过命令行把你的.sass文件转成.css文件了我们先看一个使用命令行的例子 sass --watch index.sass index.css这个命令定期把 index.sass中的Sass代码转为CSS写入到 index.css文件中 --watch参数设定后会实时监听.sass文件改动并执行编译非常方便。这个过程被称为构建步骤。这在2006年的时候是非常大的一个障碍如果你对Ruby这样的编程语言熟悉的话这个过程非常简单。但是当时很多前端开发者只用HTML和CSS他们不需要类似这样的工具。因此为了使用CSS预编译的功能而让一个人学习整个生态系统是很大的一个要求了。2009年的时候Less CSS预编译器发布。它也是Ruby写的并且提供了类似于Sass的功能关键不同点是它的语法设计上更接近CSS。这意味着任何CSS代码都是合法的Less代码同样我们看一个用Less语法的例子 dark-color: #4a4a4a; light-color: #f9f9f9; side-color: #eee; body { color: dark-color; } header, footer { background-color: dark-color; color: light-color; } main { background: light-color; } nav, aside { background: side-color; }语法上几乎是相同的变量的定义使用 替代了 $但是Less和CSS一样带有大括号和分号没有Sass例子的代码看起来漂亮。然而和CSS相近的特性反而让开发者更容易接受它在2012年Less使用了JavaScriptNode.js重写了替换了Ruby性能上比Ruby编译更快了并且很多在工作中使用了Node.js的人更容易上手了。把这段代码转化为标准的CSS你需要安装Node.js 和 Less执行的命令行如下 lessc index.less index.css这个命令把 index.less文件中的Lessz代码转化为标准的CSS代码写入到 index.css文件中注意lessc命令不能监听文件的变化和sass不一样这意味着你需要安装其他自动监听和编译的组件来实现该功能增加了流程的复杂性。同样对于程序员来说使用命令行的方式并不难但是对于其他只想使用CSS预编译器的人来说还是个非常大的障碍。汲取了Less的经验Sass开发者在2010年发布了一个新的语法叫SCSS与Less类似的一个CSS超集同时发布了LibSass一个基于C扩展的Ruby引擎让编译更快并且适配于多种语言。另外一个CSS预处理器是2010年发布的Stylus使用Node.js编写和Sass或者Less相比更注重于清晰的语法。通常主流的CSS预编译器就这三种SassLessStylus他们在功能方面非常相似所以你不必担心选择哪一个会是错误的。然而有些人认为使用CSS预处理器开始变得越来越没必要因为浏览器最终会慢慢实现这些功能像变量和计算。此外还有一种称为CSS后处理器的方法有可能会让CSS预处理器过时显然这存在些争议我们在后面会详细介绍下。使用CSS后处理器的转换功能CSS后处理器使用JavaScript分析并转换你的CSS为合法CSS从这方面来看和CSS预处理器很相似你可以认为是解决同一个问题的不同方式。关键的不同点是CSS预处理器使用特殊的语法来标记需要转换的地方而CSS后处理器可以解析转换标准的CSS并不需要任何特殊的语法。举一个例子来说明下我们用最初定义的header标签样式来看一下吧 h1, h2, h3, h4, h5, h6 { **-ms-hyphens: auto; -moz-hyphens: auto; -webkit-hyphens: auto;** hyphens: auto; }粗体部分的属性成为厂商前缀厂商前缀是浏览器厂商对CSS新功能的实验和测试使用的在正式实现前提供给开发者使用CSS新属性的一种方式。 -ms代表IE浏览器-moz是火狐浏览器 -webkit是基于webkit内核的浏览器。定义这些不同浏览器厂商的前缀属性是非常烦人的尽量使用生成工具自动添加厂商前缀。我们可以使用CSS预处理器来完成这个功能例如我们可以用SCSS来实现 mixin hyphens($value) { -ms-hyphens: $value; -moz-hyphens: $value; -webkit-hyphens: $value; hyphens: $value; } h1, h2, h3, h4, h5, h6 { include hyphens(auto); }这个地方使用了Sass的 mixin 功能你可以定义一个CSS代码块然后在其他任何地方重用当这个文件被编译成标准的CSS的时候所有的 include语句都被替换成与之匹配的 mixin中的CSS。总体来说这个解决方案也不差但是你仍然要为每个需要厂商前缀的的CSS属性定义一个mixin这些mixin的定义将需要不断的维护比如当浏览器支持了某个CSS属性后你就要在你的定义中移除掉该属性。比起写mixin的方式直接正常写CSS然后由工具自动识别添加需要厂商前缀的属性的方式显然更优雅些。CSS后处理器就恰好能完成这样的功能。比如如果你使用 PostCSS 和 autoprefixer 插件你就可以直接写正常的CSS并不需要指定浏览器厂商前缀剩下的工作全交给后置处理器去处理 h1, h2, h3, h4, h5, h6 { hyphens: auto; }当你使用CSS后处理器运行这段代码的时候 hyphens:auto; 将被替换成包含所有浏览器厂商前缀的属性这意味着你可以正常写CSS不用担心各种浏览器兼容性问题岂不是很棒 除了PostCSS的 autoprefixer插件还有很多有意思的插件cssnext 插件可以让你体验下一些实验性质的CSS新功能CSS modules 可以自动改变class的名字避免名称冲突stylelint 能检查出你CSS代码中一些定义错误和不符合规范的写法。这些工具在过去一两年里开始流行起来给开发者提供了从未有过的工程化流程。然而进程的发展总是有代价的安装和使用CSS后处理比CSS预处理器更复杂。你不仅要安装、执行命令行还需要安装配置各个插件并且定义好各种复杂的规则比如你的目标浏览器等。很多开发者不再直接使用命令行运行PostCSS了而是通过配置一些构建系统像Grunt 、Gulp 、webpack他们可以帮助你管理前端开发工作中需要的各种构建工具。值得注意的是对于CSS后处理器存在些争议有人认为这个术语有些让人迷惑一种说法是建议都应该叫CSS预处理器还有一种说法是应该都简称CSS处理器等等有人认为有了CSS后处理器完全可以不需要CSS预处理器有人则主张两者一起使用。不管怎么说去了解下CSS后处理器的使用还是非常值得的。使用CSS设计模式CSS预处理器和CSS后处理器让CSS开发体验有了巨大的提升但是单靠这些工具还不足以解决维护大型项目CSS代码的问题。为了解决这个问题人们编写了一些关于如何写CSS的指导方针通常被称为CSS规范。在我们深入分析CSS规范前首先要搞清楚是什么让CSS随着时间推移变得更加难维护关键点是CSS是全局性的——你定义的每个样式都会全局应用到页面的每个部分用一个命名约定来保证class名称的唯一性或者有特殊的规则来决定指定样式应用到指定元素。CSS规范提供了一个有组织性的方式来避免大量代码时出现的这些问题让我们按照时间顺序来看看主流的一些规范吧OOCSSOOCSS面向对象的CSS是在2009年首次提出的它是围绕两个原则建立的规范。第一个原则是结构和样式分离这意味着定义结构布局的CSS不应该和定义样式颜色、字体等的CSS混杂在一起这样我们就可以很简单的为一个应用定义新的皮肤了第二个原则是容器和内容分离把元素看成是一个可重用的对象关键核心点是一个对象不管用在页面的任何位置都应该看起来是相同的。OOCSS提供了成熟的指导规范但是对于具体的执行规范并没有明确指出。后来出现的SMACSS采用了它的核心概念并且添加了更多的细节使用起来更简单了。SMACSSSMACSS可扩展模块化架构的CSS是在2011年出现的一种设计模式它将CSS分为5个不同的类别——基本规范、布局规范、模块、状态规范和样式规范。SMACSS也有一些推荐的命名规则对于布局规范使用 l-或者 layout- 作为前缀对于状态规范使用 is-hidden 或者 is-collapsed 作为前缀。相比OOCSSSMACSS有了更多细节上的规范但是CSS规则该划分为哪一类别的规范中这是个需要仔细考虑的问题。后来出现的BEM对这一方面进行了改进让它更易使用了。BEMBEM (块, 元素, 修饰符)是在2010年出现的规范它的思想主要是围绕把用户界面切分成独立的块。块是一个可重用的组件举个例子像表单搜索可以这样定义 formclasssearch-form/form元素是块的一部分不能单独重用比如表单搜索中的button buttonclasssearch-form__buttonSearch/button修饰符是定义了块或者元素外观、状态或者行为的实体比如禁用搜索按钮定义为 buttonclasssearch-form__button search-form__button--disabledSearch/button。BEM的规范很容易理解对于新手来说命名规则上也很友好缺点就是可能会导致class名字非常长并且没有遵循传统的命名规范。后来出现的Atomic CSS又把这个非传统方式带到了一个新的高度。Atomic CSSAtomic CSS (也称为 功能性CSS)是2014年出现的一个规范它的思想是基于可视化的方法创建小而功能单一化的class。这种规范与OOCSS、SMACSS和BEM完全相反——它并不是把页面上的元素看做是可重用的对象Atomic CSS忽略掉了这些对象每一个元素使用了可重用的单一功能的class样式集合。因此像 buttonclasssearch-form__buttonSearch/button就被替换成这样的写法了 buttonclassf6 br3 ph3 pv2 white bg-purple hover-bg-light-purpleSearch/button如果你看到这个例子第一反应是被吓的退缩了没关系你并不是唯一有这想法的人——很多人认为这种方式完全违背了CSS的最佳实践但是关于这个有争议的规范在不同场景下的应用也产出了一系列精彩的讨论。这篇文章很清晰的分析了传统的分离思想是CSS依赖于HTML创建即使使用像BEM这类的规范而Atomic的方式是HTML依赖于CSS创建两者都没错但是仔细想想你会发现CSS和HTML彻底分离的想法是实现不了的。其他的CSS设计模式像CSS in JS其实也包含了CSS和HTML相互依赖的思想这也成为了一个饱受争议的设计规范之一。CSS in JSCSS in JS 是2014年推出的一种设计模式它的核心思想是把CSS直接写到各自组件中而不是单独的样式文件里。这种方式在React框架中引入的最早是使用内联样式后来又进化成了使用JavaScript生成CSS然后插入到页面的style标签中的方式。CSS in JS再一次违背了CSS中关于分离的最佳实践主要原因是web随着时间推移发生了很大的变化。最初web大部分都是静态网站——这种情况下HTML内容和CSS表现分离是很有意义的但现在大部分应用都是动态web构建——这种情况下可重用的组件更加有意义了。CSS in JS设计的目标是定义边界清晰包含自己HTML/CSS/JS的独立组件并且不受其他组件的影响。React是最早采用这种思想的框架后续也影响到了其他框架像Angular、Ember和Vue.js。需要注意的是CSS in JS的模式相对来说比较新的开发人员正在不断的尝试开发web应用组件时的一些CSS最佳实践。五花八门的设计模式很容易让你不知所措最重要的记住一点——没有银弹。结论简而言之这就是现代CSS。我们介绍了CSS基本排版样式浮动布局、flexbox和grid布局了解了CSS预处理器为CSS提供的新语法比如变量和mixins还了解了CSS后处理器的转换功能像给CSS添加厂商前缀并且使用CSS的一些设计模式克服了全局CSS的一些问题。在这里我们没有时间去挖掘更多CSS其他功能了CSS覆盖面太广了——任何一个说它简单的人可能只是对它一知半解吧现代CSS的多变和快速发展多少让人感到有些沮丧但是重要的是要记住web随着时间推移进化的历史背景并且有一群聪明的人愿意为CSS向更好的方向的进化去创建一些工具和指导规范。作为一名开发者是一件幸运的事情我希望这篇文章提供的信息能作为一个路线图帮助你更好的畅行在CSS路程中