选择器

选择器 示例 学习 CSS 的教程
类型选择器 h1 { } 类型选择器
通配选择器 * { } 通配选择器
类选择器 .box { } 类选择器
ID 选择器 #unique { } ID 选择器
标签属性选择器 a[title] { } 标签属性选择器
伪类选择器 p:first-child { } 伪类
伪元素选择器 p::first-line { } 伪元素
后代选择器 article p 后代运算符
子代选择器 article > p 子代选择器
相邻兄弟选择器 h1 + p 相邻兄弟
通用兄弟选择器 h1 ~ p 通用兄弟

@规则

@media(min-width: 1em){}

flex 模型说明

当元素表现为 flex 框时,它们沿着两个轴来布局:

  • 主轴(main axis)是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。该轴的开始和结束被称为 main startmain end
  • 交叉轴(cross axis)是垂直于 flex 元素放置方向的轴。该轴的开始和结束被称为 cross startcross end
  • 设置了 display: flex 的父元素(在本例中是 ``)被称之为 flex 容器(flex container)。
  • 在 flex 容器中表现为柔性的盒子的元素被称之为 flex 项flex item)(本例中是 `` 元素。

设置默认排布(默认为从左到右,按行)

1
flex-direction: column;

备注: 你还可以使用 row-reversecolumn-reverse 值反向排列 flex 项目。用这些值试试看吧!

换行

当在布局中使用定宽或者定高时,可能出现弹性盒子子元素溢出,破坏了布局,这时可以通过以下方式换行:

1
flex-wrap: wrap

flex-flow 缩写

flex-directionflex-wrap — 的缩写 flex-flow

1
2
flex-direction: row;
flex-wrap: wrap;

Copy to Clipboard

替换为

1
flex-flow: row wrap;

flex 项的动态尺寸

相当于权重

1
2
3
article {
flex: 1;
}

设置了每个article盒子占用宽度相同,设置为1999效果相同。

1
2
3
4
5
6
article {
flex: 1;
}
article:nth-of-type(3) {
flex: 2;
}

这样设置就让第三个盒子是其他盒子的两倍宽。

1
2
3
4
5
6
7
article {
flex: 1 200px;
}

article:nth-of-type(3) {
flex: 2 200px;
}

这样设置可以同时指定最小宽度。

flex: 缩写与全写

flex 是一个可以指定最多三个不同值的缩写属性:

  • 第一个就是上面所讨论过的无单位比例。可以单独指定全写 flex-grow 属性的值。
  • 第二个无单位比例 — flex-shrink — 一般用于溢出容器的 flex 项。这指定了从每个 flex 项中取出多少溢出量,以阻止它们溢出它们的容器。这是一个相当高级的弹性盒子功能,我们不会在本文中进一步说明。
  • 第三个是上面讨论的最小值。可以单独指定全写 flex-basis 属性的值。

水平和垂直对齐

image-20221011083044772

1
2
3
4
div {
display: flex;
align-items: stretch;
}

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

  • 默认的值是 stretch,其会使所有 flex 项沿着交叉轴的方向拉伸以填充父容器。如果父容器在交叉轴方向上没有固定宽度(即高度),则所有 flex 项将变得与最长的 flex 项一样长(即高度保持一致)。我们的第一个例子在默认情况下得到相等的高度的列的原因。
  • 在上面规则中我们使用的 center 值会使这些项保持其原有的高度,但是会在交叉轴居中。这就是那些按钮垂直居中的原因。
  • 你也可以设置诸如 flex-startflex-end 这样使 flex 项在交叉轴的开始或结束处对齐所有的值。查看 [align-items`](https://developer.mozilla.org/zh-CN/docs/Web/CSS/align-items) 了解更多。

image-20221011083118717

image-20221011083218076

justify-content 控制 flex 项在主轴(x)上的位置。

  • 默认值是 flex-start,这会使所有 flex 项都位于主轴的开始处。
  • 你也可以用 flex-end 来让 flex 项到结尾处。
  • centerjustify-content 里也是可用的,可以让 flex 项在主轴居中。
  • 而我们上面用到的值 space-around 是很有用的——它会使所有 flex 项沿着主轴均匀地分布,在任意一端都会留有一点空间。
  • 还有一个值是 space-between,它和 space-around 非常相似,只是它不会在两端留下任何空间。

image-20221011083845393

image-20221011083604818

image-20221011083821715

image-20221011083921630

image-20221011084257938

flex 项排序

弹性盒子也有可以改变 flex 项的布局位置的功能,而不会影响到源顺序(即 dom 树里元素的顺序)。这也是传统布局方式很难做到的一点。

  • 所有 flex 项默认的 order 值是 0。
  • order 值大的 flex 项比 order 值小的在显示顺序中更靠后(可以设置负值)。
  • 相同 order 值的 flex 项按源顺序显示。所以假如你有四个元素,其 order 值分别是 2,1,1 和 0,那么它们的显示顺序就分别是第四,第二,第三,和第一。
  • 第三个元素显示在第二个后面是因为它们的 order 值一样,且第三个元素在源顺序中排在第二个后面。

image-20221011084652672

image-20221011084619608

flex 嵌套

案例结构

1
2
3
4
5
6
7
section - article
article
article - div - button
div button
div button
button
button

设置section为弹性容器

1
2
3
section {
display: flex;
}

设置article flex项的占比及最小宽度

1
2
3
article {
flex: 1 200px;
}

设置section第三个article flex项:

规定其占比以及最小宽度、设置其为弹性容器、规定其子节点为列布局

1
2
3
4
5
article:nth-of-type(3) {
flex: 3 200px;
display: flex;
flex-flow: column;
}

设置第三个article的第一个div flex项:

设置其占比及最小宽度、设置其为弹性容器、规定为包装行(即行布局,出现溢出就换行)、子节点垂直居中、子节点水平均匀分布。

1
2
3
4
5
6
7
article:nth-of-type(3) div:first-child {
flex: 1 100px;
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: space-around;
}

单独设置第一个div的button flex项的占比、间距、字体大小、行高。

1
2
3
4
5
6
button {
flex: 1;
margin: 5px;
font-size: 18px;
line-height: 1.5;
}

网格布局

定义网格

首先,将容器的display属性设置为grid来定义一个网络。与弹性盒子一样,将父容器改为网格布局后,他的直接子项会变为网格项。把下面的 css 规则加到你的文件中。

1
2
3
.container {
display: grid;
}

此时页面不会发生变化,因为当前只创建了一个只有一列的网格,所以你的子项还是会像正常布局流那样从上而下一个接一个的排布。

可以使用grid-template-columns属性为网格添加列。

1
2
3
4
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
}

有多少值就有多少列,值可以为百分比。

使用 fr 单位的灵活网格

类似权重,表示了可用空间的占比

1
2
3
4
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}

备注: fr单位分配的是可用空间而非所有空间,所以如果某一格包含的内容变多了,那么整个可用空间就会减少,可用空间是不包括那些已经确定被占用的空间的。

网格间隙

使用 grid-column-gap (en-US) 属性来定义列间隙;使用 grid-row-gap (en-US) 来定义行间隙;使用 grid-gap (en-US) 可以同时设定两者。

1
2
3
4
5
.container {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
grid-gap: 20px;
}

image-20221012083846019

间隙距离可以用任何长度单位包括百分比来表示,但不能使用fr单位。

备注: *gap属性曾经有一个grid-前缀,不过后来的标准进行了修改,目的是让他们能够在不同的布局方法中都能起作用。尽管现在这个前缀不会影响语义,但为了代码的健壮性,你可以把两个属性都写上。

image-20221012084014844

重复构建行/列

使用repeat()函数

1
2
3
4
5
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
}
  • repeat(3,1fr) ==1fr 1fr 1fr
  • repeat(2,50px 10px) == 50px 10px 50px 10px

显式网格与隐式网格

显式网格是我们用grid-template-columnsgrid-template-rows 属性创建的。

隐式网格则是当有内容被放到网格外时才会生成的。

显式网格与隐式网格的关系与弹性盒子的 main 和 cross 轴的关系有些类似。

隐式网格中生成的行/列大小是参数默认是auto,大小会根据放入的内容自动调整。当然,你也可以使用grid-auto-rowsgrid-auto-columns属性手动设定隐式网格的大小。

注:简单来说,隐式网格就是为了放显式网格放不下的元素,浏览器根据已经定义的显式网格自动生成的网格部分。

方便的 minmax() 函数

可以设置行/列宽高,并可以跟随内容自动拓展。

举例:

希望高度至少为100px,最大值不限制。

  • minmax(100px,auto)

自动使用多列填充

grid-template-columns中组合使用repeat()minmax()函数

  • repeat()函数第一个参数使用auto-full,自动决定列数
  • 第二个参数使用minmax(),其中minmax()的第二个参数,使用1fr
1
2
3
4
5
6
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-rows: minmax(100px, auto);
grid-gap: 20px;
}

基于线的元素放置

我们的网格有许多分隔线,第一条线的起始点与文档书写模式相关。

在英文中,第一条列分隔线(即网格边缘线)在网格的最左边而第一条行分隔线在网格的最上面。

而对于阿拉伯语,第一条列分隔线在网格的最右边,因为阿拉伯文是从右往左书写的。

1
2
3
4
grid-column-start (en-US)
grid-column-end (en-US)
grid-row-start (en-US)
grid-row-end (en-US)

简化

1
2
grid-column
grid-row

效果类似于colspan/rowspan可用于控制跨行跨列和指定容器位置。

1
2
grid-column: 1 / span 2
grid-row: 2 / span 2
  • /前的值为起始位,之后的值为结束位或跨越行列数

注意

当有12列时,起始位为1,结束位为13,行同理。

image-20221012094606212

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

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

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

这种方法相当直观

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.container {
display: grid;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
grid-template-columns: 1fr 3fr;
grid-gap: 20px;
}

header {
grid-area: header;
}

article {
grid-area: content;
}

aside {
grid-area: sidebar;
}

footer {
grid-area: footer;
}

浮动

浮动元素会脱离正常的文档布局流,并吸附到其父容器的左边。在正常布局中位于该浮动元素之下的内容,此时会围绕着浮动元素,填满其右侧的空间。

让浮动效果可视化

给紧随浮动盒子的元素上添加 special

1
2
3
4
5
.special {
background-color: rgb(79,185,227);
padding: 10px;
color: #fff;
}

清除浮动

clear 属性接受下列值:

  • left:停止任何活动的左浮动
  • right:停止任何活动的右浮动
  • both:停止任何活动的左右浮动

clearfix 小技巧

传统上,这个问题通常由所谓的 “clearfix 小技巧” 解决,其过程为:先向包含浮动内容及其本身的盒子后方插入一些生成的内容,并将生成的内容清除浮动。

1
2
3
4
5
.wrapper::after {
content: "";
clear: both;
display: block;
}

现在重载页面,盒子的浮动就应该清除了。这与在浮动盒子后手动添加诸如 div 的 HTML 元素,并设置其样式为 clear:both 是等效的。

使用 overflow

一个替代的方案是将包裹元素的 overflow 属性设置为除 visible 外的其他值。

1
2
3
4
5
6
.wrapper {
background-color: rgb(79,185,227);
padding: 10px;
color: #fff;
overflow: auto;
}

这个例子之所以能够生效,是因为创建了所谓的 块格式化上下文(BFC)。可以把它看作页面内部包含所需元素的一小块布局区域。如此设置可以让浮动元素包含在 BFC 及其背景之内。大部分情况下这种小技巧都可以奏效,但是可能会出现莫名其妙的滚动条或裁剪阴影,这是使用 overflow 带来的一些副作用。

display: flow-root

一个较为现代的方案是使用 display 属性的 flow-root 值。它可以无需小技巧来创建块格式化上下文(BFC),在使用上没有副作用。

1
2
3
4
5
6
.wrapper {
background-color: rgb(79,185,227);
padding: 10px;
color: #fff;
display: flow-root;
}