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

CSS 布局的本质是什么

时间:2023-03-18 13:04:19 科技观察

CSS布局的本质是什么?转载本文请联系神光编程秘籍公众号。UI发展历史自图形界面操作系统问世以来,上面的应用软件基本上都会绘制界面,这也是用户使用软件的界面,称为UI(用户界面)。涉及用户体验、设计、具体界面开发是软件中最接近用户的部分,也是多个功能定位重叠最多的部分。根据操作系统的不同,会有不同的界面开发方式。Android、ios、windows等都有自己的创建ui的库,但是更底层的绘图库有标准:跨平台绘图api接口标准OpenGL和windows下的DirectX。由于每个操作系统绘制UI的方式不同,跨平台的绘制方案逐渐流行起来,即浏览器。基于浏览器服务器的软件架构称为B/S架构,而基于客户端的软件架构称为C/S架构。一段时间以来,越来越多的B/S架构应用得到应用,越来越多的C/S架构应用采用混合B/S方案实现。移动互联网时代到来后,大家发现网页的体验不如原生。PWA(ProgressiveWebApp)等技术虽然后来发展起来,但与原生体验还是有差距,所以原生开发和应用方案占据了上风。但是,Android和iOS在绘制界面和编写逻辑方面有不同的方式。两端必须分开实现,开发和测试的人力成倍增加。这种成本比较高。为了节省成本,大家探索了跨端引擎的方案,也就是说渲染和交互的逻辑还是通过网页来写,但是渲染的API分别由Android和ios实现,这样实现了跨端渲染。逻辑部分也是用JS写的,一些需要的设备能力API分别由Android和ios实现,然后注入到JS引擎中。就像安卓和ios的跨端方案逐渐流行一样,electron方案也出现在了桌面端。通过网页渲染界面和编写逻辑,将需要的api注入到JS引擎中,electron直接集成了Node.jsapi注入到JS引擎中,可以直接使用Node.jsAPI在网页中实现一些原生功能时。此外,elctron还额外注入了一些API,比如clipboard、powermonitor等。时至今日,UI绘制方案逐渐向网页靠拢,基于html、css、js的web技术成为UI界面创建的主流方案。网页的物理层和逻辑层。用过canvasAPI的人应该都知道,如果直接画的话,需要指定在什么地方画什么内容,而且每一部分都要计算,比较麻烦,所以浏览器提供了一些布局。style,并提供css来描述,而content部分则通过html来描述。开发者只需要用html来描述内容的结构,然后用css来描述布局以及如何渲染就可以完成界面的绘制。网页会把html解析成dom树,css解析成cssom树,然后将两者组合成render树,自动计算绘制什么内容,在哪里实现最终渲染。dom用id、class、tagName等标记,逻辑部分通过这些标记将一些事件处理函数绑定到具体的dom上,然后在函数中操作dom,实现界面的交互。domapi是最终浏览器提供给开发者构建web应用的接口,可以看作是web应用的物理层。当然web应用的开发并不是直接基于domapi,而是会选择一定的前端框架,比如vue、react、angular等,这些框架实现了组件的功能,也就是逻辑的拆分页面的聚合,以及相同功能的html、css、js的聚合,从而实现复用。并且提供了mvvm的功能,自动将数据映射到具体的dom,不需要开发者手动操作dom。前端框架所做的相当于Web应用的逻辑层。最终的渲染和交互还是通过domapi,但是用户不需要直接操作,而是在逻辑层描述组件和数据,前端框架完成数据到dom的自动映射。目前的跨端解决方案基本上是把物理层的domapi替换掉,然后上层连接一个逻辑层的前端框架,支持应用的跨端开发。css的两部分CSS是浏览器提供给开发者描述界面的方式,描述界面分为两部分:内容在哪里绘制和内容如何绘制其中内容绘制是布局部分,主要是显示和定位风格。如何绘制内容与具体内容有关。字体、文字、图片等内容都有自己的风格。在这篇文章中,我们主要探讨css用于布局的部分。盒模型首先,所有的内容都会有一些空白和与其他元素的间距,所以css抽象了盒模型的概念,即任何块都是由内容、padding(空白)、border、margin(间距)组成的几个部分。display但盒子之间也有区别。有的框可以显示在同一行,有的则占据单行,内容位置的计算方法不同。所以提供了显示样式来设置框类型,比如block、inline、inline-block、flex、table-cell、grid等,设置为不同的框类型,会使用不同的计算规则。block的元素会独占一行,内容的宽高可以设置。具体的计算规则称为BFC。行内元素的宽高不能脱离内容设置,不会占一行。具体计算规则称为IFC。flex的子元素可以自动计算空白部分,分配比例由flex样式指定。具体的计算规则称为FFC。网格的子元素可以拆分成多行多列来计算位置。具体的计算规则称为GFC。这些是针对不同盒子类型的布局计算规则。基于不同盒子类型的位置计算规则往往是不够的。在很多场景下,需要一些用户自定义的布局规则,所以css提供了position样式,包括static、relative、absolute、fixed、sticky。静态默认框的定位方式是static,即streaming。上一个框显示的地方,下一个框会继续计算下面的位置。显示位置由内容量决定。一开始网页主要是用来显示一些文字,所以流位置计算规则很方便。相对流规则是根据上一个框的位置自动计算下一个框的位置,但是有时候想要做一些偏移,可以通过relative指定,将position设置为relative,然后通过top和bottom,left,right指定如何偏移。相对布局为流式布局增加了一些灵活性,可以在流式计算规则的基础上做一些偏移。绝对流的计算规则并不固定在什么位置显示什么内容,只适用于文字、图片等内容的排版。但是比如有些panel需要固定,只是在某个位置不要移动,可以设置position为absolute,就可以脱离文档流。此时可以根据上次非推流位置计算当前位置。fixedabsolute是根据最后一个脱离文档流的位置来计算位置的,最外层的absolute元素是根据window来定位的。如果想直接根据窗口定位,可以指定position为fixed。此时的top、bottom、left、right都是相对于窗口的。stickysticky的效果如果滚动时超过一定高度就固定在一个位置,否则就是静态的。相当于在static和fixed的基础上封装了一层,在实现导航栏的吸顶效果时可以直接使用。可能是因为太常用了,才封装了这样一个position属性值。之前通过js监听滚动条的位置分别设置static和fixed。总结所谓布局就是确定元素的位置。框类型(显示)设置好后,内容的渲染方式会有不同的规则,如BFC、IFC、FFC、GFC等。框之间默认流向,即位置是静态的,但有时你想在流中做一个较低的偏移量,使用相对。当你不想跟随文档流时,你可以设置absolute来计算一个相对于上一个非静态位置的固定位置。如果你想直接相对于窗口,使用fixed。当需要做吊顶效果时,需要根据滚动位置在static和fixed之间切换。这时候css也有sticky定位的方法可以直接使用。也就是说,盒子内部的布局计算规则是根据显示来确定的,也可以根据position做一些调整。vscode是如何布局的说完css的布局方式(即显示和位置),我们来看一个具体的案例:vscode是如何布局的。Vscode是我们经常用到的一个IDE。它是基于electron的,即通过网页来绘制界面。那么它是如何布局的呢?vscode分为标题栏、状态栏、内容区。为上中下结构,内容区分为活动栏、侧边栏、编辑区,为左中右结构。窗口可以调整大小,但上、中、下、左、中、右嵌套的结构不变。如何实现这种布局?css的布局就是利用display和position来确定每一块内容的位置。我们的需求是窗口放大缩小,但每个块的相对位置保持不变。这可以通过绝对布局来实现。首先,最外层是上、中、下三层结构。可以把每个block都设置为absolute,然后分别设置top的值,然后把中间的部分分成left,middle,right,就??可以分别设置left,middle,right部分的left值,这样就完成了每件作品的布局。这是整体布局,每个block根据不同的布局需求,使用不同的flow、elastic等box,并采用绝对定位和相对定位的方式进行排列。但是绝对定位是指定具体的上下左右值,是静态的,具体的值需要在窗口大小变化时动态设置。这时候就需要监听窗口的resize事件,重新排列布局,分别计算不同块的位置。而且vscode的每块大小也是可以拖动改变大小的,拖动的时候left和top的值都要重新计算。综上所述,现代软件基本上都有用户界面,不同操作系统下构建UI的方式不同,因此跨平台渲染浏览器方案逐渐流行起来。移动互联网时代之后,为了融合原生体验和跨平台网页,出现了跨端引擎方案,即分别基于Android和ios实现domapi,并在JS中注入一些device-capableapi引擎,业务代码通过domapi来描述UI。domapi是浏览器提供给开发者描述UI的方式,也就是物理层。现在的前端框架可以完成组件的封装和数据到dom的映射,不再需要直接操作dom,把dom当作逻辑层。因为跨端引擎实现了domapi,所以上层可以对接前端框架。UI是用css来描述的,css可以分为两部分:具体元素的布局和渲染。具体来说,字体、文字、图片等都有不同的样式来描述如何渲染,而布局就是确定每个元素的位置,由显示和位置决定。网页的每一个内容都是一个框,由content、padding、border、margin组成,display是设置框的类型。不同的盒子有不同的布局规则,如BFC、IFC、FFC、GFC等。当有一些布局规则需要自定义时,可以使用position。默认位置是静态的,即流式。下一个框的位置是根据上一个框来确定的。您可以使用relative来进行一些偏移。如果要相对于某个位置固定,可以使用absolute。当直接相对于窗口时使用fixed。另外,在做吊顶效果的时候,可以使用sticky,sticky是基于static和fixed包的。知道了显示和位置是怎么布局的,也就是计算框的位置,我们来看看vscode是怎么布局的。Vscode有上中下左中右结构。可以通过改变或拖动窗口来调整每个块的大小,所以采用嵌套绝对的方式进行整体布局。各个体块的内部结合流动性、弹性等方式,配合位置,进行更细致的布局。网页的css布局方案已经应用在越来越多的领域。比如跨终端引擎通过Android和ios实现css,kraken基于flutter实现css,所以css的布局方式是我们必须掌握的技能。希望这篇文章能帮助大家梳理css布局的思路,分析各种布局的特点,然后用合适的方案来实现。