CSS哲学

大家好! 现在该宣布我们计划在2月底之前发布有关CSS的新书 ,推荐给已经精通MacFarland的每个人(虽然有书,我们计划在1月进行下一次超压)。

今天,邀请您翻译基思·格兰特(Keith Grant)的文章(于6月出版),作者在其中阐述了他对CSS的观点,并实际解释了他想在书中谈论的内容。 我们阅读并发表评论!



我花了很多时间思考什么是面向CSS的思想。 似乎有些人设法“学习”它,而另一些人却没有。 我认为,如果我可以清楚地阐明这种世界观是什么,那么CSS本身对于与之合作的人来说将变得更加容易理解。 这就是为什么我坐下来写《 CSS for Professionals》一书的部分原因。

今天,我想再次解决这个问题。 考虑三个主要的CSS功能,这些功能将这种语言与传统的编程语言区分开。 CSS是持久的,声明性的和上下文的。 我认为理解语言的这些方面是成为CSS大师的关键前提。

耐CSS

如果您不小心删除了JavaScript文件中的一段代码,则使用它的应用程序或网页几乎肯定会崩溃或冻结,并且脚本(甚至整个页面)都会失败。 如果在CSS中执行相同的操作,则可能不会注意到任何内容。 除已删除的片段外,几乎所有其他代码将继续正常运行。

此属性称为弹性。 HTML和CSS经过特殊设计,具有容错能力。 如果发生问题,浏览器将引发错误; 否则,它只会忽略代码的这一部分,然后继续进行下去。

从调试的角度来看,这似乎很荒谬:如果程序没有抛出错误,我们如何才能发现出了问题? 但这是CSS设备最重要的方面。 它被编织成舌头本身的织物。 我承认,这需要时间来习惯。 但是,一旦您了解了这一点,就可以安全地继续使用所有浏览器都不支持的功能。 这样可以确保站点或应用程序的逐步开发。

考虑具有网格布局的此示例。 它既可以在支持网格的浏览器中使用,也可以在不支持网格的浏览器中使用。 在不支持网格的浏览器中,布局会有些许不均匀(元素的确切大小可能会有所不同),但页面的布局仍应大致如下:

.portfolio { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); } .portfolio__item { display: inline-block; max-width: 600px; } 

不了解这两个网格声明的浏览器将忽略它们,由于其他规则,有可能完成工作。 反过来,了解网格的浏览器将使用网格布局,并且将忽略内联块声明(因为这是设计网格工作方式的方式)。 詹·西蒙斯(Jen Simmons)开玩笑地称这种现象为“ 量子CSS ”。 您具有一些CSS功能,并且“同时使用和不使用”。 但是它同时起作用,但是不起作用。”

这种“安全”行为是使用CSS不可或缺的一部分,但是它与大多数传统编程语言无关。

CSS声明式

在JavaScript中,我们编写了具体的分步说明,描述了程序应如何获得某些结果。 在CSS中,您告诉浏览器您想要在屏幕上看到的内容,浏览器找到了一种方法。 了解这一点非常重要。 如果您学到了这一点,那么CSS 将会为您完成所有艰苦的工作 ,否则,您将掌握CSS的精髓,一遍又一遍地感到失望。

编写CSS时,实际上是在建立约束系统。 我们不会向浏览器指示每个特定元素应该在页面上的位置,但是会告知它们之间应该缩进什么,然后浏览器本身会将所有内容放到适当的位置。 您不会告诉浏览器(至少您不应指出)容器的高度。 当浏览器知道容器的内容,知道在此上下文中使用了哪些其他样式以及视口的可用宽度是多少时,您就可以允许浏览器在显示期间自行确定。

您必须考虑太多变量。 CSS的本质是组织流程,因此您不必担心所有这些变量。 定义一个限制系统。 语言本身负责细节。

简单的例子

让我们看一下这样的CSS示例: font-size: 2em 。 该代码的作用是什么? 您说:“增加字体的大小。” 但这还不是全部。 它还可以纠正容器内文本行的断字,因为现在每行中包含的单词数量减少了。 因此,这通常增加了文本行的数量,并且还增加了容器的高度,使得这些新行适合其中。 当您更改容器的高度时,位于该容器下方页面上的所有文本都会相应地移动。 最后,以上代码还设置了本地em值。 必须重新计算用于确定em单位的所有其他属性的值。

仅此公告就会在页面上产生一整套更改。 所有这些都旨在完全实现您必须努力实现的目标:内容始终适合页面,元素彼此不重叠,并且所有依赖字体大小的属性都得到了纠正(例如,缩进)。 您不必考虑所有这些细节。 浏览器本身执行上述所有计算,并且默认情况下执行此操作。

