正常布局流normal flow

浏览器默认的HTML布局方式

块方向/内联方向

块方向在英语等具有水平书写模式(writing mode)的语言中垂直运行。它可以在任何垂直书写模式的语言中水平运行。对应的内联方向是内联内容(如句子)的运行方向。

display、浮动、position、表格布局和多列布局都会覆盖默认布局

display

  • 基础值: block/inline/inline-block (见盒模型)
  • 全新布局方式:flex/grid

弹性盒子flex

display: flex

flex_terms.png

  • 主轴: 沿flex元素放置方向延伸的轴:flex-direction:column/row
    • row-reverse/column-reverse可以反向排向flex项
  • 交叉轴: 垂直于flex元素垂直方向的轴
  • flex-wrap: wrap:防止溢出
  • 简写:flex-flow: row wrap
  • 可以嵌套使用

flex项

给每个flex项添加属性,flex: 数值表示每一项占的属性

1
2
3
article {
flex: 1 200px;
}
  • 指定 flex 的最小值。每个flex 项将首先给出200px的可用空间,然后,剩余的可用空间将根据分配的比例共享。

  • flex-grow:规定了 flex-grow 项在 flex 容器中分配剩余空间的相对比例。剩余空间是 flex 容器的大小减去所有 flex 项的大小加起来的大小。如果所有的兄弟项目都有相同的 flex-grow 系数,那么所有的项目将剩余空间按相同比例分配,否则将根据不同的 flex-grow 定义的比例进行分配。

  • flex-shrink:指定了 flex 元素的收缩比例

  • flex-basis:即上面说的最小值(基础值)

水平和垂直对齐

交叉轴上的位置(按行排列的垂直方向)

容器属性align-items 控制 flex 项在 交叉轴 上的位置。

  • stretch default,拉伸填充容器,如果父容器没有固定大小,则会与最高的flex项保持一致
  • center/flex-start/flex-end

flex项设置align-self可以覆盖align-items的行为

主轴上的位置(按行排列的水平方向)

容器属性justify-content 控制 flex 项在 主轴 上的位置。

  • flex-start default / flex-end/center
  • space-around均匀分布,默认整体居中
  • space-between均匀分布,两端不留空间,默认从start开始

flex项排序

可以改变 flex 项的布局位置的功能,而不会影响到源顺序(即 dom 树里元素的顺序)

通过给flex项设置order属性实现

  • 默认是0,小的在前面,也就是说其他元素默认的情况下
  • 设置为1会将当前元素放到最后
  • 设置为-1会将当前元素放到最前面

网格Grid

display: grid

  • 基础概念:row/colunm/gutter(沟槽即间隔)

  • 单位:fr,表示可用空间的一个比例

  • 网格间隙:grid-gap(单位不能用fr)(grid-row/column-gap)(直接写gap就行了)

  • minmax 函数可以为一个行/列的尺寸设置了取值范围

  • 一个网格排版框架一般由12到16列的网格构成

  • 放置元素时如果重叠,HTML里定义在后面的元素会覆盖前面的元素;但可以用order或者z-index来调整顺序

显式网格与隐式网格

  • 显式网格是我们用grid-template-columnsgrid-template-rows 属性创建的。
  • 隐式网格则是当有内容被放到网格外时才会生成的。隐式网格就是为了放显式网格放不下的元素,浏览器根据已经定义的显式网格自动生成的网格部分。
  • 隐式网格中生成的行/列大小是参数默认是auto,大小会根据放入的内容自动调整。可以使用grid-auto-rowsgrid-auto-columns属性手动设定隐式网格的大小。

创建显示网格

以列为例

  • 基础用法:grid-template-columns: 2fr 1fr 1fr
  • 重复构建:grid-template-columns: repeat(3, 1fr) / grid-template-columns: repeat(2, 2fr 1fr)
  • 自动使用多列填充:grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));

基于网格线放置元素

F12选择布局里的网格覆盖,可以查看网格线

grid-column/row-start/end

或者简写为 grid-column: start / end/隔开

用定义网格线的方法可以将元素放置在网格中

或者用span 数字指定该行/列占几格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
header {
grid-column: span 2;
grid-row: 1;
}

article {
grid-column: 2;
grid-row: 2;
}

aside {
grid-column: 1;
grid-row: 2;
}

footer {
grid-column: 1 / 3;
grid-row: 3;
}

使用grid-template-areas属性放置元素

使用grid-template-areas属性,并且你要命名一些元素并在属性中使用这些名字作为一个区域。

