Skip to content

布局

CSS 布局考虑的是在 html 的骨架上,使用 CSS 特性为骨架添加优美的界面结构,是一个前端应用在一开始就需要考虑的内容,它影响到整个应用的模块划分,同时,需要相应的 JS 逻辑来支撑布局的实现。对于单个模块,甚至单个组件,同样需要进行布局的设计。

三大布局

流式布局

流式布局是最基本的布局方式,同时,大多数非 Web 的 UI 布局也是基于这个布局理念。我们的屏幕是一个长宽固定的矩形区域,我们需要将数量未知的内容展示在屏幕上,会遇到两种情况,一种是内容的大小小于屏幕的区域,一种是内容的大小大于屏幕的区域;前者涉及内容居中展示的话题,后者涉及部分展示的话题。从处理难度上看,后者会更麻烦一点,处理手段可以有两种:一种是滚动条方案,一种是分页方案。滚动条方案比分页方案好实现,并且是流式布局天生的拿手好戏。流式布局的基本策略是将 UI 内容或者说 html 元素看作流。

html 元素分为两种类型,一种是块级元素,一种是行级元素

  • 块级元素的特点是可以设置高度和宽度,且接受自动高度和自动宽度,自动高度意味着依据自己的子元素的高度来定义自己的高度,自动宽度意味着尽量让自己的宽度大,大到摸到自己的父元素允许的最大值。
  • 行级元素有两种类型。
    • 行内元素,不可以设置高度和宽度,默认自动高度和自动宽度,自动高度意味着依据自己的子元素的高度来定义自己的高度,自动高度意味着依据自己的子元素的宽度来定义自己的宽度。一个文字就是一个行内元素,包括空白字符也是一个行内元素,非显示声明的多个空白元素的会被自动折叠为一个空格。
    • 行内块元素,行内块可以设置高度和宽度,但是将失去自动高度和自动宽度。

流式布局有两种流,块级流行级流

  • 块级流。一个内部表现为流式布局上下文的元素(块级元素内部往往表现为流式布局上下文)内部期待一个块级流,块级流会将内部的第一代子元素看作块级元素,并沿块方向进行顺序排布,当内容超出该父元素的范围后,启用滚动条,用户可以通过滚动界面,看到超出范围的内容;
  • 行级流。在一个期待块级元素的位置,如果填入的是一个或多个行级元素,那么这些行级元素将在该位置生成一个类似块级元素的虚拟空间,它具有自动高度和自动宽度。这些行内元素在这个虚拟空间上沿着行方向进行顺序排列,并获得一个重要机制——行内元素的自动换行,使得当所有行内元素的总宽度超过虚拟空间的最大宽度时,通过换行让内容可见,同时让虚拟空间的高度变大,将消耗宽度转化为消耗高度,结合块级流的滚动条,从而解决内容超出显示区域的问题。

将盒子看做是流水线线性排布,分为两种类型块级和行级,行级又分为行内块级和行内级。块级在竖向排布,行级在同一行内排布。流式布局的规整性,在同一个盒子内部,其直属子代中,应当尽可能只有一种级别的排布。行内块样式的坑比较多,有行内块基线对齐、行内块间距、浮动塌陷等常见的开发问题。

流式布局的行级、块级都属于是标准流,还有非标准流,用于完成一些特殊的需求。主要有:

  • 浮动。用于文字环绕、自动换行、多行排布,段内定位等。浮动的初衷是用于图片和文字混排的需求,对标的 word 文档中的文字环绕的特性。但是,由于早期行内块布局的诸多奇怪行为,浮动便作为一个常用的 hack 手段。
  • 定位。分为相对、绝对、固定、粘性。可以实现不同的定位效果。使用时有子绝父相和 z-index 的限制。
  • 分栏。基于由浏览器实现的原生多栏结构,可以自动换列,从而达到如报纸般效果的分栏效果。流式布局的浮动流在横向排布,并在横向排满时自动换行,而分栏布局,可以将竖向再进行分列,当竖向流排布满时,实现自动转列的效果。该效果专门为行内元素设计,不要将子元素的 display 设置为 block,尽量设置为 inline 或者 inline-block,否则页面会有明显的卡顿。

弹性布局

CSS3 新特性,功能强大,包含flexgrid,基于全新的布局理念,引入了主轴和交叉轴的概念,将元素看做一个富有弹性的盒子,可以在主轴方向进行伸缩。在进行定义时,我们不在关注元素的大小,而是更加关注子元素的弹性,通过规定盒子的弹性策略,基于该策略让盒子具有强大的自适应能力,并附加了一些额外的功能,如自定义轴、对齐、排序、换行等特性。

响应式布局

可以直接与视口或者容器的宽度和高度进行挂钩,在不同的尺寸范围内加载不同的 css 规则,从而达到响应式的自适应能力。包括媒体查询和容器查询两个部分。响应式布局,可以依据容器的大小,动态地开启大批量的不同样式组。当用户的显示设备差异巨大的时候,可以用以更换大量和样式,使得同样的 dom 结构,也呈现出巨大的样式差异。

布局技巧

  • 竖向布局,使用默认的标准流块级流即可。不建议指定其子元素的高度值,转而通过子元素的 line-height 来进行定义,然后让父元素使用 scroll 隐藏多余的元素内容。留白时,块方向:父元素的上下 padding,子元素的上下 margin 或者靠子元素的行高。行方向:行级父元素的左右 padding。
  • 横向布局
    • 标准流的行内流,适合文字,和满足可换行的需求场景,垂直居中对齐的要领是不规定行元素的高度,转而关注文字大小和行高,搞清楚 vertical-align 的意义,活用相对单位:%、em、rem、lh、ch 和 calc() 和 aspect-ratio。
    • flex,简单无脑。不要去设置行内流方向上行内元素的 width。
  • margin、padding 使用。建议减少 margin,margin 的使用可以在流方向上随意使用,但在流的垂直方向上使用需要特别注意。使用时尽量对称使用,同时规定上下或者左右,如果涉及到不对称的地方,可以考虑使用空元素来进行操作。

前期设计模块考虑

  1. 主题管理:布局和主题相分离,主题使用全局 CSS 变量来管理,布局样式使用局部样式定义;
  2. 焦点管理:所有的 display 不为 none 的表单元素+a+button,均可以被 tab 键盘进行导航,可以通过设置 tabindex=-1 来置为空,其他元素想要被 focus 可以添加 tabindex=-1,或者想要被导航就设置 tabindex=0;
  3. 快捷键管理:统一在冒泡阶段进行处理,使用统一的快捷键模块进行集中管理,然后在 body 元素上进行最后的汇总处理;
  4. 右键菜单管理:处理方式同快捷键处理;
  5. 拖动管理;
  6. 插件管理;

粘性布局

粘性布局是流式布局中的一个子模块,利用定位能力实现 UI 的漂移。