如果您不希望发生这种情况,也可以这样做。 您可以使用max-heightoverflow: auto属性严格限制容器max-height 。 您可以重新定义内部页边距,以便以rempx为单位进行度量,也就是说,它们不会在字体大小之后重新计数。 这揭示了使用CSS的一个有趣的方面:​​有时您不告诉浏览器它应该做什么,但是实际上,它禁止它做任何事情。

电网优势

但是,CSS中有一些更酷的新功能。 最常见的示例是Flexbox和Grid。 仅需几条通知-您将拥有一个非常灵活的网格布局,并且可以正常使用。 无需担心众多特殊情况。 实际上,您告诉浏览器:“将这些块分别堆叠在400像素宽的列中”,浏览器会为您完成。 关于一切的一切都需要大约三行代码。

如果您必须执行此操作,则必须处理许多奇怪的情况。 如果其中一个单词的单词太长怎么办? 如果视口太窄怎么办? 如果很宽? 如果一个元素中包含一整页内容,而另一个元素中只有几句话,该怎么办? 没错,在CSS中,您可能不必考虑任何这些。 一切都已经为您考虑好,并已在规范中列出,浏览器会为您遵循规则。 这就是声明性语言的力量。

当然,这并非没有妥协。 如果声明性语言不支持您需要的任何功能(例如“桥接”),则它仍然依赖祖父技巧或JavaScript。 此外,CSS的开发多年来一直致力于与此类事物作斗争。 幸运的是,随着Flexbox和Grid的发展,我们可以做更多的事情,而且没有任何黑客(是的,松散的元素是黑客)。 如果您在这种情况下仍然缺少什么,我建议您阅读有关CSS Houdini的文章 ,该文章刚刚开始在浏览器中扎根。

CSS是上下文相关的

在React时代,我们采用了一种非常实用的方法:基于模块化组件的开发。 它符合CSS最佳实践以及BEM,SMACSS和CSS-in-JS。 我不想低估所有这些功能的重要性,因为它们在创建大型应用程序中起着关键作用。 但是,我认为同样重要的是,认识到CSS不是100%模块化的,也不应该是100%模块化的。
这有两个原因。 第一个也是最明显的-该应用程序应该以全局样式设计。 几乎总是需要在页面级别设置耳机和字体大小,默认情况下将使用它们。 此后,所有未显式覆盖它们的后代元素都将继承这些值。 您还需要在整个页面上系统地应用设计的某些方面:颜色主题,块的圆角半径,块底纹和整体边距大小。 在这些全局样式的上下文中将应用更多在页面部分起作用的局部样式。

第二个更微妙的原因是CSS和您的设计决策都取决于页面的上下文。 假设我们将以下CSS样式应用于页面上的元素:

 .the-thing { position: absolute; top: 10px; left: 10px; } 

该代码将做什么? 不知道该元素在DOM中的确切位置以及页面其余部分应用了什么样式,我们无法回答此问题。 相对于最接近的祖先元素完成了绝对放置,并且根据所讨论的祖先类型以及对它应用了哪种放置方式,这种放置的结果将有所不同。

此外,您将元素彼此叠加的能力(或不可能)在很大程度上取决于这两个元素在DOM中的位置。 DOM中的元素重排会极大地影响元素的布局及其重叠方式。 这就是为什么文档流和覆盖上下文是基本(尽管有时很复杂)主题的原因。

CSS的上下文性质部分是由于设计就是这样工作的。 如果工程师设计了桥梁,那么您不能只看图纸说:“一切都很好,但我不喜欢这种横梁; 带她走。 如果卸下一根梁,这将影响整个桥的结构统一性。 同样,只需更改任何设计元素-屏幕上的所有其他元素都会有不同的感觉。 通常,必须一次紧密地绘制几个元素。

例如,如果您在其中一个磁贴上增加标题,则标题对用户而言将变得更加明显,因此,屏幕上的其他元素显得不太重要。 这里的限制并不像桥梁的建造那样在物理平面上。 我们正在谈论影响人类感知的更多“人道主义”法律。 该页面的元素反映在屏幕上,具有自己的物理特征,在工作时,有必要考虑物理世界的现实情况以及我们如何看待它。

如您所知,软件架构受模块化和封装原则的约束。 这种方法在代码级别是合理的,因为代码很复杂,并且所描述的方法使您可以将问题分解为可消化的片段。 但是,应该记住这种方法是不完善的。 在CSS中,您永远不能完全忽略特定模块中发生的事情。

总结

所描述的三个方面将CSS与传统编程语言区分开来。 这些差异可能不会立即引起您的注意,但是它们是CSS最强大的方面。 我敢建议那些设法理解并正确理解这些原理的开发人员将在CSS中达到真正的高度。

Source: https://habr.com/ru/post/zh-CN433698/


All Articles