1
2
3
4
5
6
7
8
9
.container {
display: grid;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
grid-template-columns: 1fr 3fr;
grid-gap: 20px;
}

然后用grid-area为相应的元素赋予对应的区域名称

1
2
3
header {
grid-area: header;
}

grid-template-areas属性的使用规则如下:

  • 你需要填满网格的每个格子
  • 对于某个横跨多个格子的元素,重复写上那个元素grid-area属性定义的区域名字
  • 所有名字只能出现在一个连续的区域,不能在不同的位置出现
  • 一个连续的区域必须是一个矩形
  • 使用.符号,让一个格子留空

浮动float

float 属性有四个可能的值:left/right/none(default)/inherit

例如:首字下沉

1
2
3
4
5
6
7
p::first-letter {
font-size: 3em;
border: 1px solid black;
float: left;
padding: 2px;
margin-right: 4px;
}

如果页面上第二个和第三个div的float都是right

则因为第二个div在先,最右边的会是div2

清除浮动

问题——所有在浮动下面的自身不浮动的内容都将围绕浮动元素进行包装,如果没有处理这些元素,就会变得很糟糕。

clear 属性

  • left:停止任何活动的左浮动
  • right:停止任何活动的右浮动
  • both:停止任何活动的左右浮动
1
2
3
footer {
clear: both;
}

结合下面的问题,应该

1
2
<div class="clearfix"></div>
<footer>foot</footer>

设置css

1
2
3
.clearfix {
clear: both;
}

事实上可以直接用伪元素选择器来清除浮动(适合浮动元素有父容器单独包裹的情况)

例:

1
2
3
4
5
6
7
8
9
<body>

<div class="wrapper">
<p class="black">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus sit amet diam. Duis mattis varius dui. Suspendisse eget dolor. Fusce pulvinar lacus ac dui.</p>
<p class="red">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus sit amet diam. Duis mattis varius dui. Suspendisse eget dolor.</p>
</div>
<p class="both">This paragraph clears both.</p>

</body>
1
2
3
4
5
6
7
8
9
10
.wrapper::after {
content: ".";/*可以使用\200B零宽度空格,这样不用设置visibility*/
clear: both;
height: 0;
display: block;
visibility: hidden;
}
.wrapper{ /*兼容IE6-7*/
*zoom: 1;
}

浮动问题

  1. 如果浮动框有内边距外边距边框等样式,布局可能损坏

    可以使用box-sizing: border-box 通过更改盒模型来使得盒子的宽度包含content + padding + border,而不仅是之前的content

  2. 因为浮动的元素存在于正常的文档布局流之外:

    • 在父元素中所占的面积的有效高度为0

    • 非浮动元素的外边距不能用于它们和浮动元素之间来创建空间

      为浮动元素后面的清除了浮动的其他元素(如footer)添加顶部外边距时不起作用的

      解决方法: 在需要清除浮动的元素前加一个空的div,将这个div的浮动清除

      Fixed layout border-box (mdn.github.io)

    • more

  3. 浮动项目的背景高度不同

    • 设定固定的height(必要时可以加上overflow: auto/scroll使内容滚动)
    • 将背景颜色都设置为父元素的背景颜色
    • 伪列技术

浮动和BFC密不可分,要熟悉BFC部分

定位

定位(positioning)能够让我们把一个元素从它原本在正常布局流(normal flow)中应该在的位置移动到另一个位置。

分类

示例:Basic document flow

  1. 静态定位(Static positioning) : 默认的属性,将元素放在文档布局流的默认位置
  1. 相对定位(Relative positioning) :相对于元素在正常的文档流中的 默认位置 偏移(对于微调和精准设计(design pinpointing)非常有用)
  1. 绝对定位(Absolute positioning) : 元素完全从页面的正常布局流(normal layout flow)中移出,放入单独的图层。相对于 <html> 元素或其最近的定位祖先⭐
  • position: absolute;

  • 不再存在于正常文档布局流中,不干扰页面上其他元素的位置的隔离

  • left/right/top/bottom指定元素应距离每个包含元素的边的距离

    • 都指定为0实际上会占满页面,但是如果为该元素指定大小,也会生效
    • margins 仍会影响定位的元素。 然而margin collapsing不会。
  • 定位上下文: 默认会被包含在 初始块容器 中。简单来说,绝对定位元素会被放在<html>元素的外面,并且根据浏览器视口来定位。

    • 设置 绝对定位元素 的 父元素 的定位属性(不为static即可)

      和BFC没有关系,因为将父容器设置为display: flow-root并不能改变定位基准

    • 示例:Positioning context (mdn.github.io)

  • 示例: Absolute positioning

  1. 固定定位(Fixed positioning) :元素相对浏览器视口固定

    • position: fixed;
    • 常用于创建持久导航菜单
    • 设置为fixed的元素不在文档流中,后面的内容会向上移动,因此可能会挡住后面的内容,可以给 后面紧跟的内容 设置上边距解决
    • 示例:Fixed positioning (mdn.github.io)
  2. 粘性定位(Sticky positioning) :让元素先保持和相对定位一样的定位(*),当它的相对视口位置(offset from the viewport)达到某一个预设值时,他就会像position: fixed一样定位。

    • position: sticky;
    • 基本上是相对位置和固定位置的混合体
    • 示例:Sticky positioning (mdn.github.io)
    • top的值设置为0,当标题滚动到视口的顶部时,支持此属性的浏览器会将标题粘贴到那个位置。随后,每个后续标题将替换前一个标题,直到它向上滚动到该位置。

    粘性定位 (mozilla.org)中说的是将静态定位与固定定位混合,定位 - 学习 Web 开发 | MDN (mozilla.org)中说的是相对定位和固定定位混合,

z-index

理解CSS的 z-index属性 - CSS(层叠样式表) | MDN (mozilla.org)

出现覆盖时,决定z轴顺序: 数字越大, 元素越接近观察者,在上面。

只对设置了定位的元素生效static以外)

示例:z-index (mdn.github.io)

表格布局

表格布局并不是用table标签进行布局,相反,CSS默认给table标签设置了表格布局的属性。

也可以用对其他元素使用table layout

display: table-caption/table-row/table-cell;

通过以上来设置表格的标题,行和单元格的元素的布局

对于标题,还可以设置caption-side: bottom/...来调整标题的位置。

基本上,它们会像HTML表格标记一样,导致标签和输入在默认情况下排列整齐。

示例: CSS tables example (mdn.github.io)

多列布局

多列布局不用设置display属性(默认是block)

可以使用 column-count属性来告诉浏览器我们需要多少列,也可以使用column-width (en-US)来告诉浏览器以至少某个宽度的尽可能多的列来填充容器。

column-gap设置间隔,column-rule设置分割线ban样式(column-width: 200px;)

为了控制文字折断,可以利用CSS分片 - CSS(层叠样式表) | MDN (mozilla.org)

添加属性break-inside: avoid;page-break-inside: avoid;


响应式设计

responsive web design,RWD

  • 媒体查询
  • 液态网格Fluid Grids
  • 液态图像 max-width: 100%

媒体查询

1
2
3
@media media-type and (media-feature-rule) {
/* CSS rules go here */
}

它由以下部分组成:

  • 媒体类型 告诉浏览器这段代码是用在什么类型的媒体上的(例如印刷品或者屏幕);
    • all
    • print
    • screen
    • speech
  • 媒体表达式 是一个被包含的CSS生效所需的规则或者测试;
    • max-width/min-width/min-height/max-height
    • orientation: portrait / landscape
    • hover:hover
    • and/or/not与或非
    • see more
  • 一组CSS规则,会在测试通过且媒体类型正确的时候应用。

断点:引入媒体查询的点

现代布局技术

  • 多列:指定column-countcolumn-width
  • flex box伸缩盒
  • 网格

响应式图像

使用了<picture>元素和<img>元素的srcsetsizes 特性,解决了这两个问题。

响应式图片 - see more)

视口元标签与视口单位

视口元标签

1
<meta name="viewport" content="width=device-width,initial-scale=1">
  • initial-scale:设定了页面的初始缩放,我们设定为1。
  • height:特别为视口设定一个高度。
  • minimum-scale:设定最小缩放级别。(尽量避免)
  • maximum-scale:设定最大缩放级别。(尽量避免)
  • user-scalable:如果设为no的话阻止缩放。(不推荐)

永远都不要只用viewport单位设定文本 ,会使用户失去放缩任何使用vw单位的文本的能力

可以用calc混合vw单位盒固定大小 font-size: calc(1.5rem + 3vw);

MDN上的练习解: [FE-learning/MDN practice/layout/fundamental-layout-comprehension at main · Augu1sto/FE-learning (github.com)](“https://github.com/Augu1sto/FE-learning/tree/main/MDN practice/layout/fundamental-layout-comprehension”)