wangpengfei
3 years ago
23 changed files with 4168 additions and 0 deletions
@ -0,0 +1,60 @@ |
|||||||
|
# 盒模型(box model) |
||||||
|
|
||||||
|
*html页面中任何元素都是一个盒子(box)。学好css的基础是理解盒模型的工作原理。* |
||||||
|
|
||||||
|
## 内容和大小 |
||||||
|
|
||||||
|
盒子的大小可以有两种控制方式: |
||||||
|
- **extrinsic sizing**: 显示设置盒子的`width`和`height`为固定尺寸,例如设置`width`和`height`为400px、600px,那么盒子的大小就固定了。 |
||||||
|
- **intrinsic sizing**: 不设置盒子的大小,或者设置盒子的大小为非固定尺寸,例如设置`width`和`height`属性值为`min-content`或者`max-content`, 此时盒子的大小由浏览器决定,浏览器会根据内容自动调整盒子的大小。 |
||||||
|
|
||||||
|
请看下面的例子,看看这两种方式有什么区别。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="001 Box Model_1" src="https://codepen.io/AhCola/embed/KKmyQYP?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/KKmyQYP"> |
||||||
|
001 Box Model_1</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
上例中,p1没有设置width和height,p1是一个block,所以它会占满父元素的整个内容宽度。p2和p3通过设置`width: min-content`、`width: max-content`,它们的宽度由内容决定。p4设置宽度高度为固定尺寸,此时内容过多导致`overflow`出现。 |
||||||
|
|
||||||
|
## 盒模型的区域 |
||||||
|
|
||||||
|
盒模型由图中几个区域组成,每个区域都有不同的作用。 |
||||||
|
|
||||||
|
![盒模型](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/91.jpg) |
||||||
|
|
||||||
|
*盒模型组成:Margin box(外边距)、Border box(边框)、Padding box(内边距)、Content box(内容)* |
||||||
|
|
||||||
|
- **content box(内容)**:子元素放置的地方,前面讲过内容可以控制父元素盒子的大小。 |
||||||
|
- **padding box(内边距)**:内边距是环绕在内容外围的一个区域,当你设置盒子的背景`background`时,内边距区域也会受到影响。当设置`overflow: scroll`时,并且出现了overflow的情况,滚轮也会占据这一块区域。 |
||||||
|
- **border box(边框)**:表示盒子的边框,通过`border`属性可以设置盒子的边框样式。 |
||||||
|
- **margin box(外边距)**:盒子外围的一块区域,通过`margin`属性可以设置盒子的外边距。`outline`和`box-shadow`会占据这块区域,设置外边距的样式并不会影响盒子内部内容。 |
||||||
|
|
||||||
|
在谷歌浏览器中,点击F12打开开发者工具,选中一个元素,可以在下方样式看到该元素的盒子各区域尺寸详情。 |
||||||
|
|
||||||
|
![盒模型](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/92.jpg) |
||||||
|
|
||||||
|
通常,浏览器会给我们的html页面设置一个默认样式(user agent style)。例如,一个段落`p`的`display`为`block`,而`span`的`display`为`inline`,这些都是默认的样式。我们可以通过设置css来覆盖这些默认样式。 |
||||||
|
|
||||||
|
## box-sizing属性 |
||||||
|
|
||||||
|
`box-sizing`定义了如何去计算一个元素的高度和宽度。当你设置了元素的`width`和`height`尺寸时,默认情况下设置的是content区域的尺寸,这意味着盒子最终的大小为会加上borderSize和paddingSize,而不是你设置的尺寸。我们可以设置`box-sizing`为`border-box`, 覆盖这一默认行为,此时我们设置的`width`和`height`尺寸就是盒子最终的尺寸(包括边框和内边距)。请看下面的例子: |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="001 Box Model_2" src="https://codepen.io/AhCola/embed/yLbPKNe?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/yLbPKNe"> |
||||||
|
001 Box Model_2</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
p1和p2的box-sizing属性不同,即使我们设置的`width`、`height`和`padding`大小一样,最终盒子的大小也不一样。 |
||||||
|
|
||||||
|
box-sizing可以设置如下两种值: |
||||||
|
- `content-box`: 是默认值。如果你设置一个元素的宽为100px,那么这个元素的内容区会有100px 宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中。 |
||||||
|
- `border-box`: 你想要设置的边框和内边距的值是包含在width内的。也就是说,如果你将一个元素的width设为100px,那么这100px会包含它的border和padding,内容区的实际宽度是width减去(border + padding)的值。大多数情况下,这使得我们更容易地设定一个元素的宽高。 |
||||||
|
|
||||||
|
## 附:参考资料 |
||||||
|
- 谷歌learn css: [https://web.dev/learn/css/box-model/](https://web.dev/learn/css/box-model/) |
||||||
|
|
||||||
|
- MDN: [Web Docs](https://developer.mozilla.org/zh-CN/docs/Web/CSS/box-sizing) |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,229 @@ |
|||||||
|
# 选择器(selector) |
||||||
|
|
||||||
|
*CSS提供了几种方式,可以让开发者将css样式应用到指定的html元素。本节内容将会讲述这些方式。* |
||||||
|
|
||||||
|
## 一.CSS规则(rules) |
||||||
|
|
||||||
|
首先,我们简单的看下css语法的结构,假设有如下css规则: |
||||||
|
|
||||||
|
```css |
||||||
|
.class-rule { |
||||||
|
background: red; |
||||||
|
color: green; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
上面是一个简单的css规则,它将类名为`class-rule`的所有元素的背景色设置为红色,颜色设置为绿色。在css代码中,`.class-rule`称之为**选择器(Selector)**, 用于说明这个样式规则将应用于哪个元素。大括号之间包裹的内容是**属性声明(Declaration)**部分,一个规则可以有多个样式声明,例如上面中有两个声明,background和color。每个声明由属性名称(Property)和属性值(Value)组成。 |
||||||
|
|
||||||
|
## 二.简单选择器 |
||||||
|
|
||||||
|
简单选择器使用html元素的类型名(type)、类名(class)、属性(attribute)和Id指定元素。 |
||||||
|
|
||||||
|
### 通配选择器 |
||||||
|
|
||||||
|
**通配选择器(universal selector)**使用一个通配符号`*`表示匹配所有元素。 |
||||||
|
|
||||||
|
```css |
||||||
|
* { |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
这个规则表示将所有元素的外边距和内边距都设置为0。一般在项目中,我习惯用这段代码,覆盖浏览器的默认样式,使元素初始边距为0。 |
||||||
|
|
||||||
|
### 类型选择器 |
||||||
|
|
||||||
|
**类型选择器(type selector)**也叫做**标记选择器(tag selector)**,使用元素的tag名作为选择器。 |
||||||
|
|
||||||
|
```css |
||||||
|
p { |
||||||
|
font-size: 18px; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
上面的规则将页面中所有的段落(paragraph)的字体设置为18px粗体。 |
||||||
|
|
||||||
|
### 类选择器 |
||||||
|
|
||||||
|
一个html元素可以有0个或者多个类名。 |
||||||
|
|
||||||
|
```html |
||||||
|
<p class="p1 bold">This is a statment.<p> |
||||||
|
<p class="p2">This is a statment.<p> |
||||||
|
``` |
||||||
|
|
||||||
|
我们可以使用类名作为选择器,来指定特定的html元素。为了区别类型选择器和**类选择器**,类选择器使用`.`加上类名作为选择器名称。将以下规则用于页面: |
||||||
|
|
||||||
|
```css |
||||||
|
.bold { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
页面中第一个段落文字将会显示为红色,因为`.bold`表示这个规则应用于类名包含bold的元素。 |
||||||
|
|
||||||
|
### ID选择器 |
||||||
|
|
||||||
|
一般html页面中,元素的ID是唯一的。虽然多个元素拥有相同的id,浏览器并不会报错,但是我们在写html时,也要遵循这个规范,保证所有元素的id都是唯一的。 |
||||||
|
|
||||||
|
可以使用id作为选择器,指定css规则应用的元素。为了使用id作为选择器,我们用符号`#`放置于id前面,表示这是一个ID选择器。看下面的代码: |
||||||
|
|
||||||
|
```html |
||||||
|
<p id="p1">This is first paragraph.</p> |
||||||
|
<p id="p2">This is second paragraph.</p> |
||||||
|
|
||||||
|
... |
||||||
|
<style> |
||||||
|
#p1 { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
#p2 { |
||||||
|
color: blue; |
||||||
|
} |
||||||
|
</style> |
||||||
|
``` |
||||||
|
|
||||||
|
p1会显示为红色,p2显示为蓝色。html的每个元素的id字段,不能像类名那样设置为多个,例如下面这样是错误的。 |
||||||
|
|
||||||
|
```html |
||||||
|
<p id="id1 id2">This is a paragrahp.</p> |
||||||
|
``` |
||||||
|
|
||||||
|
### 属性选择器 |
||||||
|
|
||||||
|
html元素可以设置属性,例如上面的class和id都是html元素的属性,我们也可以添加更多的属性。 |
||||||
|
``` |
||||||
|
<p att1="1" att2="2" att3="3">This is a paragraph.</p> |
||||||
|
``` |
||||||
|
|
||||||
|
属性选择器用中括号`[attributeName='attributeValue']`表示,attributeName表示属性名称,attributeValue指示这个属性的值。例如,将包含属性**att**,并且属性值为**attValue**的元素的颜色改为红色,可以这样写: |
||||||
|
|
||||||
|
```css |
||||||
|
[att='attValue'] { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
我们也可以,不设置属性值,那么这个规则就会被应用于所有含att属性的元素。 |
||||||
|
|
||||||
|
```css |
||||||
|
[att] { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
有一点需要注意的是,属性值不是大小写敏感的。如果选择器为`[att='attValue']`, 那么下面两个元素都会应用这个规则: |
||||||
|
|
||||||
|
```css |
||||||
|
<p att="attValue">This is a paragraph.</p> |
||||||
|
<p att="ATTVALUE">This is a paragraph.</p> |
||||||
|
``` |
||||||
|
|
||||||
|
可以在选择器中添加`s`标记`[att='attValue' s]`,表示此时属性选择器是大小写敏感的。默认情况是不分大小写的,也可以添加`i`标记显示指定这个选择器非大小写敏感。 |
||||||
|
|
||||||
|
除了大小写敏感标记符号,你还可以指定属性值部分匹配元素属性值。 |
||||||
|
|
||||||
|
```css |
||||||
|
/* 匹配href属性值包含“example.com”的元素 */ |
||||||
|
[href*='example.com'] { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
|
||||||
|
/* 匹配href属性值以“https”开头的元素 */ |
||||||
|
[href^='https'] { |
||||||
|
color: green; |
||||||
|
} |
||||||
|
|
||||||
|
/* 匹配href属性以“.com”结尾的元素 */ |
||||||
|
[href$='.com'] { |
||||||
|
color: blue; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### 组合选择器 |
||||||
|
|
||||||
|
一个规则,并不一定只设置一个选择器,可以设置多个选择器,用逗号隔开即可。 |
||||||
|
|
||||||
|
```css |
||||||
|
p, |
||||||
|
a, |
||||||
|
#id, |
||||||
|
.class { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
``` |
||||||
|
这个规则会匹配所有段落`p`、所有链接`a`、id为`id`的元素和所有类名为`class`的元素,我们称这种选择器为组合选择器。 |
||||||
|
|
||||||
|
## 三. 伪类和伪元素 |
||||||
|
|
||||||
|
### 伪类 |
||||||
|
|
||||||
|
伪类(Pseudo-classes),使元素在不同状态下,应用不同的样式规则。例如,当鼠标悬浮在元素上时,可以使用`:hover`指定规则应用于这个状态。 |
||||||
|
|
||||||
|
```css |
||||||
|
// 当鼠标悬浮在段落p上时,颜色为红色 |
||||||
|
p:hover { |
||||||
|
color: red |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
后面我会补充关于伪类更多的细节,这里只做简单的介绍。 |
||||||
|
|
||||||
|
|
||||||
|
### 伪元素 |
||||||
|
|
||||||
|
伪元素是一个附加至选择器末的关键词,允许你对被选择元素的特定部分修改样式。使用伪元素,就好像你在html页面中插入了一个新的元素。伪元素用双冒号`::`表示。 |
||||||
|
|
||||||
|
```css |
||||||
|
.my-element::before { |
||||||
|
content: 'Prefix - '; |
||||||
|
} |
||||||
|
``` |
||||||
|
这个规则,会应用到类名为`my-element`的元素,在该元素前插入`Prefix-`文字。也可以使用`::after`修改元素后面的样式。 |
||||||
|
|
||||||
|
还可以使用`::marker`修改某些标记,例如修改无序列表前面的点或者有序列表前面的数字样式。使用`::selection`修改用户选择某段文字后显示的样式。 |
||||||
|
|
||||||
|
```css |
||||||
|
li::marker { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
|
||||||
|
p::selection { |
||||||
|
background: green; |
||||||
|
color: white; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## 四.复杂选择器 |
||||||
|
|
||||||
|
|
||||||
|
### 组合器 |
||||||
|
|
||||||
|
**组合器(combinator)**是位于两个选择器中间的符号,例如`div>p`中`>`就是一个组合器。组合器有以下几种: |
||||||
|
- 后代选择器 : 用空格(` `)表示,匹配父元素后代子孙节点中的元素,例如`div p`匹配div中所有的段落,不一定是儿子结点,也可以是孙子结点。 |
||||||
|
- 相邻下一个兄弟节点:用`+`表示,匹配同级节点的紧邻下一个元素。例如`div+p`匹配div后面与该div紧邻着的段落,p与div之间不能有其他元素。 |
||||||
|
- 后面所有的兄弟节点:用`~`表示,匹配同级节点的后面的元素,不要求是紧邻的元素。例如`div~p`匹配div后面所有同级的`<P>`元素。 |
||||||
|
- 子选择器:用`>`表示,匹配某个元素的孩子结点。例如`div>p`表示div中所有p孩子元素。 |
||||||
|
|
||||||
|
|
||||||
|
### 复合选择器 |
||||||
|
|
||||||
|
你可以组合多个选择器,增强代码的可读性和规则的功能。例如,你想将规则应用于类名为`cls`的`<a>`元素,将其颜色设置为红色,可以这样写: |
||||||
|
|
||||||
|
``` |
||||||
|
a.cls { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
注意,与组合器不同的是,复合选择器在选择器之间不包含任何符号和空格。 |
||||||
|
|
||||||
|
## 附:参考资料 |
||||||
|
|
||||||
|
- MDN: [selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) |
||||||
|
- 谷歌learn css:[selectors](https://web.dev/learn/css/selectors/) |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,116 @@ |
|||||||
|
# 级联 |
||||||
|
|
||||||
|
*有时候,有多个相同的css规则可以被应用于同一个元素。此时浏览器需要使用级联算法确定最后使用哪一个css规则进行页面渲染。* |
||||||
|
|
||||||
|
css是**级联样式表(Cascading Stylesheets)**。*级联*是解决当多个css规则被同时应用于一个html元素时产生的冲突的一种算法。正因为级联,下面的按钮才会被渲染成蓝色: |
||||||
|
|
||||||
|
```html |
||||||
|
<style> |
||||||
|
button { |
||||||
|
color: red |
||||||
|
} |
||||||
|
button { |
||||||
|
color: blue; |
||||||
|
} |
||||||
|
<style> |
||||||
|
|
||||||
|
... |
||||||
|
|
||||||
|
<button>This is blue</button> |
||||||
|
``` |
||||||
|
|
||||||
|
理解级联的目的,就是为了理解浏览器是如何解决此类冲突的。级联算法分为以下四个模块: |
||||||
|
- **位置和出现的顺序**:css规则出现的顺序。 |
||||||
|
- **特征性(具体性 Specificity)**:确定css选择器具有最高匹配权的算法。 |
||||||
|
- **来源**: css在何时何处生成。它是否是一个浏览器样式或者是浏览器插件添加的样式,又或者是你写的css代码。 |
||||||
|
- **重要性**:一些css规则具有更高的重要性,特别是包含`!important`值的规则。 |
||||||
|
|
||||||
|
## 一.位置和出现的顺序 |
||||||
|
|
||||||
|
级联规则在解决css规则冲突时,会考虑css规则出现的位置和顺序。 |
||||||
|
|
||||||
|
一般一个页面可能包含多种来源不同的css样式。例如`<link>`标签引入的css文件、`<style>`标签内部的样式或者是定义在元素`style`属性中。 |
||||||
|
|
||||||
|
但是只需要记住一点,**位置越靠后的样式一般具有更高的重要性**。假设在html顶部有一个`<link>`样式,html页面底部也有一个`<link>`样式,那么底部的`<link>`样式会在css规则冲突中胜出,因为位置比较靠后。这一点对`<style>`标签内的样式也适用,但是不适用于元素的`style`属性,`style`属性的重要性会比`<link>`和`<style>`标签高。 |
||||||
|
|
||||||
|
下面的demo中,按钮显示红色。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="003 Box_Model 1" src="https://codepen.io/AhCola/embed/JjNpNJj?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/JjNpNJj"> |
||||||
|
003 Box_Model 1</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
前面说过,这个规则不适用于内联样式,内联样式就是通过元素style属性定义的样式。内联样式会覆盖所有其他的css,无论这些css出现的位置和顺序,除非css规则的声明值定义为`!important`,`!important`比内联样式的重要性更高。 |
||||||
|
|
||||||
|
这个规则同样适用于同一个规则块内,同规则的重复设置。下面的代码,背景色将会显示为`purple`: |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
background: green; |
||||||
|
background: purple; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## 二.特征性(具体性 Specificity) |
||||||
|
|
||||||
|
特征性是一种决定哪个css选择器最具体的算法。这里的最具体的意思,你可以看成哪个css权重最高的意思,选择器权重最高的css规则,在规则冲突中将会胜出。 |
||||||
|
|
||||||
|
有了特征性算法,即使有多个不同的css规则具有不同的选择器产生了规则冲突,浏览器也可以决定最后使用哪个css规则去渲染页面。 |
||||||
|
|
||||||
|
关于特征性,我将在下一节内容进行讲解。你可以学到特征性是如何计算的。 |
||||||
|
|
||||||
|
现在你只需要知道,类选择器的特征性高于类型选择器(标签选择器),ID选择器特征性高于类选择器。 |
||||||
|
|
||||||
|
因为ID选择器的特征性比较高,所以下面的按钮将会显示为`green`。 |
||||||
|
```css |
||||||
|
button { |
||||||
|
color: blue; |
||||||
|
} |
||||||
|
|
||||||
|
.button { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
|
||||||
|
#button { |
||||||
|
color: green; |
||||||
|
} |
||||||
|
|
||||||
|
... |
||||||
|
|
||||||
|
<button id="button" class="button">This is a green button</button> |
||||||
|
``` |
||||||
|
|
||||||
|
关于特征性,还需要说明的是,特征性可以累加的。如果一个选择器很复杂,因为权重的累加效果,它的最终权重往往会比较高。例如`a.my-class.another-class[href]:hover`,这样一个选择器,它的css样式一般都会被应用于页面,因为你很难写出比它权重还高的样式了,所以出于这个原因,建议大家在写css时,尽量避免写这种复杂的规则,保持选择器简洁是一个比较好的习惯。 |
||||||
|
|
||||||
|
## 三.来源 |
||||||
|
|
||||||
|
css来自不同的地方,也会影响是否会在规则冲突中胜出。关于样式的来源的特征性从低到高如下: |
||||||
|
|
||||||
|
1. 用户代理样式:也就是浏览器默认样式。 |
||||||
|
2. 本地用户样式:一般来源于系统设定,也可以是浏览器插件设定的样式。某些浏览器插件允许用户定义自己的浏览器页面样式。 |
||||||
|
3. 开发者定义的css规则:指网页开发者写下的css样式。 |
||||||
|
4. 标记为`!important`的css: 网页开发者写的含`!important`标记的css样式。 |
||||||
|
5. 含`!important`的本地用户样式:与2来源相同,不过这个css含有`!important`标记。 |
||||||
|
6. 含`!important`的用户代理样式:与1来源相同,不过这个css含有`!important`标记。 |
||||||
|
|
||||||
|
## 四.重要性 |
||||||
|
|
||||||
|
并不是所有的css规则都和其他css按照同样方式计算特征性。 |
||||||
|
|
||||||
|
不同种类的css规则重要性从低到高依次如下: |
||||||
|
|
||||||
|
1. 普通规则:例如`font-size`、`background`或者`color`。 |
||||||
|
2. `animation`规则。 |
||||||
|
3. `!important`规则。 |
||||||
|
4. `transition`规则。 |
||||||
|
|
||||||
|
所以当某些动画规则或者变换规则激活时,它会取代普通规则,进行渲染页面。 |
||||||
|
|
||||||
|
|
||||||
|
## 附:参考资料 |
||||||
|
|
||||||
|
谷歌learn css: [The cascade](https://web.dev/learn/css/the-cascade/) |
||||||
|
|
||||||
|
MDN: [Cascade and inheritance](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance) |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,151 @@ |
|||||||
|
# 特征性 |
||||||
|
|
||||||
|
*特征性是级联算法的一个关键部分,本节内容将深入了解特征性。* |
||||||
|
|
||||||
|
[上一节](http://pengfeixc.com/tutorial/css/cascade),介绍了级联算法,级联算法是为了解决css规则冲突的算法。而特征性作为其中一个重要部分,我们有必要去弄懂它。 |
||||||
|
|
||||||
|
假设有如下css和html: |
||||||
|
```html |
||||||
|
<button>color?</button> |
||||||
|
|
||||||
|
button { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
|
||||||
|
.branding { |
||||||
|
color: blue; |
||||||
|
} |
||||||
|
``` |
||||||
|
按钮文字将显示蓝色。因为类选择器的权重高于类型选择器。 |
||||||
|
|
||||||
|
## 一.特征性分数(权重) |
||||||
|
|
||||||
|
比较两个选择器的特征性(权重)大小,实际上是计算两个选择器的分数(权重,后面我统称权重),权重大的将会在规则冲突中胜出。 |
||||||
|
|
||||||
|
### 不同选择器的权重 |
||||||
|
|
||||||
|
#### 通配选择器 |
||||||
|
|
||||||
|
通配选择器(*),没有特征性,它的权重为**0**。这意味着任何其他权重大于0的选择器都会覆盖通配选择器的规则。 |
||||||
|
```css |
||||||
|
* { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
#### 类型选择器和伪元素选择器 |
||||||
|
|
||||||
|
类型选择器,也可以叫做标签选择器,还可以被叫做元素选择器,具体叫法随意,只要你明白就行了。类型选择器和伪元素选择器的权重都为**1**。 |
||||||
|
```css |
||||||
|
// 类型选择器 |
||||||
|
div { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
|
||||||
|
// 伪元素选择器 |
||||||
|
::selection { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
``` |
||||||
|
#### 类选择器、伪类选择器和属性选择器 |
||||||
|
|
||||||
|
类选择器、伪类选择器和属性选择器的权重为**10**。 |
||||||
|
```css |
||||||
|
// 类选择器 |
||||||
|
.my-class { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
|
||||||
|
// 伪类选择器 |
||||||
|
:hover { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
|
||||||
|
// 属性选择器 |
||||||
|
[href='#'] { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
#### ID选择器 |
||||||
|
|
||||||
|
ID选择器的权重为**100**。 |
||||||
|
```css |
||||||
|
#myID { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
#### 内联样式 |
||||||
|
|
||||||
|
内联样式的权重为**1000**。 |
||||||
|
```html |
||||||
|
<div style="color: red">内联样式的权重为1000</div> |
||||||
|
``` |
||||||
|
|
||||||
|
#### !important |
||||||
|
|
||||||
|
含`!important`的规则的权重为**10000**,如果你写下了一个`!important`的规则,前面提到的所有种类的规则都将会被覆盖。 |
||||||
|
```css |
||||||
|
.my-class { |
||||||
|
color: red !important; /* 10,000 points */ |
||||||
|
background: white; /* 10 points */ |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## 二. 权重的累加 |
||||||
|
|
||||||
|
前面讲过,一个选择器的权重分数是累加计算的。下面以一个例子说明。 |
||||||
|
假设有如下html: |
||||||
|
```html |
||||||
|
<a class="my-class another-class" href="#">A link</a> |
||||||
|
``` |
||||||
|
|
||||||
|
下面的css,权重为1: |
||||||
|
```css |
||||||
|
a { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
``` |
||||||
|
然后,增加一个类使选择器更具体,此时权重为11: |
||||||
|
```css |
||||||
|
a.my-class { |
||||||
|
color: green; |
||||||
|
} |
||||||
|
``` |
||||||
|
再添加另一个类名,权重变为21: |
||||||
|
```css |
||||||
|
a.my-class.another-class { |
||||||
|
color: rebeccapurple; |
||||||
|
} |
||||||
|
``` |
||||||
|
在上面的基础上,添加一个属性,权重更新为31: |
||||||
|
```css |
||||||
|
a.my-class.another-class[href] { |
||||||
|
color: goldenrod; |
||||||
|
} |
||||||
|
``` |
||||||
|
最后,添加一个伪类,权重为41: |
||||||
|
```css |
||||||
|
a.my-class.another-class[href]:hover { |
||||||
|
color: lightgrey; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## 三.可视化特征性 |
||||||
|
|
||||||
|
至此你应该知道了如何去计算一个选择性的权重(分数)。如何去写一个规则覆盖另一个规则。下面的示意图很好的总结了各类型选择器的权重(分数)。 |
||||||
|
|
||||||
|
![css选择器权重](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/93.jpg) |
||||||
|
|
||||||
|
最左侧是id选择器,中间是类选择器、属性选择器和伪类选择器,最后面是元素选择器和伪元素选择器。 |
||||||
|
|
||||||
|
如果用图中的格式描述权重,下面的权重为`0-4-1`: |
||||||
|
```css |
||||||
|
a.my-class.another-class[href]:hover { |
||||||
|
color: lightgrey; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
|
||||||
|
(完)。 |
@ -0,0 +1,117 @@ |
|||||||
|
# 继承 |
||||||
|
|
||||||
|
*某些css属性,如果你不显示设置它的值,那么它的值会从父节点继承。本节内容将会讲述继承是如何工作的,怎么去利用这一特性。* |
||||||
|
|
||||||
|
## 一. 继承流 |
||||||
|
|
||||||
|
**继承的方向是向下传递的**,父级元素的某些属性值可能被子节点继承,但是子元素的属性值,不可能被父元素继承。 |
||||||
|
|
||||||
|
看下面的demo: |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="005 Box Model_1" src="https://codepen.io/AhCola/embed/YzVaRWZ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/YzVaRWZ"> |
||||||
|
005 Box Model_1</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
父元素(div类名为parent)设置颜色为绿色,因为继承流的方向是向下的,所以第一个段落文字颜色继承父元素的color属性值显示为绿色,第二个段落设置了颜色为红色,覆盖了继承得到的绿色,所以显示为红色。第二个div中,设置了子元素段落的颜色为红色,但因为继承流方向不是向上的,所以div中的文字仍然显示为黑色。 |
||||||
|
|
||||||
|
## 二. 哪些属性可以继承? |
||||||
|
|
||||||
|
并不是所有属性都具有继承属性,但是仍然有很多属性是具有继承属性的。我从 |
||||||
|
*W3 CSS reference*上摘抄了一部分属性: |
||||||
|
|
||||||
|
- [azimuth](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/azimuth) |
||||||
|
- [border-collapse](https://developer.mozilla.org/en-US/docs/Web/CSS/border-collapse) |
||||||
|
- [border-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/border-spacing) |
||||||
|
- [caption-side](https://developer.mozilla.org/en-US/docs/Web/CSS/caption-sid) |
||||||
|
- [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) |
||||||
|
- [cursor](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor) |
||||||
|
- [direction](https://developer.mozilla.org/en-US/docs/Web/CSS/direction) |
||||||
|
- [empty-cells](https://developer.mozilla.org/en-US/docs/Web/CSS/empty-cells) |
||||||
|
- [font-family](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family) |
||||||
|
- [font-size](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size) |
||||||
|
- [font-style](https://developer.mozilla.org/en-US/docs/Web/CSS/font-style) |
||||||
|
- [font-variant](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant) |
||||||
|
- [font-weight](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight) |
||||||
|
- [font](https://developer.mozilla.org/en-US/docs/Web/CSS/font) |
||||||
|
- [letter-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/letter-spacing) |
||||||
|
- [line-height](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height) |
||||||
|
- [list-style-image](https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-image) |
||||||
|
- [list-style-position](https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-position) |
||||||
|
- [list-style-type](https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-type) |
||||||
|
- [list-style](https://developer.mozilla.org/en-US/docs/Web/CSS/list-style) |
||||||
|
- [orphans](https://developer.mozilla.org/en-US/docs/Web/CSS/orphans) |
||||||
|
- [quotes](https://developer.mozilla.org/en-US/docs/Web/CSS/quotes) |
||||||
|
- [text-align](https://developer.mozilla.org/en-US/docs/Web/CSS/text-align) |
||||||
|
- [text-indent](https://developer.mozilla.org/en-US/docs/Web/CSS/text-indent) |
||||||
|
- [text-transform](https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform) |
||||||
|
- [visibility](https://developer.mozilla.org/en-US/docs/Web/CSS/visibility) |
||||||
|
- [white-space](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) |
||||||
|
- [widows](https://developer.mozilla.org/en-US/docs/Web/CSS/widows) |
||||||
|
- [word-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/word-spacing) |
||||||
|
|
||||||
|
## 三. 继承是如何工作的? |
||||||
|
|
||||||
|
html页面中每个css属性都有一个预定义的默认值。如果级联算法计算属性值失败时,会使用这个默认的值作为最终的css属性值。 |
||||||
|
|
||||||
|
其中有一些属性是可以继承的,例如上面列举的那些属性。如果有一个元素有父元素,并且父元素定义了某个可继承css属性的值,那么这个元素的对应的属性值将会从其父节点元素继承,如果该元素自己也定义了该css属性的值,那个这个值会覆盖从父节点继承的属性值。我们可以在谷歌浏览器中,按F12打开开发者工具在样式面板中,从computed页面看到各个属性的计算详情。 |
||||||
|
|
||||||
|
![css继承](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/94.jpg) |
||||||
|
|
||||||
|
## 四. 显示控制继承 |
||||||
|
|
||||||
|
某些时候继承并不是我们想要的结果,该怎么办呢?css提供了方式处理这个问题。 |
||||||
|
|
||||||
|
### inherit关键字 |
||||||
|
|
||||||
|
可以使用`inherit`关键字显示指定一个属性值从其父元素继承。这在某些情况很有用。 |
||||||
|
``` |
||||||
|
strong { |
||||||
|
font-weight: 900; |
||||||
|
} |
||||||
|
|
||||||
|
.my-component { |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
|
||||||
|
.my-component strong { |
||||||
|
font-weight: inherit; |
||||||
|
} |
||||||
|
``` |
||||||
|
上例中,我们设置`<strong>`元素的`font-weight`为900,此时有一个类名为`.my-component`的元素,设置其`font-weight`为500,该元素内部有一个`<strong>`子元素,因为`<strong>`的`font-weight`为900,但是希望`.my-component`内部的`<strong>`元素`font-weight`为500,此时可以将该属性设置为inherit,用于覆盖之前设置的值。 |
||||||
|
|
||||||
|
### initial关键字 |
||||||
|
|
||||||
|
继承可能造成意外的结果,但是`initial`关键字可以将属性重置为初始默认值。 |
||||||
|
|
||||||
|
在之前我说到过,css属性都有一个默认值。`initial`关键字的作用,正是将这个属性重置为默认值。 |
||||||
|
```css |
||||||
|
aside strong { |
||||||
|
font-weight: initial; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
再看一个demo: |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="005 Box Model_2" src="https://codepen.io/AhCola/embed/ZEKxVzQ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/ZEKxVzQ"> |
||||||
|
005 Box Model_2</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
因为段落设置了`color: initial`,所以段落颜色重置为黑色。 |
||||||
|
|
||||||
|
### unset关键字 |
||||||
|
|
||||||
|
`unset`关键字的表现有点特殊,当css属性是可以继承的,那么`unset`关键字和`inherit`关键字作用相同;当css属性是不可以继承的,那么`unset`关键字的作用和`initial`作用相同。 |
||||||
|
|
||||||
|
|
||||||
|
你并不需要立刻记住哪些属性是可以继承的,哪些是不可以被继承的,太多了,不可能全部记住的。你只需要知道有继承属性的存在,剩下的就交给时间,慢慢熟悉即可。 |
||||||
|
|
||||||
|
## 附:参考资料 |
||||||
|
|
||||||
|
- 谷歌learn css: [Inheritance](https://web.dev/learn/css/inheritance/) |
||||||
|
- MDN:[Inheritance](https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(完)。 |
@ -0,0 +1,97 @@ |
|||||||
|
# 颜色 |
||||||
|
|
||||||
|
*在css中颜色的值可以有多种格式设置。本节内容讲述一些最常用的方式。* |
||||||
|
|
||||||
|
## 一. 数值类型的颜色 |
||||||
|
|
||||||
|
用数值表示颜色,也有几种不同的方式。 |
||||||
|
|
||||||
|
### 十六进制 |
||||||
|
|
||||||
|
```css |
||||||
|
h1 { |
||||||
|
color: #b71540; |
||||||
|
} |
||||||
|
``` |
||||||
|
十六进制数值表示法是RGB的一种简写方式,六个数字中每两个数字为R、G、B赋予一个0-255区间的值。 |
||||||
|
|
||||||
|
> 据统计,十六进制是最受欢迎的颜色表示格式。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="006 Box Model_1" src="https://codepen.io/AhCola/embed/jOmxwaQ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/jOmxwaQ"> |
||||||
|
006 Box Model_1</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
你还可以指定颜色的透明度(alpha)。只需要在十六进制后面再增加两位变为8位即可。例如`#11223344`其中R=11、G=22、B=33、A=44。alpha值越接近255,颜色的透明度越低,0表示完全透明,255(即十六进制的FF)表示完全不透明。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="" src="https://codepen.io/AhCola/embed/PomejRQ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/PomejRQ"> |
||||||
|
</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
十六进制数值可以简写,当RGBA的各自的两位数都相同时,可以用一位数值代替。例如`#11223344`可以简写为`#1234`,`#AABBCCDD`可以简写为`#ABCD`,`#AABBCC`可以简写为`#ABC`。 |
||||||
|
|
||||||
|
### RGB(Red, Green, Blue) |
||||||
|
|
||||||
|
```css |
||||||
|
h1 { |
||||||
|
color: rgb(183, 21, 64); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
这种方式使用函数`rgb()`定义,参数值可以使用数值(0-255)或者百分比(0%-100%)表示,0%等于0,100%等于255。 |
||||||
|
|
||||||
|
将颜色设置为黑色,可以这样定义`rgb(0, 0, 0)`,也可以使用百分比形式`rgb(0%, 0%, 0%)`。 |
||||||
|
|
||||||
|
这种形式也支持设置透明度。可以在红色值后面添加`/`,或者使用`rgba()`函数设置透明度,建议大家使用`rgba()`函数设置,因为这种方式比较明显,也是最常用的方式: |
||||||
|
```css |
||||||
|
color: rgb(0 0 0 / 0.5); // 透明度为50% |
||||||
|
|
||||||
|
color: rgba(0, 0, 0, 0.5); // 使用rgba()设置透明度为50% |
||||||
|
``` |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="" src="https://codepen.io/AhCola/embed/LYymLXx?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/LYymLXx"> |
||||||
|
</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
> 注意:rgb()函数中参数间的逗号,也可以用空格代替,这是为了与一些新的颜色函数统一。像lab()和lch()等函数都是使用空格代替逗号作为参数分割符号的。 |
||||||
|
|
||||||
|
### HSL(Hue, Saturation, Lightness) |
||||||
|
|
||||||
|
```css |
||||||
|
h1 { |
||||||
|
color: hsl(344, 79%, 40%); |
||||||
|
} |
||||||
|
``` |
||||||
|
HSL表示色彩、饱和度、亮度。Hue描述了色轮上的颜色值,从0度到360度,0度表示红色(360度也是红色),180度或者50%表示蓝色。 |
||||||
|
|
||||||
|
![css color](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/95.jpg) |
||||||
|
|
||||||
|
Saturation表示所选颜色的亮度。饱和度为0%,将显示为灰色。lightness表述的是光照强度,你可以想像一个红色的物体在不同光照强度下表现的颜色,当lightness为100%,最终显示为白色,当lightness为0%,最终显示为黑色。注意Saturation和lightness参数必须传百分比数值。这个lightness其实就是图形学中的[颜色反射定律](https://pengfeixc.com/blogs/computer-graphics/color-and-feng-illumination-model)。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="" src="https://codepen.io/AhCola/embed/mdmLMeK?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/mdmLMeK"> |
||||||
|
</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### 颜色关键字 |
||||||
|
|
||||||
|
总共有[148个命名的颜色](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#color_keywords)。它们都是普通的英文单词,例如purple、tomato。比较常用的有black、white、red、blue、gray和transparent。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="006 Box Model_5" src="https://codepen.io/AhCola/embed/PomeKbX?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/PomeKbX"> |
||||||
|
006 Box Model_5</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
## 二. 何处使用 |
||||||
|
|
||||||
|
如果一个css属性接受`<color>`数据类型作为值,那么上面讲述的所有方式都可以用来设置这个css属性的值。例如可以用`color`、`text-shadow`和`text-decoration-color`描述文字的颜色样式,这些属性都接受`<color>`类型的数值。设置背景色,可以通过`background`或者`background-color`属性设置颜色。另外还有`border-color`和`outline-color`等等都接受颜色数值类型。 |
||||||
|
|
||||||
|
|
||||||
|
(完)。 |
@ -0,0 +1,164 @@ |
|||||||
|
# 尺寸单位 |
||||||
|
|
||||||
|
*本节内容,将讲述如何使用css调整元素的大小,提高页面的美观性。* |
||||||
|
|
||||||
|
|
||||||
|
## 一. 数字(Numbers) |
||||||
|
|
||||||
|
数字可以用来定义`opacity`、`line-height`,还可以用于定义rgb颜色中的大小。这里指的数字是无单位的。例如(1, 2, 3, 100)和小数(.1, .2, .3)。 |
||||||
|
|
||||||
|
数字所处的上下文不同,它的意义也不一样。例如当定义`line-height`时,一个无单位的数字表示的是一个比例值: |
||||||
|
```css |
||||||
|
p { |
||||||
|
font-size: 24px; |
||||||
|
line-height: 1.5; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="007 Box Model_1" src="https://codepen.io/AhCola/embed/jOmxoYw?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/jOmxoYw"> |
||||||
|
007 Box Model_1</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
这个例子中,`line-height`为1.5,但是最终行高结果为24px的1.5倍大小,即36px。 |
||||||
|
|
||||||
|
> 为`line-height`提供一个无单位的数字值(即字体大小的倍数)是一个不错的选择。正如之前在继承中说过,`font-size`是可继承属性。定义无单位的`line-height`,保证行高永远是相对于`font-size`的。如果你定义`line-height: 15px`, 在某些字体大小的情况下,最终页面可能会看起来比较奇怪。 |
||||||
|
|
||||||
|
数字还可以使用在以下几种情形: |
||||||
|
|
||||||
|
- filte: `filter: speia(0.5)`, 给元素添加一个50%的褐色滤镜。 |
||||||
|
- opacity: `opacity: 0.5`, 50%不透明度。 |
||||||
|
- color: `rgb(50, 50, 50)`, 分别设置r、g、b的颜色值,允许范围为0-255。 |
||||||
|
- transform: `transform: scale(1.2)`, 将元素放大1.2倍。 |
||||||
|
|
||||||
|
## 二. 百分比(Percentages) |
||||||
|
|
||||||
|
当使用百分比设置css属性值时,你需要知道百分比是如何用于计算的。例如`width`的百分比是相对于父元素的宽度进行计算的。 |
||||||
|
```css |
||||||
|
div { |
||||||
|
width: 300px; |
||||||
|
height: 100px; |
||||||
|
} |
||||||
|
div p { |
||||||
|
width: 50%; // 最终结果为150px |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="007 Box Model_2" src="https://codepen.io/AhCola/embed/yLbjWEp?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/yLbjWEp"> |
||||||
|
007 Box Model_2</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
上面的例子中`div p`的宽度为150px。 |
||||||
|
|
||||||
|
如果设置`margin`和`padding`百分比值,不论`margin`和`padding`的方向如何,它们的百分比都是相对于父元素的`width`的。 |
||||||
|
```css |
||||||
|
div { |
||||||
|
width: 300px; |
||||||
|
height: 100px; |
||||||
|
} |
||||||
|
|
||||||
|
div p { |
||||||
|
margin-top: 50%; /* calculated: 150px */ |
||||||
|
padding-left: 50%; /* calculated: 150px */ |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## 三. 尺寸和长度单位 |
||||||
|
|
||||||
|
如果在数字后面添加一个单位,那么它就变成了**尺寸**,例如`1rem`。 |
||||||
|
|
||||||
|
### 绝对长度 |
||||||
|
|
||||||
|
所有绝对长度都基于相同的基础进行解析,使它们在CSS中使用的任何地方都是可预测的。例如使用`cm`单位设置一个元素的`width`,那么这个元素将呈现4cm的宽度,这个值是一个精确值,可以用尺子去测量的。 |
||||||
|
|
||||||
|
```css |
||||||
|
div { |
||||||
|
width: 10cm; |
||||||
|
height: 5cm; |
||||||
|
background: black; |
||||||
|
} |
||||||
|
``` |
||||||
|
绝对长度非常适合设计用于打印的页面。 |
||||||
|
|
||||||
|
绝对长度尺寸表: |
||||||
|
|
||||||
|
| 单位 | 名称 | 公式 | |
||||||
|
| ---- | ------------------- | ------------------- | |
||||||
|
| cm | Centimeters | 1cm = 96px/2.54 | |
||||||
|
| mm | Millimeters | 1mm = 1/10th of 1cm | |
||||||
|
| Q | Quarter-millimeters | 1Q = 1/40th of 1cm | |
||||||
|
| in | Inches | 1in = 2.54cm = 96px | |
||||||
|
| pc | Picas | 1pc = 1/6th of 1in | |
||||||
|
| pt | Points | 1pt = 1/72th of 1in | |
||||||
|
| px | Pixels | 1px = 1/96th of 1in | |
||||||
|
|
||||||
|
|
||||||
|
### 相对长度 |
||||||
|
|
||||||
|
相对长度是基于基础值进行计算的,与百分比有点类似。和百分比之间的区别在于,您可以根据上下文来确定元素的大小。如果尺寸单位为`ch`,表示使用文字大小作为计算的基础值,单位`vw`表示使用viewport的宽度作为计算的基础值。相对值在响应式布局中很有用。 |
||||||
|
|
||||||
|
#### 字体大小相对单位 |
||||||
|
|
||||||
|
css提供了一些相对于元素字体大小的相对单位。 |
||||||
|
|
||||||
|
| 单位 | 相对于 | |
||||||
|
| ---- | ------------------------------------------------------------ | |
||||||
|
| em | 在 font-size 中使用是相对于父元素的字体大小,在其他属性中使用是相对于自身的字体大小,如 width | |
||||||
|
| ex | 字符“x”的高度 | |
||||||
|
| ch | 数字“0”的宽度 | |
||||||
|
| rem | 根元素的字体大小 | |
||||||
|
| lh | 元素的line-height | |
||||||
|
| cap | 当前元素字体的首字母大小 | |
||||||
|
| ic | "水"字形 | |
||||||
|
| rlh | 根节点行高 | |
||||||
|
|
||||||
|
![css尺寸单位](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/96.jpg) |
||||||
|
|
||||||
|
#### 视口相对单位 |
||||||
|
|
||||||
|
你可以使用视口的大小作为相对值计算的基。 |
||||||
|
|
||||||
|
| 单位 | 相对于 | |
||||||
|
| ---- | ------------------------------------------------------------ | |
||||||
|
| vw | 视口宽度的1% | |
||||||
|
| vh | 视口高度的1% | |
||||||
|
| vi | 等于初始[包含块](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Containing_block)大小的 1%,在根元素的[行内轴](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Logical_Properties#inline-dimension)方向上。 | |
||||||
|
| vb | 等于初始[包含块](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Containing_block)大小的 1%,在根元素的[区块轴](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Logical_Properties#block-dimension)方向上。 | |
||||||
|
| vmin | 视口高度 `vw` 和宽度 `vh` 两者之间的最小值。 | |
||||||
|
| vmax | 视口高度 `vw` 和宽度 `vh` 两者之间的最大值。 | |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 四. 其他单位 |
||||||
|
|
||||||
|
还有一些其他的单位已经被指定来处理特定类型的值。 |
||||||
|
|
||||||
|
### 角度单位 |
||||||
|
|
||||||
|
```css |
||||||
|
div { |
||||||
|
width: 150px; |
||||||
|
height: 150px; |
||||||
|
transform: rotate(60deg); // deg单位,旋转60度 |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="007 Box Model_3" src="https://codepen.io/AhCola/embed/ZEKRqvX?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/ZEKRqvX"> |
||||||
|
007 Box Model_3</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### 分辨率单位 |
||||||
|
|
||||||
|
`dpi`表示每英寸的点数。 |
||||||
|
|
||||||
|
## 附:参考资料 |
||||||
|
|
||||||
|
- 谷歌learn css: [Sizing Units](https://web.dev/learn/css/sizing/#relative-lengths) |
||||||
|
|
||||||
|
- MDN web文档:[length](https://developer.mozilla.org/zh-CN/docs/Web/CSS/length) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,202 @@ |
|||||||
|
# 布局 |
||||||
|
|
||||||
|
*当你构建一个组件或者页面时,有多种布局方式可供选择,本节内容是各种布局的一个概览。* |
||||||
|
|
||||||
|
假设你是一个开发者,此时一个设计专业的同事递给你一份新的网站设计稿让你开发。这份设计稿有很多有趣的布局和组件,有二维布局,也有非常灵活可流动的布局。你怎么去选择最好的css布局方式呢? |
||||||
|
|
||||||
|
CSS为我们提供了多种布局方式,有水平轴布局,垂直轴布局或者水平和竖直混合布局。选择一个正确的布局方式往往很困难,通常你需要多个布局方式去解决问题。为了解决这些,在接下来的几个模块,你将会学习css的布局机制。 |
||||||
|
|
||||||
|
## 二.display属性 |
||||||
|
|
||||||
|
`display`属性做了两件事。第一件事是他决定一个盒子是否表现为**inline**或者**block**。 |
||||||
|
|
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
display: inline |
||||||
|
} |
||||||
|
``` |
||||||
|
inline元素被称为行内元素,行内元素就像一段语句中的一个单词。它们在行内方向上紧挨着彼此。像`<span>`和`<strong>`元素就是典型的行内元素,它们在`<p>`(段落,`<p>`是一个block元素,后面将会介绍block元素)中都是紧挨着彼此的。它们同样拥有周围的空间,即`padding`、`border`和`margin`属性都是有效的。 |
||||||
|
|
||||||
|
![css布局](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/120.jpg) |
||||||
|
|
||||||
|
你无法设置行内元素的`width`和`height`属性。block层级的margin和padding将会被周围的元素忽略(这句话的英文原文是*Any block level margin and padding will be ignored by the surrounding elements*,我不清楚这样翻译是否合适)。 |
||||||
|
|
||||||
|
block元素,即块元素,它们并不是紧挨着其他元素的。它们在页面中会自动生成新的一行。块元素在行内方向上会扩展尺寸,因此它们会占据水平方向100%宽度。块元素任意方向的边距将不会被忽略。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
``` |
||||||
|
`display`属性还可以决定元素的子元素的行为。例如设置`display: flex`,使元素盒子成为一个block层级的盒子(块元素),并且将子元素变成flex项目(item)。这会启用flex属性,flex属性可以用来控制子元素的布局方式(对其、排序、流动)。 |
||||||
|
|
||||||
|
## 二.flex和Grid |
||||||
|
|
||||||
|
flex(弹性布局)和grid(格子布局)是为多个元素创建布局规则的两种主要布局机制。它们有很多共同点,但是却是被设计出来去解决不同的布局问题的。 |
||||||
|
|
||||||
|
> 在后面的章节内容,我将会更详细的介绍弹性布局和格子布局的内容。但是目前我们仅大致看下这两种布局方式,了解它们的功能。 |
||||||
|
|
||||||
|
首先明确两个概念: |
||||||
|
- flex/grid盒子(简称盒子):`display`属性设置为`flex`或者`grid`的元素被称为盒子。 |
||||||
|
- flex/grid项目(简称项目):flex/grid盒子元素的直接子元素,不包含孙子元素。 |
||||||
|
|
||||||
|
### 弹性布局 |
||||||
|
|
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
display: flex; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
|
||||||
|
弹性布局主要用于一维布局。布局方向是单轴的,可以是水平方向或者竖直方向。默认情况下,弹性布局会在内联方向上(水平方向)排列元素,flex项目会紧挨着彼此,并且会在块方向上(竖直方向)被拉伸,所以项目与盒子高度相同。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="008 Layout_1" src="https://codepen.io/AhCola/embed/jOmeoOX?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/jOmeoOX"> |
||||||
|
008 Layout_1</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
flex项目会保持同轴排列,在超过flex盒子范围时,并不会换行,而是被自动压缩宽度排列。可以通过`align-items`、 `justify-content`和`flex-wrap`改变这一默认行为。 |
||||||
|
|
||||||
|
你也可以通过`flex`属性设置flex项目如何压缩、拉伸尺寸。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
flex: 1 0 auto; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
`flex`属性是`flex-grow`、`flex-shrink`、`flex-basis`三个属性的混合写法。你可以将上面的例子改写为: |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
flex-grow: 1; |
||||||
|
flex-shrink: 0; |
||||||
|
flex-basis: auto; |
||||||
|
} |
||||||
|
``` |
||||||
|
开发人员提供这些低级规则,以提示浏览器当视口尺寸发生变化时如何布局元素。这使得弹性布局非常适合设计响应式网页。 |
||||||
|
|
||||||
|
### 格子布局 |
||||||
|
|
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
display: grid; |
||||||
|
} |
||||||
|
``` |
||||||
|
格子布局(Grid)与弹性布局(flex)非常相似,但是格子布局是为多轴布局而设计的。 |
||||||
|
|
||||||
|
格子布局引入了一些新的布局基础规则,例如`repeat()`和`minmax()`函数。还有一个`fr`单位,用来描述分配剩余空间的弹性系数。你可以创建一个12列,每列之间有一个空白间距的布局。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: repeat(12, 1fr); |
||||||
|
gap: 1rem; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="008 Layout_2" src="https://codepen.io/AhCola/embed/zYwmQor?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/zYwmQor"> |
||||||
|
008 Layout_2</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
你还可以通过格子布局设置二维布局。我们可以设置第一个grid项目占据两行三列的空间。 |
||||||
|
```css |
||||||
|
.my-element :first-child { |
||||||
|
grid-row: 1/3; |
||||||
|
grid-column: 1/4; |
||||||
|
} |
||||||
|
``` |
||||||
|
通过`grid-row`和`grid-column`属性设置盒子中第一个元素水平占据空间从第一列到第四列,竖直占据空间从第一行到第三行。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="008 Layout_3" src="https://codepen.io/AhCola/embed/MWmPdmW?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/MWmPdmW"> |
||||||
|
008 Layout_3</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### flow布局 |
||||||
|
|
||||||
|
如果不使用弹性布局和格子布局,你的元素将会显示为正常文档流。还有一些布局方式可以在正常文档流中改变元素的行为和位置。 |
||||||
|
|
||||||
|
#### inline-block |
||||||
|
|
||||||
|
前面提到过,内联元素的块方向上的边距(margin和padding)将会被周围的元素忽略。通过设置`inline-block`,可以使内联元素的块方向上的边距不会被忽略。 |
||||||
|
```css |
||||||
|
p span { |
||||||
|
display: inline-block; |
||||||
|
} |
||||||
|
``` |
||||||
|
使用`inline-block`可以让一个盒子拥有块元素的一些特性,但是仍然在处于内联文档流中,与其他元素紧挨着。 |
||||||
|
```css |
||||||
|
p span { |
||||||
|
margin-top: 0.5rem; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
#### Floats |
||||||
|
|
||||||
|
如果一个段落中有一张图片,但是你想让文字环绕在图片周围,就像杂志一样。你可以使用floats特征去完成这种效果: |
||||||
|
```css |
||||||
|
img { |
||||||
|
float: left; |
||||||
|
margin-right: 1em; |
||||||
|
} |
||||||
|
``` |
||||||
|
`float`属性指示元素朝着指定方向流动。例子中的图片被指示朝着左侧流动,并且允许它的姐妹元素环绕着它。你可以设置`float`属性为`left`、`right`、`inherit`等值。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="008 Layout_4" src="https://codepen.io/AhCola/embed/PomyvEd?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/PomyvEd"> |
||||||
|
008 Layout_4</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
注意:当你使用`float`属性,你要记住所有在float元素后的元素的布局都会被调整。为了防止这种情况,你可以清除float效果,可以通过设置float元素后面的元素`clear: both`属性值,也可以通过为float元素的父元素添加`display: flow-root`属性值。 |
||||||
|
|
||||||
|
#### 多列布局 |
||||||
|
|
||||||
|
如果有一个很长的列表,你可以通过`column-count`设置列表的列数,通过`column-gap`设置列表的列间距。 |
||||||
|
```css |
||||||
|
.countries { |
||||||
|
column-count: 2; |
||||||
|
column-gap: 1em; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="008 Layout_5" src="https://codepen.io/AhCola/embed/KKmGLBK?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/KKmGLBK"> |
||||||
|
008 Layout_5</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
上面的例子,会自动将列表分成两列,并且在列之间添加一个空白间距。 |
||||||
|
|
||||||
|
也可以通过设置`column-width`,然后通过列表宽度,自动划分列数。 |
||||||
|
```css |
||||||
|
.countries { |
||||||
|
width: 100%; |
||||||
|
column-width: 260px; |
||||||
|
column-gap: 1em; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="008 Layout_6" src="https://codepen.io/AhCola/embed/QWvZRBe?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/QWvZRBe"> |
||||||
|
008 Layout_6</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
#### position |
||||||
|
|
||||||
|
`position`属性会改变元素在正常文档流中的表现和它与其他元素之间的关系。可用的属性值由`static`、`relative`、`absolute`、`fixed`和`sticky`。默认值为`static`。 |
||||||
|
|
||||||
|
- static:该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 top, right, bottom, left 和 z-index 属性无效。 |
||||||
|
|
||||||
|
- relative: 该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。position:relative对table-row, table-column, table-cell, table-caption 元素无效。 |
||||||
|
|
||||||
|
- absolute:元素会被移出正常文档流,并不为元素预留空间,通过指定元素相对于最近的非 static定位祖先元素的偏移,来确定元素位置。绝对定位的元素可以设置外边距(margins),且不会与其他边距合并。 |
||||||
|
|
||||||
|
- fixed:元素会被移出正常文档流,并不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。打印时,元素会出现在的每页的固定位置。fixed属性会创建新的层叠上下文。当元素祖先的transform,perspective或filter属性非 none 时,容器由视口改为该祖先。 |
||||||
|
|
||||||
|
- sticky:元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor)和containing block(最近块级祖先nearest block-level ancestor),包括table-related元素,基于top、right、bottom和left的值进行偏移。偏移值不会影响任何其他元素的位置。 |
||||||
|
|
||||||
|
可以在[这里](https://developer.mozilla.org/zh-CN/docs/Web/CSS/position)获得更详细的内容。 |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,247 @@ |
|||||||
|
# Flex 布局教程:语法篇 |
||||||
|
|
||||||
|
*本文转自阮一峰老师的flex教程文章*。 |
||||||
|
|
||||||
|
作者:[阮一峰](http://www.ruanyifeng.com/home.html) |
||||||
|
|
||||||
|
日期:[2015年7月10日](https://www.ruanyifeng.com/blog/2015/07/) |
||||||
|
|
||||||
|
网页布局(layout)是 CSS 的一个重点应用。 |
||||||
|
|
||||||
|
![CSS Layout](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071001.gif) |
||||||
|
|
||||||
|
布局的传统解决方案,基于[盒状模型](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model),依赖 [display](https://developer.mozilla.org/en-US/docs/Web/CSS/display) 属性 + [position](https://developer.mozilla.org/en-US/docs/Web/CSS/position)属性 + [float](https://developer.mozilla.org/en-US/docs/Web/CSS/float)属性。它对于那些特殊布局非常不方便,比如,[垂直居中](https://css-tricks.com/centering-css-complete-guide/)就不容易实现。 |
||||||
|
|
||||||
|
![CSS Flexbox](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071002.png) |
||||||
|
|
||||||
|
2009年,W3C 提出了一种新的方案----Flex 布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。 |
||||||
|
|
||||||
|
![flexbox browser support](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071003.jpg) |
||||||
|
|
||||||
|
Flex 布局将成为未来布局的首选方案。本文介绍它的语法,下一篇文章给出常见布局的 Flex 写法。网友 [JailBreak](http://vgee.cn/) 为本文的所有示例制作了 [Demo](http://static.vgee.cn/static/index.html),也可以参考。 |
||||||
|
|
||||||
|
以下内容主要参考了下面两篇文章:[A Complete Guide to Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) 和 [A Visual Guide to CSS3 Flexbox Properties](https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties)。 |
||||||
|
|
||||||
|
## 一.Flex 布局是什么? |
||||||
|
|
||||||
|
Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。 |
||||||
|
|
||||||
|
任何一个容器都可以指定为 Flex 布局。 |
||||||
|
```css |
||||||
|
.box{ |
||||||
|
display: flex; |
||||||
|
} |
||||||
|
``` |
||||||
|
行内元素也可以使用 Flex 布局。 |
||||||
|
```css |
||||||
|
.box{ |
||||||
|
display: inline-flex; |
||||||
|
} |
||||||
|
``` |
||||||
|
Webkit 内核的浏览器,必须加上-webkit前缀。 |
||||||
|
|
||||||
|
> ps: 现在主流的浏览器,都已经支持了flex值,所以一般不需要添加-webkit前缀,可以在[caniuse](https://caniuse.com/?search=display%3A%20flex)查看该属性值各浏览器的支持。 |
||||||
|
```css |
||||||
|
.box{ |
||||||
|
display: -webkit-flex; /* Safari */ |
||||||
|
display: flex; |
||||||
|
} |
||||||
|
``` |
||||||
|
注意,设为 Flex 布局以后,子元素的`float`、`clear`和`vertical-align`属性将失效。 |
||||||
|
|
||||||
|
## 二.基本概念 |
||||||
|
|
||||||
|
采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。 |
||||||
|
|
||||||
|
![Flexbox](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071004.png) |
||||||
|
|
||||||
|
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做`main start`,结束位置叫做`main end`;交叉轴的开始位置叫做`cross start`,结束位置叫做`cross end`。 |
||||||
|
|
||||||
|
项目默认沿主轴排列。单个项目占据的主轴空间叫做`main size`,占据的交叉轴空间叫做`cross size`。 |
||||||
|
|
||||||
|
## 三.容器的属性 |
||||||
|
|
||||||
|
以下6个属性设置在容器上。 |
||||||
|
- flex-direction |
||||||
|
- flex-wrap |
||||||
|
- flex-flow |
||||||
|
- justify-content |
||||||
|
- align-items |
||||||
|
- align-content |
||||||
|
|
||||||
|
### flex-direction属性 |
||||||
|
|
||||||
|
`flex-direction`属性决定主轴的方向(即项目的排列方向)。 |
||||||
|
```css |
||||||
|
.box { |
||||||
|
flex-direction: row | row-reverse | column | column-reverse; |
||||||
|
} |
||||||
|
``` |
||||||
|
![flex-direction](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071005.png) |
||||||
|
|
||||||
|
它可能有4个值。 |
||||||
|
- row(默认值):主轴为水平方向,起点在左端。 |
||||||
|
- row-reverse:主轴为水平方向,起点在右端。 |
||||||
|
- column:主轴为垂直方向,起点在上沿。 |
||||||
|
- column-reverse:主轴为垂直方向,起点在下沿。 |
||||||
|
|
||||||
|
### flex-wrap属性 |
||||||
|
|
||||||
|
默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。 |
||||||
|
|
||||||
|
![flex-wrap](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071006.png) |
||||||
|
|
||||||
|
```css |
||||||
|
.box{ |
||||||
|
flex-wrap: nowrap | wrap | wrap-reverse; |
||||||
|
} |
||||||
|
``` |
||||||
|
它可能取三个值。 |
||||||
|
|
||||||
|
(1)`nowrap`(默认):不换行。 |
||||||
|
![nowrap](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071007.png) |
||||||
|
|
||||||
|
(2)`wrap`:换行,第一行在上方。 |
||||||
|
![wrap](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071008.jpg) |
||||||
|
|
||||||
|
(3)`wrap-reverse`:换行,第一行在下方。 |
||||||
|
![wrap-reverse](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071009.jpg) |
||||||
|
|
||||||
|
### flex-flow |
||||||
|
|
||||||
|
`flex-flow`属性是`flex-direction`属性和`flex-wrap`属性的简写形式,默认值为`row nowrap`。 |
||||||
|
```css |
||||||
|
.box { |
||||||
|
flex-flow: <flex-direction> || <flex-wrap>; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### justify-content属性 |
||||||
|
|
||||||
|
`justify-content`属性定义了项目在主轴上的对齐方式。 |
||||||
|
```css |
||||||
|
.box { |
||||||
|
justify-content: flex-start | flex-end | center | space-between | space-around; |
||||||
|
} |
||||||
|
``` |
||||||
|
![justify-content](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071010.png) |
||||||
|
|
||||||
|
它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。 |
||||||
|
- flex-start(默认值):左对齐 |
||||||
|
- flex-end:右对齐 |
||||||
|
- center:居中 |
||||||
|
- space-between:两端对齐,项目之间的间隔都相等。 |
||||||
|
- space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。 |
||||||
|
|
||||||
|
### align-items属性 |
||||||
|
|
||||||
|
`align-items`属性定义项目在交叉轴上如何对齐。 |
||||||
|
```css |
||||||
|
.box { |
||||||
|
align-items: flex-start | flex-end | center | baseline | stretch; |
||||||
|
} |
||||||
|
``` |
||||||
|
![align-items](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071011.png) |
||||||
|
|
||||||
|
### align-content属性 |
||||||
|
|
||||||
|
`align-content`属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。 |
||||||
|
```css |
||||||
|
.box { |
||||||
|
align-content: flex-start | flex-end | center | space-between | space-around | stretch; |
||||||
|
} |
||||||
|
``` |
||||||
|
![align-content](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071012.png) |
||||||
|
|
||||||
|
该属性可能取6个值。 |
||||||
|
- flex-start:与交叉轴的起点对齐。 |
||||||
|
- flex-end:与交叉轴的终点对齐。 |
||||||
|
- center:与交叉轴的中点对齐。 |
||||||
|
- space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。 |
||||||
|
- space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。 |
||||||
|
- stretch(默认值):轴线占满整个交叉轴。 |
||||||
|
|
||||||
|
## 四.项目的属性 |
||||||
|
|
||||||
|
以下6个属性设置在项目上。 |
||||||
|
- order |
||||||
|
- flex-grow |
||||||
|
- flex-shrink |
||||||
|
- flex-basis |
||||||
|
- flex |
||||||
|
- align-self |
||||||
|
|
||||||
|
### order属性 |
||||||
|
|
||||||
|
`order`属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。 |
||||||
|
```css |
||||||
|
.item { |
||||||
|
order: <integer>; |
||||||
|
} |
||||||
|
``` |
||||||
|
![order属性](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071013.png) |
||||||
|
|
||||||
|
### flex-grow属性 |
||||||
|
|
||||||
|
`flex-grow`属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。 |
||||||
|
```css |
||||||
|
.item { |
||||||
|
flex-grow: <number>; /* default 0 */ |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
![flex-grow属性](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071014.png) |
||||||
|
|
||||||
|
如果所有项目的`flex-grow`属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的`flex-grow`属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。 |
||||||
|
|
||||||
|
### flex-shrink属性 |
||||||
|
|
||||||
|
`flex-shrink`属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。 |
||||||
|
```css |
||||||
|
.item { |
||||||
|
flex-shrink: <number>; /* default 1 */ |
||||||
|
} |
||||||
|
``` |
||||||
|
![flex-shrink](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071015.jpg) |
||||||
|
|
||||||
|
如果所有项目的`flex-shrink`属性都为1,当空间不足时,都将等比例缩小。如果一个项目的`flex-shrink`属性为0,其他项目都为1,则空间不足时,前者不缩小。 |
||||||
|
|
||||||
|
负值对该属性无效。 |
||||||
|
|
||||||
|
### flex-basis属性 |
||||||
|
|
||||||
|
`flex-basis`属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为`auto`,即项目的本来大小。 |
||||||
|
```css |
||||||
|
.item { |
||||||
|
flex-basis: <length> | auto; /* default auto */ |
||||||
|
} |
||||||
|
``` |
||||||
|
它可以设为跟`width`或`height`属性一样的值(比如350px),则项目将占据固定空间。 |
||||||
|
|
||||||
|
### flex属性 |
||||||
|
|
||||||
|
flex属性是`flex-grow`, `flex-shrink` 和 `flex-basis`的简写,默认值为0 1 auto。后两个属性可选。 |
||||||
|
```css |
||||||
|
.item { |
||||||
|
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
该属性有两个快捷值:`auto` (`1 1 auto`) 和 `none` (`0 0 auto`)。 |
||||||
|
|
||||||
|
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。 |
||||||
|
|
||||||
|
### align-self属性 |
||||||
|
|
||||||
|
`align-self`属性允许单个项目有与其他项目不一样的对齐方式,可覆盖`align-items`属性。默认值为`auto`,表示继承父元素的`align-items`属性,如果没有父元素,则等同于`stretch`。 |
||||||
|
```css |
||||||
|
.item { |
||||||
|
align-self: auto | flex-start | flex-end | center | baseline | stretch; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
![align-self](https://www.ruanyifeng.com/blogimg/asset/2015/bg2015071016.png) |
||||||
|
|
||||||
|
该属性可能取6个值,除了auto,其他都与align-items属性完全一致。 |
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,660 @@ |
|||||||
|
# CSS Grid 网格布局教程 |
||||||
|
|
||||||
|
*本文转自阮一峰老师的grid布局教程文章*。 |
||||||
|
|
||||||
|
作者:[阮一峰](http://www.ruanyifeng.com/home.html) |
||||||
|
|
||||||
|
日期:[2019年3月25日](https://www.ruanyifeng.com/blog/2015/07/) |
||||||
|
|
||||||
|
## 一.概述 |
||||||
|
|
||||||
|
网格布局(Grid)是最强大的 CSS 布局方案。 |
||||||
|
|
||||||
|
它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局。以前,只能通过复杂的 CSS 框架达到的效果,现在浏览器内置了。 |
||||||
|
|
||||||
|
![CSS Grid布局](https://www.wangbase.com/blogimg/asset/201903/1_bg2019032501.png) |
||||||
|
|
||||||
|
上图这样的布局,就是 Grid 布局的拿手好戏。 |
||||||
|
|
||||||
|
Grid 布局与 Flex 布局有一定的相似性,都可以指定容器内部多个项目的位置。但是,它们也存在重大区别。 |
||||||
|
|
||||||
|
Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局。Grid 布局远比 Flex 布局强大。 |
||||||
|
|
||||||
|
## 二.基本概念 |
||||||
|
|
||||||
|
学习 Grid 布局之前,需要了解一些基本概念。 |
||||||
|
|
||||||
|
### 容器和项目 |
||||||
|
|
||||||
|
采用网格布局的区域,称为"容器"(container)。容器内部采用网格定位的子元素,称为"项目"(item)。 |
||||||
|
|
||||||
|
```css |
||||||
|
<div> |
||||||
|
<div><p>1</p></div> |
||||||
|
<div><p>2</p></div> |
||||||
|
<div><p>3</p></div> |
||||||
|
</div> |
||||||
|
``` |
||||||
|
|
||||||
|
上面代码中,最外层的`<div>`元素就是容器,内层的三个`<div>`元素就是项目。 |
||||||
|
|
||||||
|
注意:项目只能是容器的顶层子元素,不包含项目的子元素,比如上面代码的`<p>`元素就不是项目。Grid 布局只对项目生效。 |
||||||
|
|
||||||
|
### 行和列 |
||||||
|
|
||||||
|
容器里面的水平区域称为"行"(row),垂直区域称为"列"(column)。 |
||||||
|
|
||||||
|
![grid布局的行和列](https://www.wangbase.com/blogimg/asset/201903/1_bg2019032502.png) |
||||||
|
|
||||||
|
上图中,水平的深色区域就是"行",垂直的深色区域就是"列"。 |
||||||
|
|
||||||
|
### 单元格 |
||||||
|
|
||||||
|
行和列的交叉区域,称为"单元格"(cell)。 |
||||||
|
|
||||||
|
正常情况下,`n`行和`m`列会产生`n x m`个单元格。比如,3行3列会产生9个单元格。 |
||||||
|
|
||||||
|
### 网格线 |
||||||
|
|
||||||
|
划分网格的线,称为"网格线"(grid line)。水平网格线划分出行,垂直网格线划分出列。 |
||||||
|
|
||||||
|
正常情况下,`n`行有`n + 1`根水平网格线,`m`列有`m + 1`根垂直网格线,比如三行就有四根水平网格线。 |
||||||
|
|
||||||
|
![css grid](https://www.wangbase.com/blogimg/asset/201903/1_bg2019032503.png) |
||||||
|
|
||||||
|
## 三.容器的属性 |
||||||
|
|
||||||
|
Grid 布局的属性分成两类。一类定义在容器上面,称为容器属性;另一类定义在项目上面,称为项目属性。这部分先介绍容器属性。 |
||||||
|
|
||||||
|
### display属性 |
||||||
|
|
||||||
|
`display: grid`指定一个容器采用网格布局。 |
||||||
|
```css |
||||||
|
div { |
||||||
|
display: grid; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
![display: grid](https://www.wangbase.com/blogimg/asset/201903/bg2019032504.png) |
||||||
|
|
||||||
|
上图是`display: grid`的[效果](https://jsbin.com/guvivum/edit?html,css,output)。 |
||||||
|
|
||||||
|
默认情况下,容器元素都是块级元素,但也可以设成行内元素。 |
||||||
|
```css |
||||||
|
div { |
||||||
|
display: inline-grid; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
上面代码指定`div`是一个行内元素,该元素内部采用网格布局。 |
||||||
|
|
||||||
|
![display: inline-grid](https://www.wangbase.com/blogimg/asset/201903/bg2019032505.png) |
||||||
|
|
||||||
|
上图是`display: inline-grid`的[效果](https://jsbin.com/qatitav/edit?html,css,output)。 |
||||||
|
|
||||||
|
> 注意,设为网格布局以后,容器子元素(项目)的`float`、`display: inline-block`、`display: table-cell`、`vertical-align`和`column-*`等设置都将失效。 |
||||||
|
|
||||||
|
### grid-template-columns 属性和 grid-template-rows 属性 |
||||||
|
|
||||||
|
容器指定了网格布局以后,接着就要划分行和列。`grid-template-columns`属性定义每一列的列宽,`grid-template-rows`属性定义每一行的行高。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: 100px 100px 100px; |
||||||
|
grid-template-rows: 100px 100px 100px; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
[上面代码](https://jsbin.com/qiginur/edit?css,output)指定了一个三行三列的网格,列宽和行高都是100px。 |
||||||
|
|
||||||
|
![grid-template-columns、grid-template-rows 属性](https://www.wangbase.com/blogimg/asset/201903/bg2019032506.png) |
||||||
|
|
||||||
|
除了使用绝对单位,也可以使用百分比。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: 33.33% 33.33% 33.33%; |
||||||
|
grid-template-rows: 33.33% 33.33% 33.33%; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
#### repeat() |
||||||
|
|
||||||
|
有时候,重复写同样的值非常麻烦,尤其网格很多时。这时,可以使用repeat()函数,简化重复的值。上面的代码用repeat()改写如下。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: repeat(3, 33.33%); |
||||||
|
grid-template-rows: repeat(3, 33.33%); |
||||||
|
} |
||||||
|
``` |
||||||
|
`repeat()`接受两个参数,第一个参数是重复的次数(上例是3),第二个参数是所要重复的值。 |
||||||
|
|
||||||
|
`repeat()`重复某种模式也是可以的。 |
||||||
|
```css |
||||||
|
grid-template-columns: repeat(2, 100px 20px 80px); |
||||||
|
``` |
||||||
|
|
||||||
|
[上面代码](https://jsbin.com/cokohu/edit?css,output)定义了6列,第一列和第四列的宽度为100px,第二列和第五列为20px,第三列和第六列为80px。 |
||||||
|
|
||||||
|
![repeat()](https://www.wangbase.com/blogimg/asset/201903/bg2019032507.png) |
||||||
|
|
||||||
|
#### auto-fill 关键字 |
||||||
|
|
||||||
|
有时,单元格的大小是固定的,但是容器的大小不确定。如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用`auto-fill`关键字表示自动填充。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: repeat(auto-fill, 100px); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
[上面代码](https://jsbin.com/himoku/edit?css,output)表示每列宽度100px,然后自动填充,直到容器不能放置更多的列。 |
||||||
|
![auto-fill](https://www.wangbase.com/blogimg/asset/201903/bg2019032508.png) |
||||||
|
|
||||||
|
#### fr 关键字 |
||||||
|
|
||||||
|
为了方便表示比例关系,网格布局提供了`fr`关键字(fraction 的缩写,意为"片段")。如果两列的宽度分别为`1fr`和`2fr`,就表示后者是前者的两倍。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: 1fr 1fr; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
[上面代码](https://jsbin.com/hadexek/edit?html,css,output)表示两个相同宽度的列。 |
||||||
|
|
||||||
|
![fr关键字](https://www.wangbase.com/blogimg/asset/201903/1_bg2019032509.png) |
||||||
|
|
||||||
|
`fr`可以与绝对长度的单位结合使用,这时会非常方便。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: 150px 1fr 2fr; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
[上面代码](https://jsbin.com/remowec/edit?html,css,output)表示,第一列的宽度为150像素,第二列的宽度是第三列的一半。 |
||||||
|
![fr关键字](https://www.wangbase.com/blogimg/asset/201903/bg2019032510.png) |
||||||
|
|
||||||
|
#### minmax() |
||||||
|
|
||||||
|
minmax()函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。 |
||||||
|
```css |
||||||
|
grid-template-columns: 1fr 1fr minmax(100px, 1fr); |
||||||
|
``` |
||||||
|
|
||||||
|
上面代码中,`minmax(100px, 1fr)`表示列宽不小于`100px`,不大于`1fr`。 |
||||||
|
|
||||||
|
#### auto 关键字 |
||||||
|
|
||||||
|
`auto`关键字表示由浏览器自己决定长度。 |
||||||
|
```css |
||||||
|
grid-template-columns: 100px auto 100px; |
||||||
|
``` |
||||||
|
|
||||||
|
上面代码中,第二列的宽度,基本上等于该列单元格的最大宽度,除非单元格内容设置了`min-width`,且这个值大于最大宽度。 |
||||||
|
|
||||||
|
#### 网格线的名称 |
||||||
|
|
||||||
|
`grid-template-columns`属性和`grid-template-rows`属性里面,还可以使用方括号,指定每一根网格线的名字,方便以后的引用。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4]; |
||||||
|
grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4]; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
上面代码指定网格布局为3行 x 3列,因此有4根垂直网格线和4根水平网格线。方括号里面依次是这八根线的名字。 |
||||||
|
|
||||||
|
网格布局允许同一根线有多个名字,比如`[fifth-line row-5]`。 |
||||||
|
|
||||||
|
#### 布局实例 |
||||||
|
|
||||||
|
`grid-template-columns`属性对于网页布局非常有用。两栏式布局只需要一行代码。 |
||||||
|
```css |
||||||
|
.wrapper { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: 70% 30%; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
上面代码将左边栏设为70%,右边栏设为30%。 |
||||||
|
|
||||||
|
传统的十二网格布局,写起来也很容易。 |
||||||
|
```css |
||||||
|
grid-template-columns: repeat(12, 1fr); |
||||||
|
``` |
||||||
|
|
||||||
|
### grid-row-gap 属性、grid-column-gap 属性和grid-gap 属性 |
||||||
|
|
||||||
|
`grid-row-gap`属性设置行与行的间隔(行间距),`grid-column-gap`属性设置列与列的间隔(列间距)。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
grid-row-gap: 20px; |
||||||
|
grid-column-gap: 20px; |
||||||
|
} |
||||||
|
``` |
||||||
|
[上面代码](https://jsbin.com/mezufab/edit?css,output)中,`grid-row-gap`用于设置行间距,`grid-column-gap`用于设置列间距。 |
||||||
|
|
||||||
|
![grid-row-gap、grid-column-gap](https://www.wangbase.com/blogimg/asset/201903/bg2019032511.png) |
||||||
|
|
||||||
|
`grid-gap`属性是`grid-column-gap`和`grid-row-gap`的合并简写形式,语法如下。 |
||||||
|
```css |
||||||
|
grid-gap: <grid-row-gap> <grid-column-gap>; |
||||||
|
``` |
||||||
|
|
||||||
|
因此,上面一段 CSS 代码等同于下面的代码。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
grid-gap: 20px 20px; |
||||||
|
} |
||||||
|
``` |
||||||
|
如果`grid-gap`省略了第二个值,浏览器认为第二个值等于第一个值。 |
||||||
|
|
||||||
|
> 根据最新标准,上面三个属性名的`grid-`前缀已经删除,`grid-column-gap`和`grid-row-gap`写成`column-gap`和`row-gap`,`grid-gap`写成`gap`。 |
||||||
|
|
||||||
|
### grid-template-areas 属性 |
||||||
|
|
||||||
|
网格布局允许指定"区域"(area),一个区域由单个或多个单元格组成。 |
||||||
|
|
||||||
|
`grid-template-areas`属性用于定义区域。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: 100px 100px 100px; |
||||||
|
grid-template-rows: 100px 100px 100px; |
||||||
|
grid-template-areas: 'a b c' |
||||||
|
'd e f' |
||||||
|
'g h i'; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
上面代码先划分出9个单元格,然后将其定名为`a`到`i`的九个区域,分别对应这九个单元格。 |
||||||
|
|
||||||
|
多个单元格合并成一个区域的写法如下。 |
||||||
|
```css |
||||||
|
grid-template-areas: 'a a a' |
||||||
|
'b b b' |
||||||
|
'c c c'; |
||||||
|
``` |
||||||
|
|
||||||
|
上面代码将9个单元格分成a、b、c三个区域。 |
||||||
|
|
||||||
|
下面是一个布局实例。 |
||||||
|
```css |
||||||
|
grid-template-areas: "header header header" |
||||||
|
"main main sidebar" |
||||||
|
"footer footer footer"; |
||||||
|
``` |
||||||
|
|
||||||
|
上面代码中,顶部是页眉区域`header`,底部是页脚区域`footer`,中间部分则为`main`和`sidebar`。 |
||||||
|
|
||||||
|
如果某些区域不需要利用,则使用"点"(`.`)表示。 |
||||||
|
```css |
||||||
|
grid-template-areas: 'a . c' |
||||||
|
'd . f' |
||||||
|
'g . i'; |
||||||
|
``` |
||||||
|
|
||||||
|
上面代码中,中间一列为点,表示没有用到该单元格,或者该单元格不属于任何区域。 |
||||||
|
|
||||||
|
> 注意,区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为`区域名-start`,终止网格线自动命名为`区域名-end`。 |
||||||
|
比如,区域名为`header`,则起始位置的水平网格线和垂直网格线叫做`header-start`,终止位置的水平网格线和垂直网格线叫做`header-end`。 |
||||||
|
|
||||||
|
### grid-auto-flow 属性 |
||||||
|
|
||||||
|
划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行,即下图数字的顺序。 |
||||||
|
|
||||||
|
![grid-auto-flow](https://www.wangbase.com/blogimg/asset/201903/bg2019032506.png) |
||||||
|
|
||||||
|
这个顺序由`grid-auto-flow`属性决定,默认值是`row`,即"先行后列"。也可以将它设成`column`,变成"先列后行"。 |
||||||
|
|
||||||
|
[上面代码](https://jsbin.com/xutokec/edit?css,output)设置了`column`以后,放置顺序就变成了下图。 |
||||||
|
|
||||||
|
![grid-auto-flow](https://www.wangbase.com/blogimg/asset/201903/bg2019032512.png) |
||||||
|
|
||||||
|
`grid-auto-flow`属性除了设置成`row`和`column`,还可以设成`row dense`和`column dense`。这两个值主要用于,某些项目指定位置以后,剩下的项目怎么自动放置。 |
||||||
|
|
||||||
|
[下面的例子](https://jsbin.com/muyigopasu/edit?css,output)让1号项目和2号项目各占据两个单元格,然后在默认的`grid-auto-flow: row`情况下,会产生下面这样的布局。 |
||||||
|
|
||||||
|
![grid-auto-flow: row](https://www.wangbase.com/blogimg/asset/201903/bg2019032513.png) |
||||||
|
|
||||||
|
上图中,1号项目后面的位置是空的,这是因为3号项目默认跟着2号项目,所以会排在2号项目后面。 |
||||||
|
|
||||||
|
现在修改设置,设为`row dense`,表示"先行后列",并且尽可能紧密填满,尽量不出现空格。 |
||||||
|
```css |
||||||
|
grid-auto-flow: row dense; |
||||||
|
``` |
||||||
|
|
||||||
|
[上面代码](https://jsbin.com/helewuy/edit?css,output)的效果如下。 |
||||||
|
|
||||||
|
![grid-auto-flow: row dense](https://www.wangbase.com/blogimg/asset/201903/bg2019032514.png) |
||||||
|
|
||||||
|
上图会先填满第一行,再填满第二行,所以3号项目就会紧跟在1号项目的后面。8号项目和9号项目就会排到第四行。 |
||||||
|
|
||||||
|
如果将设置改为`column dense`,表示"先列后行",并且尽量填满空格。 |
||||||
|
```css |
||||||
|
grid-auto-flow: column dense; |
||||||
|
``` |
||||||
|
上面代码的效果如下。 |
||||||
|
|
||||||
|
![grid-auto-flow: column dense;](https://www.wangbase.com/blogimg/asset/201903/bg2019032515.png) |
||||||
|
|
||||||
|
上图会先填满第一列,再填满第2列,所以3号项目在第一列,4号项目在第二列。8号项目和9号项目被挤到了第四列。 |
||||||
|
|
||||||
|
### justify-items 属性、align-items 属性和 place-items 属性 |
||||||
|
|
||||||
|
`justify-items`属性设置单元格内容的水平位置(左中右),`align-items`属性设置单元格内容的垂直位置(上中下)。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
justify-items: start | end | center | stretch; |
||||||
|
align-items: start | end | center | stretch; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
这两个属性的写法完全相同,都可以取下面这些值。 |
||||||
|
- start:对齐单元格的起始边缘。 |
||||||
|
- end:对齐单元格的结束边缘。 |
||||||
|
- center:单元格内部居中。 |
||||||
|
- stretch:拉伸,占满单元格的整个宽度(默认值)。 |
||||||
|
|
||||||
|
```css |
||||||
|
.container { |
||||||
|
justify-items: start; |
||||||
|
} |
||||||
|
``` |
||||||
|
[上面代码](https://jsbin.com/gijeqej/edit?css,output)表示,单元格的内容左对齐,效果如下图。 |
||||||
|
|
||||||
|
![justify-items: start;](https://www.wangbase.com/blogimg/asset/201903/bg2019032516.png) |
||||||
|
|
||||||
|
```css |
||||||
|
.container { |
||||||
|
align-items: start; |
||||||
|
} |
||||||
|
``` |
||||||
|
[上面代码](https://jsbin.com/tecawur/edit?css,output)表示,单元格的内容头部对齐,效果如下图。 |
||||||
|
|
||||||
|
`place-items`属性是`align-items`属性和`justify-items`属性的合并简写形式。 |
||||||
|
```css |
||||||
|
place-items: <align-items> <justify-items>; |
||||||
|
``` |
||||||
|
|
||||||
|
下面是一个例子。 |
||||||
|
```css |
||||||
|
place-items: start end; |
||||||
|
``` |
||||||
|
如果省略第二个值,则浏览器认为与第一个值相等。 |
||||||
|
|
||||||
|
### justify-content 属性、align-content 属性和place-content 属性 |
||||||
|
|
||||||
|
`justify-content`属性是整个内容区域在容器里面的水平位置(左中右),`align-content`属性是整个内容区域的垂直位置(上中下)。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
justify-content: start | end | center | stretch | space-around | space-between | space-evenly; |
||||||
|
align-content: start | end | center | stretch | space-around | space-between | space-evenly; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
这两个属性的写法完全相同,都可以取下面这些值。(下面的图都以`justify-content`属性为例,`align-content`属性的图完全一样,只是将水平方向改成垂直方向。) |
||||||
|
|
||||||
|
- start - 对齐容器的起始边框。 |
||||||
|
|
||||||
|
![start](https://www.wangbase.com/blogimg/asset/201903/bg2019032519.png) |
||||||
|
|
||||||
|
- end - 对齐容器的结束边框。 |
||||||
|
|
||||||
|
![end](https://www.wangbase.com/blogimg/asset/201903/bg2019032518.png) |
||||||
|
|
||||||
|
- center - 容器内部居中。 |
||||||
|
|
||||||
|
![center](https://www.wangbase.com/blogimg/asset/201903/bg2019032520.png) |
||||||
|
|
||||||
|
- stretch - 项目大小没有指定时,拉伸占据整个网格容器。 |
||||||
|
|
||||||
|
![stretch](https://www.wangbase.com/blogimg/asset/201903/bg2019032521.png) |
||||||
|
|
||||||
|
- space-around - 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍。 |
||||||
|
|
||||||
|
![space-around](https://www.wangbase.com/blogimg/asset/201903/bg2019032522.png) |
||||||
|
|
||||||
|
- space-between - 项目与项目的间隔相等,项目与容器边框之间没有间隔。 |
||||||
|
|
||||||
|
![space-between](https://www.wangbase.com/blogimg/asset/201903/bg2019032523.png) |
||||||
|
|
||||||
|
- space-evenly - 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。 |
||||||
|
|
||||||
|
![space-evenly](https://www.wangbase.com/blogimg/asset/201903/bg2019032524.png) |
||||||
|
|
||||||
|
`place-content`属性是`align-content`属性和`justify-content`属性的合并简写形式。 |
||||||
|
|
||||||
|
```css |
||||||
|
place-content: <align-content> <justify-content> |
||||||
|
``` |
||||||
|
|
||||||
|
下面是一个例子。 |
||||||
|
```css |
||||||
|
place-content: space-around space-evenly; |
||||||
|
``` |
||||||
|
|
||||||
|
如果省略第二个值,浏览器就会假定第二个值等于第一个值。 |
||||||
|
|
||||||
|
### grid-auto-columns 属性和grid-auto-rows 属性 |
||||||
|
|
||||||
|
有时候,一些项目的指定位置,在现有网格的外部。比如网格只有3列,但是某一个项目指定在第5行。这时,浏览器会自动生成多余的网格,以便放置项目。 |
||||||
|
|
||||||
|
`grid-auto-columns`属性和`grid-auto-rows`属性用来设置,浏览器自动创建的多余网格的列宽和行高。它们的写法与`grid-template-columns`和`grid-template-rows`完全相同。如果不指定这两个属性,浏览器完全根据单元格内容的大小,决定新增网格的列宽和行高。 |
||||||
|
|
||||||
|
[下面的例子](https://jsbin.com/sayuric/edit?css,output)里面,划分好的网格是3行 x 3列,但是,8号项目指定在第4行,9号项目指定在第5行。 |
||||||
|
```css |
||||||
|
.container { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: 100px 100px 100px; |
||||||
|
grid-template-rows: 100px 100px 100px; |
||||||
|
grid-auto-rows: 50px; |
||||||
|
} |
||||||
|
``` |
||||||
|
上面代码指定新增的行高统一为50px(原始的行高为100px)。 |
||||||
|
|
||||||
|
![grid-auto-rows](https://www.wangbase.com/blogimg/asset/201903/bg2019032525.png) |
||||||
|
|
||||||
|
### grid-template 属性和grid 属性 |
||||||
|
|
||||||
|
`grid-template`属性是`grid-template-columns`、`grid-template-rows`和`grid-template-areas`这三个属性的合并简写形式。 |
||||||
|
|
||||||
|
`grid`属性是`grid-template-rows`、`grid-template-columns`、`grid-template-areas`、 `grid-auto-rows`、`grid-auto-columns`、`grid-auto-flow`这六个属性的合并简写形式。 |
||||||
|
|
||||||
|
从易读易写的角度考虑,还是建议不要合并属性,所以这里就不详细介绍这两个属性了。 |
||||||
|
|
||||||
|
## 四.项目属性 |
||||||
|
|
||||||
|
下面这些属性定义在项目上面。 |
||||||
|
|
||||||
|
### grid-column-start 属性、grid-column-end 属性、grid-row-start 属性、grid-row-end 属性 |
||||||
|
|
||||||
|
项目的位置是可以指定的,具体方法就是指定项目的四个边框,分别定位在哪根网格线。 |
||||||
|
|
||||||
|
- grid-column-start属性:左边框所在的垂直网格线 |
||||||
|
- grid-column-end属性:右边框所在的垂直网格线 |
||||||
|
- grid-row-start属性:上边框所在的水平网格线 |
||||||
|
- grid-row-end属性:下边框所在的水平网格线 |
||||||
|
|
||||||
|
```css |
||||||
|
.item-1 { |
||||||
|
grid-column-start: 2; |
||||||
|
grid-column-end: 4; |
||||||
|
} |
||||||
|
``` |
||||||
|
[上面代码](https://jsbin.com/yukobuf/edit?css,output)指定,1号项目的左边框是第二根垂直网格线,右边框是第四根垂直网格线。 |
||||||
|
|
||||||
|
上图中,只指定了1号项目的左右边框,没有指定上下边框,所以会采用默认位置,即上边框是第一根水平网格线,下边框是第二根水平网格线。 |
||||||
|
|
||||||
|
除了1号项目以外,其他项目都没有指定位置,由浏览器自动布局,这时它们的位置由容器的`grid-auto-flow`属性决定,这个属性的默认值是`row`,因此会"先行后列"进行排列。读者可以把这个属性的值分别改成`column`、`row dense`和`column dense`,看看其他项目的位置发生了怎样的变化。 |
||||||
|
|
||||||
|
[下面的例子](https://jsbin.com/nagobey/edit?html,css,output)是指定四个边框位置的效果。 |
||||||
|
```css |
||||||
|
.item-1 { |
||||||
|
grid-column-start: 1; |
||||||
|
grid-column-end: 3; |
||||||
|
grid-row-start: 2; |
||||||
|
grid-row-end: 4; |
||||||
|
} |
||||||
|
``` |
||||||
|
![grid布局](https://www.wangbase.com/blogimg/asset/201903/bg2019032527.png) |
||||||
|
|
||||||
|
这四个属性的值,除了指定为第几个网格线,还可以指定为网格线的名字。 |
||||||
|
```css |
||||||
|
.item-1 { |
||||||
|
grid-column-start: header-start; |
||||||
|
grid-column-end: header-end; |
||||||
|
} |
||||||
|
``` |
||||||
|
上面代码中,左边框和右边框的位置,都指定为网格线的名字。 |
||||||
|
|
||||||
|
这四个属性的值还可以使用`span`关键字,表示"跨越",即左右边框(上下边框)之间跨越多少个网格。 |
||||||
|
```css |
||||||
|
.item-1 { |
||||||
|
grid-column-start: span 2; |
||||||
|
} |
||||||
|
``` |
||||||
|
[上面代码](https://jsbin.com/hehumay/edit?html,css,output)表示,1号项目的左边框距离右边框跨越2个网格。 |
||||||
|
|
||||||
|
![grid-column-start: span 2](https://www.wangbase.com/blogimg/asset/201903/bg2019032528.png) |
||||||
|
|
||||||
|
这与[下面的代码](https://jsbin.com/mujihib/edit?html,css,output)效果完全一样。 |
||||||
|
```css |
||||||
|
.item-1 { |
||||||
|
grid-column-end: span 2; |
||||||
|
} |
||||||
|
``` |
||||||
|
使用这四个属性,如果产生了项目的重叠,则使用`z-index`属性指定项目的重叠顺序。 |
||||||
|
|
||||||
|
### grid-column 属性、grid-row 属性 |
||||||
|
|
||||||
|
`grid-column`属性是`grid-column-start`和`grid-column-end`的合并简写形式,`grid-row`属性是`grid-row-start`属性和`grid-row-end`的合并简写形式。 |
||||||
|
```css |
||||||
|
.item { |
||||||
|
grid-column: <start-line> / <end-line>; |
||||||
|
grid-row: <start-line> / <end-line>; |
||||||
|
} |
||||||
|
``` |
||||||
|
下面是一个例子。 |
||||||
|
```css |
||||||
|
.item-1 { |
||||||
|
grid-column: 1 / 3; |
||||||
|
grid-row: 1 / 2; |
||||||
|
} |
||||||
|
/* 等同于 */ |
||||||
|
.item-1 { |
||||||
|
grid-column-start: 1; |
||||||
|
grid-column-end: 3; |
||||||
|
grid-row-start: 1; |
||||||
|
grid-row-end: 2; |
||||||
|
} |
||||||
|
``` |
||||||
|
上面代码中,项目`item-1`占据第一行,从第一根列线到第三根列线。 |
||||||
|
|
||||||
|
这两个属性之中,也可以使用`span`关键字,表示跨越多少个网格。 |
||||||
|
```css |
||||||
|
.item-1 { |
||||||
|
background: #b03532; |
||||||
|
grid-column: 1 / 3; |
||||||
|
grid-row: 1 / 3; |
||||||
|
} |
||||||
|
/* 等同于 */ |
||||||
|
.item-1 { |
||||||
|
background: #b03532; |
||||||
|
grid-column: 1 / span 2; |
||||||
|
grid-row: 1 / span 2; |
||||||
|
} |
||||||
|
``` |
||||||
|
[上面代码](https://jsbin.com/volugow/edit?html,css,output)中,项目item-1占据的区域,包括第一行 + 第二行、第一列 + 第二列。 |
||||||
|
|
||||||
|
![grid-column、grid-row](https://www.wangbase.com/blogimg/asset/201903/bg2019032529.png) |
||||||
|
|
||||||
|
斜杠以及后面的部分可以省略,默认跨越一个网格。 |
||||||
|
```css |
||||||
|
.item-1 { |
||||||
|
grid-column: 1; |
||||||
|
grid-row: 1; |
||||||
|
} |
||||||
|
``` |
||||||
|
上面代码中,项目`item-1`占据左上角第一个网格。 |
||||||
|
|
||||||
|
### grid-area 属性 |
||||||
|
|
||||||
|
`grid-area`属性指定项目放在哪一个区域。 |
||||||
|
```css |
||||||
|
.item-1 { |
||||||
|
grid-area: e; |
||||||
|
} |
||||||
|
``` |
||||||
|
[上面代码](https://jsbin.com/qokexob/edit?css,output)中,1号项目位于e区域,效果如下图。 |
||||||
|
|
||||||
|
![grid-are](https://www.wangbase.com/blogimg/asset/201903/bg2019032530.png) |
||||||
|
|
||||||
|
`grid-area`属性还可用作`grid-row-start`、`grid-column-start`、`grid-row-end`、`grid-column-end`的合并简写形式,直接指定项目的位置。 |
||||||
|
```css |
||||||
|
.item { |
||||||
|
grid-area: <row-start> / <column-start> / <row-end> / <column-end>; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
下面是一个[例子](https://jsbin.com/duyafez/edit?css,output)。 |
||||||
|
```css |
||||||
|
.item-1 { |
||||||
|
grid-area: 1 / 1 / 3 / 3; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### justify-self 属性、align-self 属性、place-self 属性 |
||||||
|
|
||||||
|
`justify-self`属性设置单元格内容的水平位置(左中右),跟`justify-items`属性的用法完全一致,但只作用于单个项目。 |
||||||
|
|
||||||
|
`align-self`属性设置单元格内容的垂直位置(上中下),跟`align-items`属性的用法完全一致,也是只作用于单个项目。 |
||||||
|
```css |
||||||
|
.item { |
||||||
|
justify-self: start | end | center | stretch; |
||||||
|
align-self: start | end | center | stretch; |
||||||
|
} |
||||||
|
``` |
||||||
|
这两个属性都可以取下面四个值。 |
||||||
|
- start:对齐单元格的起始边缘。 |
||||||
|
- end:对齐单元格的结束边缘。 |
||||||
|
- center:单元格内部居中。 |
||||||
|
- stretch:拉伸,占满单元格的整个宽度(默认值)。 |
||||||
|
|
||||||
|
下面是justify-self: start的例子。 |
||||||
|
```css |
||||||
|
.item-1 { |
||||||
|
justify-self: start; |
||||||
|
} |
||||||
|
``` |
||||||
|
![justify-self: start](https://www.wangbase.com/blogimg/asset/201903/bg2019032532.png) |
||||||
|
|
||||||
|
`place-self`属性是`align-self`属性和`justify-self`属性的合并简写形式。 |
||||||
|
```css |
||||||
|
place-self: <align-self> <justify-self>; |
||||||
|
``` |
||||||
|
|
||||||
|
下面是一个例子。 |
||||||
|
```css |
||||||
|
place-self: center center; |
||||||
|
``` |
||||||
|
如果省略第二个值,`place-self`属性会认为这两个值相等。 |
||||||
|
|
||||||
|
## 附:参考资料 |
||||||
|
- [A Complete Guide to Grid](https://css-tricks.com/snippets/css/complete-guide-grid/), by Chris House |
||||||
|
|
||||||
|
- [Understanding the CSS Grid Layout Module](https://webdesign.tutsplus.com/series/understanding-the-css-grid-layout-module--cms-1079), by Ian Yates |
||||||
|
|
||||||
|
- [How to Build an Off-Canvas Navigation With CSS Grid](https://webdesign.tutsplus.com/tutorials/how-to-build-an-off-canvas-navigation-with-css-grid--cms-28191), Ian Yates |
||||||
|
|
||||||
|
- [Introduction to the CSS Grid Layout With Examples](https://code.tutsplus.com/tutorials/introduction-to-css-grid-layout-with-examples--cms-25392), Dogacan Bilgili |
||||||
|
|
||||||
|
- [Learn CSS Grid](https://learncssgrid.com/), Jonathan Suh |
||||||
|
|
||||||
|
- [How I stopped using Bootstrap's layout thanks to CSS Grid](https://blog.theodo.com/2018/03/stop-using-bootstrap-layout-thanks-to-css-grid/), Cédric Kui |
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,130 @@ |
|||||||
|
# css逻辑属性 |
||||||
|
|
||||||
|
*本节,将讨论css中的一些逻辑属性。* |
||||||
|
|
||||||
|
## 一.块流(Block flow) |
||||||
|
|
||||||
|
**块流(Block flow)**指的是块排列的方向。例如有两个段落,块流动的方向就是从第一个块到第二个块。在英文文档中,块流动方向是从上到下。 |
||||||
|
|
||||||
|
下一个段落在上一个段落的下方。 |
||||||
|
![CSS Block FLow](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/122.jpg) |
||||||
|
|
||||||
|
## 二.内联流(Inline flow) |
||||||
|
|
||||||
|
**内联流**的方向就是一行文本的书写方向(页面渲染一行文字的方向)。在英文文档中内内联流的方向是从左至右。如果你将网页页面语言更改为*Arabic*(`<html lang="ar">`),内联流方向将变为从右至左。 |
||||||
|
![CSS Inline Flow](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/123.jpg) |
||||||
|
|
||||||
|
文本流动的方向由页面的**书写模式**决定。我们可以通过更改`writing-mode`来更改文字的流动方向。`writing-mode`可以设置以下几种值: |
||||||
|
- `horizontal-tb`:文本流的方向是水平方向的(从左至右),元素是从上往下(tb:top-bottom)堆叠。 |
||||||
|
- `vertical-rl`:文本流的方向是竖直方向的(从上至下),元素是右至左(rl:right-left)堆叠,与我们国家古代的书写方式一致,阅读方向是从右至左的。 |
||||||
|
- `vertical-lr`:文本流的方向是竖直方向的(从上至下),元素是左至右(lr:left-right)堆叠。 |
||||||
|
|
||||||
|
请看下面的例子: |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="011 Logical Properties_01" src="https://codepen.io/AhCola/embed/zYwbOWQ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/zYwbOWQ"> |
||||||
|
011 Logical Properties_01</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
`writing-mode`还支持这几个全局关键字属性值:`inherit`、`initial`和`unset`。 |
||||||
|
|
||||||
|
## 三.相对流 |
||||||
|
|
||||||
|
很多时候,我们设置元素的某一侧(上下左右)的边距、边框等都是相对于元素的物理方向的,例如`margin-top`属性设置的是元素的上侧外边距,类似`margin-top`、`padding-top`和`border-top`这种属性称之为物理属性(非逻辑属性),它们不受元素的流动方向的影响。 |
||||||
|
|
||||||
|
有一些属性值,会随着元素的流动方向(语言和文字书写方向)产生不同的效果,这种属性叫做相对流逻辑属性(后面简称逻辑属性),逻辑属性通常很少用到,所以很容易被我们所忽视。 |
||||||
|
|
||||||
|
通过设置逻辑属性,我们可以设置元素边距和边框等随着元素流的方向而变化。例如`margin-block-start`会受块流方向的影响。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="011 Logical Properties_02" src="https://codepen.io/AhCola/embed/KKmYYpO?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/KKmYYpO"> |
||||||
|
011 Logical Properties_02</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
通过`margin-block-start`属性名和上面的demo,可以猜到该属性受block流的方向影响并且设置的是block流的起始方向。类似的属性还有`margin-block-end`、 `margin-inline-start`、`margin-inline-end`、`padding-inline-start`、`padding-inline-end`、`border-block-start`和`border-block-end`等。需要注意的是这些属性目前都属于实验中的功能。 |
||||||
|
|
||||||
|
注意以上几种属性是处于实验中的属性。 |
||||||
|
> **Experimental** |
||||||
|
> |
||||||
|
> **这是一个实验中的功能** |
||||||
|
> |
||||||
|
>此功能某些浏览器尚在开发中,请参考浏览器兼容性表格以得到在不同浏览器中适合使用的前缀。由于该功能对应的标准文档可能被重新修订,所以在未来版本的浏览器中该功能的语法和行为可能随之改变。 |
||||||
|
|
||||||
|
![css float direction](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/120.jpg) |
||||||
|
|
||||||
|
## 四.尺寸 |
||||||
|
|
||||||
|
为了防止元素尺寸超出某个确定的范围,可以通过`width`和`height`给元素添加一个固定的最大值最小值尺寸用于限制元素尺寸: |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
max-width: 150px; |
||||||
|
max-height: 100px; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
同样`max-width`和`max-height`也有对应的逻辑属性: |
||||||
|
- `max-inline-size`:内联流方向上的最大尺寸。 |
||||||
|
- `max-block-size`:块流方向上的最大尺寸。 |
||||||
|
- `min-inline-size`:内联流方向上的最小尺寸。 |
||||||
|
- `min-block-size`:块流方向上的最小尺寸。 |
||||||
|
|
||||||
|
以上属性都受`writing-mode`影响,在默认值`horizontal-tb`时,`max-inline-size`和`min-inline-size`设置的是水平方向的最大值和最小值,`max-block-size`和`min-block-size`设置的是竖直方向的最大值和最小值,因为此时内联方向为水平方向,块方向是竖直方向。 |
||||||
|
|
||||||
|
## 五.start和end |
||||||
|
|
||||||
|
某些属性支持`start`和`end`作为属性值,用来代替`top`、`right`、`bottom`和`left`,`start`和`end`可以设置block-start、inline-end、block-end和inline-start方向,这样可以让属性受`writing-mode`和`direction`的影响,变成一个逻辑属性。 |
||||||
|
|
||||||
|
例如,将文字右对齐,你可以通过`text-aling`设置: |
||||||
|
```css |
||||||
|
p { |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
``` |
||||||
|
如果你的目标不是设置文字物理方向上的右对齐,而是受`wrigin-mode`的影响,那么你可以设置属性值为`start`和`end`. |
||||||
|
```css |
||||||
|
p { |
||||||
|
text-align: end; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="011 Logical Properties_03" src="https://codepen.io/AhCola/embed/YzVMMjO?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/YzVMMjO"> |
||||||
|
011 Logical Properties_03</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
demo中,我使用了`direction`属性改变了水平文本的方向。`direction`接受`ltr`、`rtl`作为值。`p2`的`text-align`为`end`,`direction`为`rtl`,所以此时`end`为左侧。 |
||||||
|
|
||||||
|
## 六.边距和边界 |
||||||
|
|
||||||
|
这部分在上面讲解过,这里单独拎出来。 |
||||||
|
|
||||||
|
主要有这些逻辑属性:`margin-block-start`、`margin-block-end`、 `margin-inline-start`、`margin-inline-end`、`padding-inline-start`、`padding-inline-end`、`border-block-start`和`border-block-end`。*block*表示受块流方向的影响,*inline*表示受内联流方向的影响,*start*表示方向的起始点,*end*表示方向的终止点。通过这些属性设置元素的外边距(margin)、边框(border)和内边距(padding)。 |
||||||
|
|
||||||
|
另外,还有`border-radius`对应的逻辑属性。例如设置一个右下角的的边框半径: |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
border: 1px solid red; |
||||||
|
border-bottom-right-radius: 5px; |
||||||
|
} |
||||||
|
``` |
||||||
|
在内联流方向从左至右,块流方向从上至下时,下面的代码是等价的: |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
border: 1px solid red; |
||||||
|
border-end-end-radius: 5px; |
||||||
|
} |
||||||
|
``` |
||||||
|
`border-end-end-radius`属性中第一个`end`受块流方向的影响,第二个`end`受内联流方向的影响。 |
||||||
|
|
||||||
|
## 七. 单位 |
||||||
|
|
||||||
|
CSS也有两个**逻辑属性单位**,`vb`和`vi`。`1vi`表示视口内联方向长度的百分之一,`1vb`表示视口块方向长度的百分之一。 |
||||||
|
|
||||||
|
注意以上`vb`和`vi`是处于实验中的属性单位。 |
||||||
|
> **Experimental** |
||||||
|
> |
||||||
|
> **这是一个实验中的功能** |
||||||
|
> |
||||||
|
>此功能某些浏览器尚在开发中,请参考浏览器兼容性表格以得到在不同浏览器中适合使用的前缀。由于该功能对应的标准文档可能被重新修订,所以在未来版本的浏览器中该功能的语法和行为可能随之改变。 |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,177 @@ |
|||||||
|
# css间距 |
||||||
|
|
||||||
|
*本节深入研究如何更好的调整元素之间的间距(margin和padding)*。 |
||||||
|
|
||||||
|
first,假设有三个box,从上往下堆叠在一起。现在你想在它们之前添加一个间距,你有几种方式处理这个问题呢? |
||||||
|
|
||||||
|
![css spacing](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/124.jpg) |
||||||
|
|
||||||
|
`margin`属性也许正好能满足你现在的要求,但是它可能会添加了额外的边距,超出了你的预期。例如,你如何调整边距正好处在这些元素的之间?可能`gap`属性更适合这种情况。调整元素的间距有很多方式,每种方式都有它们的优点和使用场景。 |
||||||
|
|
||||||
|
## 一.HTML间距 |
||||||
|
|
||||||
|
HTML本身提供了一些元素可以用来创建间距(空间)。`<br>`和`<hr>`元素可以在[block流](http://pengfeixc.com/blogs/css/css-logic-property)方向上创建一个空白间距。 |
||||||
|
|
||||||
|
`<br>`元素的作用是换行,类似于你在文本编辑器上敲了一个回车键。 |
||||||
|
|
||||||
|
`<hr>`元素的作用是创建一个水平线,并且水平线两侧都附有外边距(margin)。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="012 Spacing_01" src="https://codepen.io/AhCola/embed/zYwQzwQ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/zYwQzwQ"> |
||||||
|
012 Spacing_01</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
HTML还提供了一些HTML实体(HTML entities),它们是保留的字符串,在浏览器中渲染会被替换成指定的字符实体。例如`©`和` `,`©`会被渲染成©,` `会创建一个内联空格。 |
||||||
|
|
||||||
|
> 只有当可以增加页面的阅读性,理解性时,才使用HTML元素来创建间距。而不要为了增加间距去使用HTML元素。例如`<hr>`元素不仅仅是为了增加间距,更重要的是将页面内容分块。 |
||||||
|
|
||||||
|
## 二.外边距(margin) |
||||||
|
|
||||||
|
如果你想在元素box外侧添加一个边距,可以使用`margin`属性。`margin`属性是`margin-top`、`margin-right`、`margin-bottom`和`margin-left`的简写。 |
||||||
|
|
||||||
|
![box model](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/125.jpg) |
||||||
|
|
||||||
|
以下两种方式等价: |
||||||
|
```css |
||||||
|
// margin属性简写方式 |
||||||
|
margin: 1px 2px 3px 4px; |
||||||
|
|
||||||
|
// 另一种等价写法 |
||||||
|
margin-top: 1px; |
||||||
|
margin-right: 2px; |
||||||
|
margin-bottom: 3px; |
||||||
|
margin-left: 4px; |
||||||
|
``` |
||||||
|
|
||||||
|
`margin`属性可以接受一个值、两个值、三个值或者四个值。 |
||||||
|
- `margin: 1px;`:元素四侧外边距都是1px。 |
||||||
|
- `margin: 1px 2px;`:上下外边距为1px,左右外边距为2px。 |
||||||
|
- `margin: 1px 2px 3px;`:上外边距为1px,左右外边距为2px,下外边距为3px。 |
||||||
|
- `margin: 1px 2px 3px 4px;`:上右下左外边距分别为1px、2px、3px、4px。 |
||||||
|
|
||||||
|
`margin`可以被定义为一个指定长度、百分比或者`auto`值,例如`1em`和`20%`。使用百分比,最终的外边距是基于该元素的包含元素的`width`进行计算的。 |
||||||
|
|
||||||
|
这意味着,如果元素的包含元素的宽度为`250px`,元素的外边距为`20%`:那么该元素任意一侧的外边距等于`50px`。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="012 Spacing_02" src="https://codepen.io/AhCola/embed/VwbOWEP?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/VwbOWEP"> |
||||||
|
012 Spacing_02</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
你还可以给外边距赋予`auto`值,如果一个拥有固定大小的block元素,给它的某一侧`margin`设置为`auto`,那么这一侧的margin会尽可能的填充剩余空间。下例中,第三个item左边距设置为`auto`,它的外边距会自动将填充左侧的空间,从而与其他item分开。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="012 Spacing_03" src="https://codepen.io/AhCola/embed/ZEKNJyb?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/ZEKNJyb"> |
||||||
|
012 Spacing_03</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
还可以利用`auto`值,将block元素居中。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="012 Spacing_04" src="https://codepen.io/AhCola/embed/eYWaEEJ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/eYWaEEJ"> |
||||||
|
012 Spacing_04</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### 负外边距 |
||||||
|
|
||||||
|
`margin`还可以设置为负值。设置一个负值,可以用来减少两个元素间的间距,可以用来创建两个折叠的元素。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="012 Spacing_05" src="https://codepen.io/AhCola/embed/qBmGXpX?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/qBmGXpX"> |
||||||
|
012 Spacing_05</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### 外边距重叠(Margin collapse) |
||||||
|
|
||||||
|
外边距重叠是一个很少见的概念,但是这个现象在绘制页面工作中是非常常见的。假设有两个段落,第一个段落的`margin-bottom`为`2em`,第二个段落的`margin-top`为3em,那么你认为两个段落之间的间距是多少?`5em`吗? |
||||||
|
|
||||||
|
当然不是`5em`,因为垂直外边距会重叠,所以结果是`3em`。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="012 Spacing_06" src="https://codepen.io/AhCola/embed/abWryGW?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/abWryGW"> |
||||||
|
012 Spacing_06</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
你可以打开浏览器开发者工具,查看两个box之间的间距。 |
||||||
|
|
||||||
|
可以看到**两个相邻上下元素的垂直外边距是可以重叠的,元素的间距取得是两个元素外边距的最大值**。还需要知道,**仅垂直外边距会出现外边距重叠的现象,水平相邻元素的水平外边距不会重叠**。 |
||||||
|
|
||||||
|
如果两个元素是[弹性布局](http://pengfeixc.com/tutorial/css/flex)的项目,那么它们的外边距不会重叠。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="012 Spacing_07" src="https://codepen.io/AhCola/embed/vYmweME?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/vYmweME"> |
||||||
|
012 Spacing_07</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
第一个`<div>`的下外边距为`10px`,第二个`<div>`的上外边距为`10px`,因为它们是弹性布局盒子的项目,所以它们之间垂直外边距不会重叠,所以间距为20px。 |
||||||
|
|
||||||
|
## 三.内边距(padding) |
||||||
|
|
||||||
|
`padding`与`margin`相似,但是它是在盒子内部创建一个边距,称之为内边距。 |
||||||
|
|
||||||
|
![css padding](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/126.jpg) |
||||||
|
|
||||||
|
如果元素设置了`padding`,那么在不同`box-sizing`属性值时,元素的尺寸也不同。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="012 Spacing_07" src="https://codepen.io/AhCola/embed/PomvJMG?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/PomvJMG"> |
||||||
|
012 Spacing_07</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
上例中,两个block的`width`和`height`都设置成`100px`,并设置`padding: 10px;`,但是因为两个元素的`box-sizing`值不同,所以导致最终尺寸不一样。box-sizing在[这里](http://pengfeixc.com/tutorial/css/box-model)讲解过,它有两种取值方式:`border-box`和`content-box`。 |
||||||
|
- `border-box`:你想要设置的边框和内边距的值是包含在width内的。也就是说,如果你将一个元素的width设为100px,那么这100px会包含它的border和padding,内容区的实际宽度是width减去(border + padding)的值。大多数情况下,这使得我们更容易地设定一个元素的宽高。 |
||||||
|
- `content-box`:`box-sizing`属性的默认值,如果你设置一个元素的宽为100px,那么这个元素的内容区会有100px 宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中。 |
||||||
|
|
||||||
|
因为第二个block的`box-sizing`为`content-box`,所以最后看到的高度是加上内边距后的高度`120px`,而第一个block的`box-sizing`为`border-box`,所以高度就是设置的`height`属性高度`110px`。 |
||||||
|
|
||||||
|
与`margin`类似,`padding`属性是`padding-top`、`padding-right`、`padding-bottom`和`padding-left`属性的结合简写方式。 |
||||||
|
- `padding: 1px;`:元素四侧内边距都是1px。 |
||||||
|
- `padding: 1px 2px;`:上下内边距为1px,左右内边距为2px。 |
||||||
|
- `padding: 1px 2px 3px;`:上内边距为1px,左右内边距为2px,下内边距为3px。 |
||||||
|
- `padding: 1px 2px 3px 4px;`:上右下左内边距分别为1px、2px、3px、4px。 |
||||||
|
|
||||||
|
## 四.位置(position) |
||||||
|
|
||||||
|
在[布局](https://pengfeixc.com/tutorial/css/layout)章节中讲解过`position`属性,当你为`position`设置了非`static`值,那么你可以使用`top`、`right`、`bottom`和`left`属性设置元素的位置。 |
||||||
|
- `static`:该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 `top`, `right`, `bottom`, `left`和`z-index` 属性无效。 |
||||||
|
|
||||||
|
- `relative`: 该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。`position:relative`对`table-row`, `table-column`, `table-cell`, `table-caption`元素无效。 |
||||||
|
|
||||||
|
- `absolute`:元素会被移出正常文档流,并不为元素预留空间,通过指定元素相对于最近的非`static`定位祖先元素的偏移,来确定元素位置。绝对定位的元素可以设置外边距(margins),且不会与其他边距合并。 |
||||||
|
|
||||||
|
- `fixed`:元素会被移出正常文档流,并不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。打印时,元素会出现在的每页的固定位置。`fixed`属性会创建新的层叠上下文。当元素祖先的`transform`,`perspective`或`filter`属性非none时,容器由视口改为该祖先。 |
||||||
|
|
||||||
|
- `sticky`:元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor)和containing block(最近块级祖先nearest block-level ancestor),包括`table-related`元素,基于`top`、`right`、`bottom`和`left`的值进行偏移。偏移值不会影响任何其他元素的位置。 |
||||||
|
|
||||||
|
下面看一个`position:sticky;`的例子。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="012 Spacing_08" src="https://codepen.io/AhCola/embed/rNmgYjP?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/rNmgYjP"> |
||||||
|
012 Spacing_08</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
## 五.格子布局和弹性布局(Grid和Flex) |
||||||
|
|
||||||
|
在[Grid](http://pengfeixc.com/tutorial/css/grid)和[Flex](http://pengfeixc.com/tutorial/css/flex)中,可以使用`gap`属性,在元素中间添加一个间距。 |
||||||
|
|
||||||
|
![Grid和Flex](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/127.jpg) |
||||||
|
|
||||||
|
## 六.间距一致 |
||||||
|
|
||||||
|
无论你采用哪种方式调整元素的间距。最好的是保持整个页面同种类型布局的间距统一性。例如你将所有段落的间距都设置为20px,最好的方式是利用[css变量](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Using_CSS_custom_properties)(css自定义属性)。 |
||||||
|
```css |
||||||
|
:root { |
||||||
|
--gutter: 20px; |
||||||
|
--spacing: 1em; |
||||||
|
} |
||||||
|
|
||||||
|
h1 { |
||||||
|
margin-left: var(--gutter); |
||||||
|
margin-top: var(--spacing); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
css变量通过`--varname`(两个短横线)定义,然后在其他位置使用`var()`函数获取变量的值。上面定义了`--guuter`和`--spacing`两个变量。 |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,144 @@ |
|||||||
|
# 伪元素 |
||||||
|
|
||||||
|
*伪元素的作用是在不添加任何html代码的情况下可以拥有添加额外的元素的功能,或者是指定某个目标元素。你可以在本节学习伪元素的相关知识。* |
||||||
|
|
||||||
|
如果你的上司安排给你一个任务,将一篇文章的每个段落的首字母变大,你将如何实现这个功能呢? |
||||||
|
![css伪元素](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/128.jpg) |
||||||
|
|
||||||
|
幸运的是,css恰好提供了这个功能。你可以使用`::first-letter`实现这个需求。 |
||||||
|
```css |
||||||
|
p::first-letter { |
||||||
|
color: blue; |
||||||
|
float: left; |
||||||
|
font-size: 2.6em; |
||||||
|
font-weight: bold; |
||||||
|
line-height: 1; |
||||||
|
margin-inline-end: 0.2rem; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="013 Pseudo-elements_01" src="https://codepen.io/AhCola/embed/PomrPEm?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/PomrPEm"> |
||||||
|
013 Pseudo-elements_01</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
上面的codepen代码,使用了`::first-letter`伪元素,轻松的实现了上司的需求。CSS拥有很多伪元素,它们都是以`::`开头的格式,接下来一起看下这些伪元素。 |
||||||
|
|
||||||
|
## 一.`::before`和`::after` |
||||||
|
|
||||||
|
`::before`和`::after`这两个伪元素的功能是配合`content`属性在目标元素内部创建一个子元素,`::before`在目标元素头部创建一个元素,`::after`在目标元素尾部创建一个元素。 |
||||||
|
```css |
||||||
|
.ele::before { |
||||||
|
content: ""; |
||||||
|
} |
||||||
|
.ele::after { |
||||||
|
content: ""; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
一旦你使用`::before`和`::after`创建了伪元素,你可以给这个元素添加样式。但是记住你只能在可以拥有子元素的元素目标上使用`::before`和`::after`创建伪元素,例如`::before`和`::after`对`<img />`和`<video>`等无效。 |
||||||
|
|
||||||
|
## 二.`::first-letter` |
||||||
|
|
||||||
|
在文章最前面,我们使用`::first-letter`伪元素完成了上司给我们安排的任务。与`::before`和`::after`不同的是,`::first-letter`并不会创建一个元素,它指示了目标元素内部的首字母,通过`::first-letter`,我们可以为目标元素的首字母单独设置样式,就像我们使用`::first-letter`更改段落的首字母的`font-size`。 |
||||||
|
|
||||||
|
但是并不是所有css属性都可以设置,仅可以更改`::first-letter`指示目标的以下属性: |
||||||
|
- `color` |
||||||
|
- 背景属性,例如`background`、`background-image`和`background-color`等。 |
||||||
|
- 边框属性,例如`border`、`border-color`等。 |
||||||
|
- `float` |
||||||
|
- 字体属性,例如`font`、`font-size`和`font-weight`等。 |
||||||
|
- 文本属性,例如`text-decoration`和`word-spacing`等。 |
||||||
|
```css |
||||||
|
p::first-letter { |
||||||
|
color: goldenrod; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
``` |
||||||
|
## 三.`::first-line` |
||||||
|
|
||||||
|
顾名思义,`::first-line`指示目标的首行。例如`p::first-line`的指示目标是段落的首行。 |
||||||
|
```css |
||||||
|
p::first-line { |
||||||
|
color: red; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="013 Pseudo-elements_02" src="https://codepen.io/AhCola/embed/vYmqGGQ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/vYmqGGQ"> |
||||||
|
013 Pseudo-elements_02</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
和`::first-letter`类似,我们只可以更改部分css属性: |
||||||
|
- `color` |
||||||
|
- `background`属性 |
||||||
|
- `font`属性 |
||||||
|
- `text`属性 |
||||||
|
|
||||||
|
## 四.`::backdrop` |
||||||
|
|
||||||
|
backdrop表示背景幕布的意思。`::backdrop`指示的就是可全屏元素的背景元素,通过`::backdrop`可以设置全屏元素背景的样式。可全屏元素有`<dialog>`和`<video>`。 |
||||||
|
|
||||||
|
看一个例子,感受下`::backdrop`的作用。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="013 Pseudo-elements_03" src="https://codepen.io/AhCola/embed/QWvXNBG?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/QWvXNBG"> |
||||||
|
013 Pseudo-elements_03</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
通过`::backdrop`,将dialog弹出时的背景颜色更改为`rgba(100, 10, 10, 0.7);`。 |
||||||
|
|
||||||
|
## 五.`::marker` |
||||||
|
|
||||||
|
`::marker`可以用来修改某些元素的标记符号样式,例如`<ul>`和`<ol>`列表项前面的点和数字,也可以更改`<summary>`前面的内容。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="013 Pseudo-elements_04" src="https://codepen.io/AhCola/embed/zYwVqQL?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/zYwVqQL"> |
||||||
|
013 Pseudo-elements_04</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
可支持`::marker`修改的css属性有: |
||||||
|
- `color` |
||||||
|
- `content` |
||||||
|
- `white-space` |
||||||
|
- `font`属性 |
||||||
|
- `animation`和`transition`属性 |
||||||
|
|
||||||
|
## 六.`::selection` |
||||||
|
|
||||||
|
`::selection`允许你修改选中的文本样式。 |
||||||
|
```css |
||||||
|
::selection { |
||||||
|
background: green; |
||||||
|
color: white; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="013 Pseudo-elements_05" src="https://codepen.io/AhCola/embed/eYWwZqr?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/eYWwZqr"> |
||||||
|
013 Pseudo-elements_05</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
`::selection`支持修改的css属性有: |
||||||
|
- `color` |
||||||
|
- `background-color`属性,不支持`background-image` |
||||||
|
- `text`相关属性 |
||||||
|
|
||||||
|
## 七.`::placeholder` |
||||||
|
|
||||||
|
在使用`<input>`元素时,通常会添加一个`placeholder`属性提示用户输入。`::placeholder`伪元素用于更改提示文字(placeholder)的样式。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="" src="https://codepen.io/AhCola/embed/rNmELar?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/rNmELar"> |
||||||
|
</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
支持修改的css属性如下: |
||||||
|
- `color` |
||||||
|
- `background`相关属性 |
||||||
|
- `font`相关属性 |
||||||
|
- `text`相关属性 |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,231 @@ |
|||||||
|
# 伪类 |
||||||
|
|
||||||
|
*伪类(pseudo classes)允许你根据元素的状态动态的设置样式。这意味着,你的设计可以根据用户的操作发生动态的变化。* |
||||||
|
|
||||||
|
本节内容比较多,你不需要完全记住所有的伪类,只需要知道伪类的作用和一些常用伪类即可,用到的时候,可以来这里再回忆一下。 |
||||||
|
|
||||||
|
假设需要在页面上添加一个邮箱输入框,当用户输入无效格式的邮箱字符串时,输入框会出现一个红色的边框,你要如何实现这个功能呢?CSS提供了`:invalid`伪类,恰好满足我们的需求。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="018 Pseudo classes_01" src="https://codepen.io/AhCola/embed/gOROjoN?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/gOROjoN"> |
||||||
|
018 Pseudo classes_01</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
当邮箱账号格式正确时,显示绿色的边框,格式不正确时,显示红色的边框。这种设计可以起到提示的作用。 |
||||||
|
|
||||||
|
例子中的`:invalid`和`:valid`就是伪类。与[伪元素](http://pengfeixc.com/tutorial/css/pseudo-elements)写法有点类似,但是伪类用单冒号表示。 |
||||||
|
|
||||||
|
## 一.交互状态 |
||||||
|
|
||||||
|
下面是一些与用户操作引发元素状态改变有关的伪类。 |
||||||
|
|
||||||
|
### `:hover` |
||||||
|
|
||||||
|
当鼠标悬浮在某个元素上面时,元素的hover状态被激活,你可以用`:hover`更改此时元素的样式。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="018 Pseudo classes_02" src="https://codepen.io/AhCola/embed/JjJjBqm?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/JjJjBqm"> |
||||||
|
018 Pseudo classes_02</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `:active` |
||||||
|
|
||||||
|
当元素正在处于与用户交互的操作时,此时该元素处于激活状态,例如用户点击了该元素,该元素在点击的过程中处于激活状态。可以用`:active`更改这个状态下的元素样式。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="018 Pseudo classes_03" src="https://codepen.io/AhCola/embed/NWgWLWb?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/NWgWLWb"> |
||||||
|
018 Pseudo classes_03</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `:focus`、`:focus-within`和`:focus-visible` |
||||||
|
|
||||||
|
通过`:focus`可以更改focusable元素(例如button)获得焦点时的样式。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="018 Pseudo classes_04" src="https://codepen.io/AhCola/embed/powoOjW?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/powoOjW"> |
||||||
|
018 Pseudo classes_04</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
如果一个元素的子元素获得焦点,可以通过`:focus-within`更改该元素此时的样式。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="018 Pseudo classes_05" src="https://codepen.io/AhCola/embed/rNwNZxK?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/rNwNZxK"> |
||||||
|
018 Pseudo classes_05</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
关于`:focus-visible`[这里](https://www.zhangxinxu.com/wordpress/2019/03/css-focus-visible/)有详细解释。它的作用是可以让我们知道元素的聚焦行为到底是鼠标触发还是键盘触发。 |
||||||
|
例如下面的例子,我们希望去除鼠标点击时候的`outline`轮廓,而保留键盘访问时候的`outline`轮廓。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="018 Pseudo classes_06" src="https://codepen.io/AhCola/embed/zYzYJpe?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/zYzYJpe"> |
||||||
|
018 Pseudo classes_06</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `:target` |
||||||
|
|
||||||
|
当url中锚片段匹配某个元素的id时,可以用`:target`更改此时元素的样式。通常用这个标志页面跳转的区域。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="018 Pseudo classes_07" src="https://codepen.io/AhCola/embed/zYzYJJX?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/zYzYJJX"> |
||||||
|
018 Pseudo classes_07</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
## 二.历史状态 |
||||||
|
|
||||||
|
### `:link` |
||||||
|
|
||||||
|
如果一个拥有`href`属性的`<a>`元素还没有访问过(被用户点击),可以使用`:link`更改它的样式。 |
||||||
|
|
||||||
|
也可以使用`:visited`更改已访问过得`<a>`元素的样式。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="018 Pseudo classes_08" src="https://codepen.io/AhCola/embed/NWgWLJy?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/NWgWLJy"> |
||||||
|
018 Pseudo classes_08</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
#### 顺序问题 |
||||||
|
|
||||||
|
在某些浏览器中,如果你定义了一个`:visited`样式,它可能会被后面定义的`:link`样式覆盖,所以建议按照如下顺序定义伪类样式。 |
||||||
|
```css |
||||||
|
a:link {} |
||||||
|
a:visited {} |
||||||
|
a:hover {} |
||||||
|
a:active {} |
||||||
|
``` |
||||||
|
|
||||||
|
## 三.表单状态 |
||||||
|
|
||||||
|
### `:disabled`和`:enabled` |
||||||
|
|
||||||
|
`:disabled`和`:enabled`用于设置表单元素(例如button)是否禁用时的样式,表单元素默认是enabled,所以我们一般很少用`:enabled`设置元素的样式。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="018 Pseudo classes_09" src="https://codepen.io/AhCola/embed/rNwNqBg?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/rNwNqBg"> |
||||||
|
018 Pseudo classes_09</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `:checked` and `:indeterminate` |
||||||
|
|
||||||
|
`:checked`用于指示某些可以被用户点击选中的表单元素,例如checkbox和radioButton。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="018 Pseudo classes_10" src="https://codepen.io/AhCola/embed/powoxrm?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/powoxrm"> |
||||||
|
018 Pseudo classes_10</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
checkbox元素除了拥有选中和被选中两种状态,还有一种状态为`indeterminate`,需要通过js激活该状态: |
||||||
|
```javascript |
||||||
|
inputCheckbox.indeterminate = true; |
||||||
|
``` |
||||||
|
可以使用`:indeterminate`设置该状态下的样式。 |
||||||
|
|
||||||
|
### `:placeholder-shown` |
||||||
|
|
||||||
|
如果某个表单元素设置了`placeholder`属性,那么当`placeholder`显示的时候,可以用`:placeholder-shown`设置该状态下的样式。 |
||||||
|
|
||||||
|
### 验证状态 |
||||||
|
|
||||||
|
正如文章开始的例子那样,可以使用`:valid`、`:invalid`和`in-range`根据表单元素的验证状态,动态的更改样式。 |
||||||
|
|
||||||
|
`:in-range`主要是针对,设置了`min`和`max`属性的`<input>`元素。例如`<input type=number min=1 max=5 />`,使用下面的css代码,当用户输入数字范围不在1~5范围间时,输入框背景色为红色。 |
||||||
|
```css |
||||||
|
input { |
||||||
|
background: red; |
||||||
|
} |
||||||
|
input:in-range { |
||||||
|
background: white; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## 四.根据元素的索引、出现顺序选中元素 |
||||||
|
|
||||||
|
|
||||||
|
### `:first-child`和`:last-child` |
||||||
|
|
||||||
|
`:first-child`和`:last-child`用于选中一组元素内同级的第一个和最后一个元素。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="018 Pseudo classes_11" src="https://codepen.io/AhCola/embed/PojoxoX?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/PojoxoX"> |
||||||
|
018 Pseudo classes_11</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `only-child` |
||||||
|
|
||||||
|
`only-child`用于选中没有兄弟元素的元素。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="018 Pseudo classes_12" src="https://codepen.io/AhCola/embed/gOROQpZ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/gOROQpZ"> |
||||||
|
018 Pseudo classes_12</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `:first-of-type`和`:last-of-type` |
||||||
|
|
||||||
|
`:first-of-type`和`:last-of-type`与`:first-child`和`:last-child`类似,也是选中第一个和最后一个元素,但是范围不一样,它不限于元素在一个组内,不要求元素是兄弟节点。 |
||||||
|
|
||||||
|
|
||||||
|
### `nth-child`和`nth-of-type` |
||||||
|
|
||||||
|
`nth-child`和`nth-of-type`是前面内容的扩充,用于选中第n个元素。 |
||||||
|
|
||||||
|
你还可以使用`nth-child(even)`选中所有奇数位元素。 |
||||||
|
|
||||||
|
甚至更复杂的形式,选中3n+3位置的元素。 |
||||||
|
```css |
||||||
|
li:nth-child(3n+3) { |
||||||
|
background: yellow; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### `only-of-type` |
||||||
|
|
||||||
|
`only-of-type`与`only-child`元素类似,区别是`only-child`选中的是一组内唯一子元素,而`only-of-type`选中的是一组内唯一类型的子元素。 |
||||||
|
|
||||||
|
|
||||||
|
## 五.寻找空元素 |
||||||
|
|
||||||
|
### `:empty` |
||||||
|
|
||||||
|
当某个元素没有子元素时,我们认为它是一个空元素。可以使用`:empty`设置空元素的样式。 |
||||||
|
|
||||||
|
注意空元素,标签内部没有空格。 |
||||||
|
```html |
||||||
|
<div></div> |
||||||
|
<div> |
||||||
|
</div> |
||||||
|
``` |
||||||
|
第二个`<div>`元素不是一个空元素,所以`:empty`对其无效果。 |
||||||
|
|
||||||
|
## 六.选择和过滤 |
||||||
|
|
||||||
|
### `:is() ` |
||||||
|
|
||||||
|
如果你想要指示类名为`.post`元素下`h2`、`li`子元素,可以这样写: |
||||||
|
```css |
||||||
|
.post :is(h2, li) { |
||||||
|
|
||||||
|
} |
||||||
|
``` |
||||||
|
等价的写法: |
||||||
|
```css |
||||||
|
.post h2,.post li { |
||||||
|
|
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### `:not()` |
||||||
|
|
||||||
|
可以使用`:not()`排除某些元素。例如选中所有没有类名(`class`属性)的链接。 |
||||||
|
```css |
||||||
|
a:not([class]) { |
||||||
|
|
||||||
|
} |
||||||
|
``` |
||||||
|
选中所有没有`alt`属性的图片。 |
||||||
|
```css |
||||||
|
img:not([alt]) { |
||||||
|
|
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,218 @@ |
|||||||
|
# 边框 |
||||||
|
|
||||||
|
*边框指的是CSS元素盒子的边框。本节内容将说明如何通过css更改边框的尺寸、样式和颜色。* |
||||||
|
|
||||||
|
在[盒模型](http://pengfeixc.com/tutorial/css/box-model)章节中,讲述了盒模型由四个部分组成:内容区(content box)、内边距(padding box)、边框(border box)和外边距(margin box)。 |
||||||
|
|
||||||
|
可以通过`border`属性修改边框(border box)的样式。 |
||||||
|
|
||||||
|
## 一.边框属性 |
||||||
|
|
||||||
|
### 类型 |
||||||
|
|
||||||
|
元素的边框可以有多种类型,例如实线、虚线、双线等等。可以通过`border-style`属性修改边框的风格。 |
||||||
|
|
||||||
|
有以下几种样式: |
||||||
|
- dotted |
||||||
|
- dashed |
||||||
|
- solid |
||||||
|
- double |
||||||
|
- groove |
||||||
|
- ridge |
||||||
|
- inset |
||||||
|
- outset |
||||||
|
|
||||||
|
各类型边框效果如下。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="014 Border_01" src="https://codepen.io/AhCola/embed/WNjqmXZ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/WNjqmXZ"> |
||||||
|
014 Border_01</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
你也可以使用`border-top-style`、`border-right-style`、 `border-left-style`和`border-bottom-style`单独设置元素盒子某一侧的边框样式。 |
||||||
|
|
||||||
|
### 简写 |
||||||
|
|
||||||
|
与`margin`和`padding`类似,可以使用`border`定义边框的所有style。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
border: 1px solid red; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
`border`属性接受值的顺序为:`border-width`、`border-style`、`border-color`。 |
||||||
|
|
||||||
|
### 颜色 |
||||||
|
|
||||||
|
默认情况下,边框的颜色与文字的`currentColor`一致。可以通过`border-color`自定义边框的颜色。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
border-color: blue; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="014 Border_02" src="https://codepen.io/AhCola/embed/BaRgbOZ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/BaRgbOZ"> |
||||||
|
014 Border_02</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
也可以使用`border-top-color`、`border-right-color`、`border-left-color`和`border-bottom-color`单独设置某一侧的颜色。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="014 Border_03" src="https://codepen.io/AhCola/embed/vYmqPQK?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/vYmqPQK"> |
||||||
|
014 Border_03</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### 宽度 |
||||||
|
|
||||||
|
边框的宽度就是边框的厚度,用`border-width`设置边框的宽度。默认的边框的宽度为`medium`。默认情况下,我们是看不到边框的,只有当设置了`border-style`后,边框才会显示出来。还可以使用`thin`和`thick`关键字定义边框的宽度。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="014 Border_04" src="https://codepen.io/AhCola/embed/vYmqPPX?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/vYmqPPX"> |
||||||
|
014 Border_04</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
同样,可以使用`border-top-width`、`border-right-width`、`border-left-width`和`border-bottom-width`单独定义每一侧边框的宽度。 |
||||||
|
|
||||||
|
## 二.逻辑属性 |
||||||
|
|
||||||
|
在[逻辑属性](http://www.pengfeixc.com/tutorial/css/logic-property)讲解过块流、内联流和逻辑属性的知识。 |
||||||
|
|
||||||
|
边框也有对应的逻辑属性。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
border: 2px dotted; |
||||||
|
border-inline-end: 2px solid red; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="014 Border_05" src="https://codepen.io/AhCola/embed/eYWwXaX?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/eYWwXaX"> |
||||||
|
014 Border_05</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
在英文文档中,文档的默认内联流方向是从左至右的,所以`border-inline-end`设置的是右侧边框。 |
||||||
|
|
||||||
|
> 这里在提醒一下大家,目前(2021年8月19日)**很多逻辑属性仍然处于测试阶段**,所以并不是所有的浏览器都支持逻辑属性,所以建议大家少用逻辑属性,如果需要用逻辑属性,在使用前检查浏览器是否支持该逻辑属性。 |
||||||
|
|
||||||
|
## 三.圆角半径 |
||||||
|
|
||||||
|
`border-radius`可以为边框添加圆角。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
border-radius: 1em; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="014 Border_06" src="https://codepen.io/AhCola/embed/zYwVXOg?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/zYwVXOg"> |
||||||
|
014 Border_06</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
`border-radius`是`border-top-left-radius`、`border-top-right-radius`、`border-bottom-right-radius`和`border-bottom-left-radius`的简写方式,所以可以单独设置某一个角的圆角半径。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
border-radius: 1em 2em 3em 4em; |
||||||
|
} |
||||||
|
|
||||||
|
// 等价的写法 |
||||||
|
.ele { |
||||||
|
border-top-left-radius: 1em; |
||||||
|
border-top-right-radius: 2em; |
||||||
|
border-bottom-right-radius: 3em; |
||||||
|
border-bottom-left-radius: 4em; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### 椭圆圆角 |
||||||
|
|
||||||
|
`border-top-left-radius`、`border-top-right-radius`、`border-bottom-right-radius`和`border-bottom-left-radius`都可以接受两个值,将圆角的圆弧设置成椭圆的弧形。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
border-top-left-radius: 1em 2em; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
上面的代码,将top-left-top的半径设置为1em,将top-left-left的半径设置为2em。你可以想像圆角的圆弧为椭圆的左上角的四分之一弧,该椭圆的x半径为1em,y半径为2em。具体效果如下。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="014 Border_07" src="https://codepen.io/AhCola/embed/bGWPJEM?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/bGWPJEM"> |
||||||
|
014 Border_07</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
如果用`border-radius`简写方式,需要使用`/`标记。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
border-radius: 95px 155px 148px 103px / 48px 95px 130px 203px; |
||||||
|
} |
||||||
|
|
||||||
|
// 拆分的等价写法 |
||||||
|
.ele { |
||||||
|
border-top-left-radius: 95px 48px; |
||||||
|
border-top-right-radius: 155px 95px; |
||||||
|
border-bottom-right-radius: 148px 130px; |
||||||
|
border-bottom-left-radius: 103px 203px; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## 四.图片边框 |
||||||
|
|
||||||
|
css还支持用图片设置边框。`border-image`属性允许用户设置图片作为边框。它是`border-image-source`、`border-image-slice`、`border-image-width`、`border-image-outset`和`border-image-repeat`的复合简写方式。 |
||||||
|
- `border-image-source`:图片源 |
||||||
|
- `border-image-slice`:分割图片 |
||||||
|
- `border-image-width`:图像边框宽度 |
||||||
|
- `border-image-outset`:定义边框图像可超出边框盒的大小 |
||||||
|
- `border-image-repeat`:定义图片如何填充边框 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="014 Border_08" src="https://codepen.io/AhCola/embed/zYwVXjr?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/zYwVXjr"> |
||||||
|
014 Border_08</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### border-image-source |
||||||
|
|
||||||
|
`border-image-source`可以是任意有效图片的url,也可以是css渐变。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
border-image-source: url('path/to/image.png'); |
||||||
|
} |
||||||
|
|
||||||
|
.my-element { |
||||||
|
border-image-source: linear-gradient(to bottom, #000, #fff); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### border-image-slice |
||||||
|
|
||||||
|
`border-image-slice`允许你用四条分割线将图片分割成9个部分。类似`margin`简写方式,定义了上、右、下、左四侧偏移值。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
border-image: url('image.jpg'); |
||||||
|
border-image-slice: 61 58 51 48; |
||||||
|
} |
||||||
|
``` |
||||||
|
![border-image-slice](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/129.jpg) |
||||||
|
|
||||||
|
经过四条分割线,图片被分成9个区域:四个角(左上、右上、右下和左下)、四边(上、右、下、左)和中间区域。四个角区域用于渲染元素盒子的四个角,四边区域用于渲染元素的边缘。`border-image-repeat`定义了它们是如何填充各自负责的空间的。`border-image-width`定义了边框的宽度。 |
||||||
|
|
||||||
|
`fill`关键字用于将分割的中间区域作为元素的背景图片。 |
||||||
|
|
||||||
|
### border-image-repeat |
||||||
|
|
||||||
|
`border-image-repeat`决定了边框图片是如何填充的。 |
||||||
|
|
||||||
|
- `stretch`:默认方式,边框图片将会被拉伸以填满区域。 |
||||||
|
- `repeat`:边框图片重复,以填满区域。 |
||||||
|
- `round`:与`repeat`类似,区别在于对待四个角的处理方式不同,`repeat`会将多余的部分切割掉,而`round`不会。 |
||||||
|
- `space`:与`repeat`类似,只不过会在图片中间填充空格。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="014 Border_09" src="https://codepen.io/AhCola/embed/ZEKdZgQ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/ZEKdZgQ"> |
||||||
|
014 Border_09</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,90 @@ |
|||||||
|
# 阴影 |
||||||
|
|
||||||
|
*css提供了多种方式可以为元素或者文字添加不同的阴影效果。通过本节内容,你将学会如何使用这些方式,知道它们各自的用途。* |
||||||
|
|
||||||
|
## 一.`box-shadow` |
||||||
|
|
||||||
|
`box-shadow`是比较常用的一个属性,可以为元素边框周围添加一层阴影效果。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
box-shadow: 5px 5px 20px 5px #000; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
`box-shadow`接受的值,按照从左至右的顺序依次表示: |
||||||
|
1. x偏移:水平偏移,正值表示向右偏移,负值表示向左偏移。 |
||||||
|
2. y偏移:竖直偏移,正值表示向下偏移,负值表示向上偏移。 |
||||||
|
3. 模糊半径:表示阴影的模糊范围。 |
||||||
|
4. 扩散半径(可选):正值会增加阴影的半径,负值会减少阴影的半径,设置为0时,阴影半径为模糊半径。 |
||||||
|
5. 颜色:设置阴影的颜色,如果没有显示设置该值,那么会使用text的颜色作为阴影颜色。 |
||||||
|
|
||||||
|
还可以在`box-shadow`值最开始处添加`inset`关键字,使阴影呈现在边框内部。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="015 Box Shadow_01" src="https://codepen.io/AhCola/embed/OJmKZLg?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/OJmKZLg"> |
||||||
|
015 Box Shadow_01</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
可以添加多个阴影,形成叠加效果。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
box-shadow: 5px 5px 20px 5px darkslateblue, -5px -5px 20px 5px dodgerblue, |
||||||
|
inset 0px 0px 10px 2px darkslategray, inset 0px 0px 20px 10px steelblue; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="015 Box Shadow_02" src="https://codepen.io/AhCola/embed/MWmNGYz?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/MWmNGYz"> |
||||||
|
015 Box Shadow_02</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
## 二.`text-shadow` |
||||||
|
|
||||||
|
使用`text-shadow`可以给文字添加阴影效果。与`box-shadow`类似,但是作用对象是文字。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
text-shadow: 3px 3px 3px hotpink; |
||||||
|
} |
||||||
|
``` |
||||||
|
`text-shadow`接受的值与`box-shadow`一样。唯一不同的是,`text-shadow`不能设置扩散半径和`inset`关键字。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="015 Box Shadow_03" src="https://codepen.io/AhCola/embed/rNmXveb?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/rNmXveb"> |
||||||
|
015 Box Shadow_03</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
和`box-shadow`一样,也可以给文字添加多个阴影。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
text-shadow: 1px 1px 0px white,2px 2px 0px firebrick; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="015 Box Shadow_04" src="https://codepen.io/AhCola/embed/wvdVjzp?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/wvdVjzp"> |
||||||
|
015 Box Shadow_04</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
## 三.`drop-shadow` |
||||||
|
|
||||||
|
`drop-shadow`是一个css函数,而不是属性。用于给图片中的内容添加阴影的,对的你没有看错的确是图片里的内容。实现过程实际上是分析图片中的内容,然后在图片原有的位置上添加一个模糊的偏移的图片,达到阴影的效果。与[filter](http://pengfeixc.com/blogs/css/css-filter)属性配合使用。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
filter: drop-shadow(0px 0px 10px rgba(0 0 0 / 30%)) |
||||||
|
} |
||||||
|
``` |
||||||
|
`drop-shadow`参数与`box-shadow`一样,但是不能设置扩散半径和`inset`关键字,你也可以为图片添加多个阴影。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
filter: drop-shadow(0px 0px 10px hotpink) drop-shadow(10px 10px 20px rgba(0 0 0 / 30%)) |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="015 Box Shadow_05" src="https://codepen.io/AhCola/embed/ExmqLwa?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/ExmqLwa"> |
||||||
|
015 Box Shadow_05</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,59 @@ |
|||||||
|
# 焦点focus |
||||||
|
|
||||||
|
*本节讲述web应用中焦点的重要性。你将会知道如何管理焦点,引导别人使用鼠标或者键盘来浏览你的页面。* |
||||||
|
|
||||||
|
在某个页面,你点击了一个链接,然后跳转到网站的主页面。通常这个链接叫做跳转链接或者锚链接。当这个链接被键盘激活时(通常使用*tab*或者*enter*键),它的周围会有一圈焦点圈,表示该元素获得了焦点。 |
||||||
|
|
||||||
|
## 一.为什么焦点很重要? |
||||||
|
|
||||||
|
作为一个web开发者,你的职责是让所有人可以浏览(操作)你的网页。css焦点就是为了这个目的而诞生的。 |
||||||
|
|
||||||
|
焦点存在的目的,是为了方便那些使用键盘的人浏览页面的。如果一个元素获得了焦点,但是没有任何视觉上的指示表明它获得了焦点,那么使用键盘的人就不会知道此时哪个元素是处于激活状态的(哪个元素获得了焦点),这将会导致导航出错,例如跳转到错误的页面。 |
||||||
|
|
||||||
|
## 二.元素是如何获得焦点的? |
||||||
|
|
||||||
|
某些可操作的元素自带获得焦点的属性。例如`<a>`、`<button>`、`<input>`和`<select>`。如果一个元素可以获得焦点,我将之称为**focusable元素**(实在不知道怎么翻译这个名称,翻译成中文可获得焦点的元素,太长了,后面就用**focusable元素**称呼它)。 |
||||||
|
|
||||||
|
我们可以用键盘*tab*键,在一个页面的所有focusable元素来回移动,达到导航的作用。 |
||||||
|
|
||||||
|
我们还可以通过html的`tabindex`属性,使非focusable元素变成focusable元素,只需要设置`tabindex=0`。 |
||||||
|
```css |
||||||
|
<div tabindex="0">可以获得焦点</div> |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="016 Focus_01" src="https://codepen.io/AhCola/embed/wvevawj?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/wvevawj"> |
||||||
|
016 Focus_01</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
可以设置tabindex值小于0,将focusable元素变成非focusable元素,例如`tabindex=-1`。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="016 Focus_02" src="https://codepen.io/AhCola/embed/ZEyEGEd?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/ZEyEGEd"> |
||||||
|
016 Focus_02</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
应该**避免将tabindex设置为任何大于0的数**。因为`tabindex`大于0会导致比较奇怪的现象,当页面存在`tabindex`大于0的元素,用户按下tab键,页面中元素获得焦点的顺序首先从**tabindex**大于0的最小的那个元素开始,然后从这个元素开始向下在循环整个页面中的focusable元素。而且我认为我们不应该通过这种方式更改页面focusable元素,获得焦点的顺序,因为页面的阅读方向应该是从上至下的。所以建议大家避免这种错误的使用方式。 |
||||||
|
|
||||||
|
## 三.自定义获得焦点时的样式 |
||||||
|
|
||||||
|
默认情况下,浏览器会给获得焦点的元素添加一个焦点环,表示某个元素获得了焦点。焦点环的样式,在不同浏览器、不同系统上是不一样的。 |
||||||
|
|
||||||
|
我们可以通过css修改焦点环的样式。主要通过`:focus`、`:focus-within`和`:focus-visible`伪类修改。 |
||||||
|
|
||||||
|
通过`:focus`和`outline`,可以更改焦点环的样式: |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="016 Focus_03" src="https://codepen.io/AhCola/embed/OJgJVpw?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/OJgJVpw"> |
||||||
|
016 Focus_03</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
有时候焦点环,离文字内容太近了,可以通过`outline-offset`属性更改。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="016 Focus_04" src="https://codepen.io/AhCola/embed/OJgJVgo?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/OJgJVgo"> |
||||||
|
016 Focus_04</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,94 @@ |
|||||||
|
# z-index和栈空间 |
||||||
|
|
||||||
|
*本节内容,将深入研究z-index这个属性和栈空间(stacking context)。* |
||||||
|
|
||||||
|
## 一.z-index |
||||||
|
[MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/z-index)上是这样描述z-index的: |
||||||
|
> `z-index`属性设定了一个定位元素及其后代元素或flex项目的z-order。 当元素之间重叠的时候,`z-index`较大的元素会覆盖较小的元素在上层进行显示。 |
||||||
|
|
||||||
|
MDN中还提到了下面两点内容,作为补充。 |
||||||
|
> 1.盒子在当前堆叠上下文中的堆叠层级。 |
||||||
|
> |
||||||
|
> 2.盒子是否创建一个本地堆叠上下文。 |
||||||
|
|
||||||
|
如果你足够细心,应该能够注意到**堆叠上下文**这个词。本着好好学习天天向上的精神,我们来个追查到底。 |
||||||
|
|
||||||
|
先来看一个例子。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="z-index and stacking context_01" src="https://codepen.io/AhCola/embed/WNjVEBm?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/WNjVEBm"> |
||||||
|
z-index and stacking context_01</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
为什么`z-index`设置为`-1`,但是它还是在最上面显示呢? |
||||||
|
|
||||||
|
其实罪魁祸首就是**堆叠上下文**。 |
||||||
|
|
||||||
|
## 二.栈空间 |
||||||
|
|
||||||
|
**栈空间(stacking context),也称堆叠上下文**。[w3c](https://www.w3.org/TR/2012/WD-css3-positioning-20120207/#det-stacking-context)中有详细介绍,我在这里就扮演一个搬运工的角色,将这部分内容搬出来。 |
||||||
|
|
||||||
|
在css(html)的世界中,所有的元素都是处于三维世界中的,对的是三维的,它们不仅仅只有x和y坐标,还有一个z坐标,在图形学中z坐标也叫做深度。你可以认为这个css的坐标系的x正轴方向是从左到右,y正轴方向是从上到下,z轴方向是从屏幕里指向屏幕外的。 |
||||||
|
|
||||||
|
每个元素box都属于一个栈空间,这些元素box在栈空间内都有一个整数的**栈层级**,元素的**栈层级**可以用`z-index`,默认**栈层级**为0,同一个栈空间内,栈层级大的元素永远在栈层级小的元素的前面,栈层级大表示其z坐标大,越靠近屏幕外面,离人眼越近,所以一般我们可以通过设置`z-index`使某个元素显示在其他元素的上面。 |
||||||
|
|
||||||
|
![stacking context](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/130.jpg) |
||||||
|
|
||||||
|
### 栈空间的创建 |
||||||
|
|
||||||
|
根元素会创建一个**根栈空间(root stacking context)**,根栈空间内的元素有可能会创建一个**局部的栈空间**,然后局部栈空间内的元素可能又会创建一个**局部栈空间内的局部栈空间**... |
||||||
|
|
||||||
|
创建局部栈空间的元素有两个栈层级:一个是它在它所属的栈空间中的栈层级(栈层级由它的z-index设置),另一个是它在自己所创建的局部栈空间内的栈层级(栈层级为0)。 |
||||||
|
|
||||||
|
子元素的栈层级与它的父元素的栈层级相等,除非设置它的**z-index**属性为一个不同的值。 |
||||||
|
|
||||||
|
#### 1.position属性 |
||||||
|
|
||||||
|
如果设置了一个元素的position属性,那么该元素有可能会创建一个局部栈空间。具体由该元素的z-index属性确定。 |
||||||
|
|
||||||
|
`z-index`有两个作用: |
||||||
|
1. 设置元素在所属栈空间内的栈层级。 |
||||||
|
2. 决定元素是否创建了一个局部栈空间。 |
||||||
|
|
||||||
|
`z-index`接受两种值:关键字`auto`、整数。 |
||||||
|
1. `z-index:auto;`: 元素在所属栈空间内的栈层级为0,元素不会创建新的栈空间(局部栈空间),除非该元素是页面根元素,页面根元素默认会创建一个栈空间。 |
||||||
|
2. `z-index:<interger>`: 元素在所属栈空间内的栈层级为0设置的`<interger>`,元素会创建一个新的局部栈空间。 |
||||||
|
|
||||||
|
所以前面那个例子,我们设置了`z-index:-1;`没有效果,因为`<span>`元素处于新的局部栈空间内。而它的父元素在外层栈空间内的栈层级为0。 |
||||||
|
|
||||||
|
#### 2.其他 |
||||||
|
|
||||||
|
还有许多其他情况也可以创建新的栈空间,这里我做一个总结。 |
||||||
|
- 文档根元素(html)。 |
||||||
|
- `position`为`absolute`或`relative`的元素,并且`z-index`不为`auto`的元素。 |
||||||
|
- `position`为`fixed`或者`sticky`的元素。 |
||||||
|
- flex容器的子元素(项目),且`z-index`值不为`auto`。 |
||||||
|
- grid容器的子元素(项目),且`z-index`值不为`auto`。 |
||||||
|
- `opacity`属性值小于`1`的元素 |
||||||
|
- `mix-blend-mode`属性值不为`normal`的元素; |
||||||
|
- 以下任意属性值不为 none 的元素: |
||||||
|
- `transform` |
||||||
|
- `filter` |
||||||
|
- `perspective` |
||||||
|
- `clip-path` |
||||||
|
- `mask`/`mask-image`/`mask-border` |
||||||
|
- `isolation`属性值为`isolate`的元素。 |
||||||
|
- `-webkit-overflow-scrolling`属性值为`touch`的元素。 |
||||||
|
|
||||||
|
## 三.绘制顺序 |
||||||
|
|
||||||
|
元素的绘制顺序,影响了当两个元素重叠时,其中一个元素是否会被另一个元素遮住。 |
||||||
|
|
||||||
|
在一个栈空间内,绘制顺序从先往后大致如下。 |
||||||
|
1. 构成该栈空间元素的背景和边框(先绘制背景,再绘制边框)。 |
||||||
|
2. `z-index`为负值的并且创建了局部栈空间的元素,`z-index`最小的先绘制。 |
||||||
|
3. 处在正常文档流内,position为static的非内联(non-inline)元素。 |
||||||
|
4. position为static的浮动元素。 |
||||||
|
5. 处在正常文档流内,position为static的内联(inline)元素,包括内联table和内联块(inline blocks)。 |
||||||
|
6. `z-index`为0的并且创建了局部站那空间的元素和`z-index`为0并且position为非static的元素。 |
||||||
|
7. `z-index`为正值的并且创建了局部栈空间的元素,`z-index`最小的先绘制。 |
||||||
|
|
||||||
|
更详细的绘制顺序可以参考[这里](https://www.w3.org/TR/2012/WD-css3-positioning-20120207/#det-stacking-context)。 |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,221 @@ |
|||||||
|
# CSS函数 |
||||||
|
|
||||||
|
*css有一些内置的函数(方法)。本节内容带大家一起了解一些常用的内置函数。* |
||||||
|
|
||||||
|
在前面的章节中,我们已经使用过一些函数了,例如`minmax()`、`fit-content()`、`rgb()`、`hsl()`以及`calc()`等。 |
||||||
|
|
||||||
|
与其他语言一样,css同样包含一些内置的函数,你可以在页面的任何地方使用它们来修改优化页面的样式。 |
||||||
|
|
||||||
|
每个函数都有它各自的目的及用法。本节将对这些函数做个大概的讲解,希望可以帮助你更好的认识和理解css函数。 |
||||||
|
|
||||||
|
## 一.函数是什么? |
||||||
|
|
||||||
|
如果你是个程序员,你肯定知道函数是什么。函数是一段代码的封装,这段代码用于完成某个特定的任务。函数有入口和出口,你可以通过入口传递一些参数给函数,等函数执行完毕,它的执行结果从出口出来。css的函数类似一个加工厂的生产机器,你给它一些原材料(函数参数),它会帮你加工,生产产品(函数返回值)。这里我不做过多介绍。 |
||||||
|
|
||||||
|
你可以将函数认为是一个数学公式,例如`a+b`,向公式传入参数`a`和`b`的值`1`和`2`,得到结果`3`。 |
||||||
|
|
||||||
|
在其他语言(C#、C++、javascript)中,你可以自定义函数使用。但是在css中,你只可以使用css内置的函数。 |
||||||
|
|
||||||
|
## 二.函数选择器 |
||||||
|
|
||||||
|
```css |
||||||
|
.post :is(h1, h2, h3) { |
||||||
|
line-height: 1.2; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
在[伪类](http://pengfeixc.com/tutorial/css/pseudo-class)中介绍过`:is()`和`:not()`的作用。`:is()`和`:not()`接受的参数为css选择器,它们用于选择和过滤元素。 |
||||||
|
|
||||||
|
|
||||||
|
## 三.自定义属性和`var()` |
||||||
|
|
||||||
|
```css |
||||||
|
:root { |
||||||
|
--base-color: #ff00ff; |
||||||
|
} |
||||||
|
|
||||||
|
.my-element { |
||||||
|
background: var(--base-color); |
||||||
|
} |
||||||
|
``` |
||||||
|
自定义属性也叫做**CSS变量**。自定义属性名称必须以双横线(--)开头,表示它是一个自定义属性(css变量)。 |
||||||
|
|
||||||
|
`var()`函数接受一个自定义属性名称作为参数,然后返回该自定义变量的值(css样式)。上面的代码,`var()`函数以`--base-color`为参数,如果`--base-color`已经定义,那么`var()`函数将返回`--base-color`变量的值。 |
||||||
|
|
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
background: var(--base-color, hotpink); |
||||||
|
} |
||||||
|
``` |
||||||
|
你还可以给`var()`函数传递第二个参数,表示如果没有找到`--base-color`的定义,函数会以`hotpink`作为返回值(输出)。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="019 Functions_01" src="https://codepen.io/AhCola/embed/YzQPVjx?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/YzQPVjx"> |
||||||
|
019 Functions_01</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
## 四.有返回值的函数 |
||||||
|
|
||||||
|
并不是所有函数都有返回值得。`var()`函数恰好是一个有返回值的函数。`attr()`和`url()`函数与`var()`类似,你可以向它们传递一个或者多个参数,然后将它们作为css声明的属性值。 |
||||||
|
```css |
||||||
|
a::after { |
||||||
|
content: attr(href); |
||||||
|
} |
||||||
|
``` |
||||||
|
上面的代码,将`<a>`元素的`href`属性值与`::after`伪类元素的内容绑定,当`href`属性变化时,`::after`伪类的内容也会变化。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
background-image: url('/path/to/image.jpg'); |
||||||
|
} |
||||||
|
``` |
||||||
|
`url()`函数接受一个URL字符串,用于加载图片、字体和内容。如果没有传递一个有效的url或者url指示的资源找不到了,那么`url()`函数不会返回任何值。 |
||||||
|
|
||||||
|
## 五.颜色函数 |
||||||
|
|
||||||
|
在[颜色](http://pengfeixc.com/tutorial/css/color)章节中,我们介绍过与颜色相关的所有函数。如果你还没有看过[这篇](http://pengfeixc.com/tutorial/css/color)文章,强烈建议你去看一下。 |
||||||
|
|
||||||
|
与颜色相关的函数:`rgb()`、`rgba()`、`hsl()`、`hsla()`、`hwb()`、`lab()` 和`lch()`。它们都接受一些参数,然后返回一个颜色。 |
||||||
|
|
||||||
|
## 六.数学表达式 |
||||||
|
|
||||||
|
CSS提供了一些非常有用的数学计算相关的函数。 |
||||||
|
|
||||||
|
### `calc()` |
||||||
|
|
||||||
|
`calc()`接受一个数学表达式作为参数,返回该表达式的结果。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
width: calc(100% - 2rem); |
||||||
|
} |
||||||
|
``` |
||||||
|
上面的代码,`calc()`的计算结果是`.ele`元素的容器元素的高度减去`2rem`,然后将结果作为`.ele`的宽度。 |
||||||
|
|
||||||
|
`calc`函数可以嵌套使用,你还可以将`var()`函数作为表达式参数的一部分。 |
||||||
|
```css |
||||||
|
:root { |
||||||
|
--root-height: 5rem; |
||||||
|
} |
||||||
|
|
||||||
|
.my-element { |
||||||
|
width: calc(calc(10% + 2rem) * 2); |
||||||
|
height: calc(var(--root-height) * 3); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### `min()`和`max()` |
||||||
|
|
||||||
|
通过名称,就知道这两个函数是用来计算最大值和最小值的,它们都接受两个参数,返回两个数中的最小值和最大值。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
width: min(20vw, 30rem); |
||||||
|
height: max(20vh, 20rem); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### `clamp()` |
||||||
|
|
||||||
|
`clamp()`函数接受三个参数:最小值、理想值、最大值。 |
||||||
|
|
||||||
|
`clamp(MIN, VAL, MAX)`与`max(MIN, min(VAL, MAX))`等价,`clamp(MIN, VAL, MAX)`的目的是要找到三个数的中间值。 |
||||||
|
1. 如果`VAL`在`MIN`和`MAX`之间,结果为`VAL`。 |
||||||
|
2. 如果`VAL`小于`MIN`,结果为`MIN`。 |
||||||
|
3. 如果`VAL`大于`MAX`,结果为`MAX`。 |
||||||
|
|
||||||
|
```css |
||||||
|
h1 { |
||||||
|
font-size: clamp(2rem, 1rem + 3vw, 3rem); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
`min`、`max`和`clamp`在其他语言也有类似的实现,基本用法都是一样的。 |
||||||
|
|
||||||
|
## 七.形状 |
||||||
|
|
||||||
|
`clip-path`、`offset-path`和`shape-outside`属性用于裁剪元素盒子或者为内容提供一个形状区域。它们接受一些css函数作为属性值。 |
||||||
|
|
||||||
|
例如一些简单的形状函数,`circle()`、`ellipse()`和`inset`,还有一些更复杂的函数,例如`polygon()`。 |
||||||
|
```css |
||||||
|
.circle { |
||||||
|
clip-path: circle(50%); |
||||||
|
} |
||||||
|
|
||||||
|
.polygon { |
||||||
|
clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## 八.变换 |
||||||
|
|
||||||
|
最后,再介绍下css中的变换。下面所有的变换都是用`transform`属性实现的。 |
||||||
|
|
||||||
|
### 旋转 |
||||||
|
|
||||||
|
你可以使用`rotate()`函数旋转一个元素,它将一个元素绕其中心轴,旋转一个角度。你可以使用`rotateX()`、`rotateY()`、`rotateZ()`函数,让元素绕某个特定轴旋转。旋转函数接受`deg`、`turn`或者`rad`等角度单位值作为参数。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
transform: rotateX(10deg) rotateY(10deg) rotateZ(10deg); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="019 Functions_02" src="https://codepen.io/AhCola/embed/oNwgebm?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/oNwgebm"> |
||||||
|
019 Functions_02</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
还有一个`rotate3d()`函数,接受4个参数,前三个参数是数字,定义X、Y、Z坐标,第四个参数表示角度。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
transform: rotate3d(1, 1, 1, 10deg); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### 缩放 |
||||||
|
|
||||||
|
`scale()`函数用于缩放元素。同样有`scaleX()`、`scaleY()`、`scaleZ()`,用于缩放不同轴方向的尺寸。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
transform: scaleX(1.2) scaleY(1.2); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
`scale3d()`与`rotate3d()`类似,只不过它接受三个参数,分别是X、Y、Z方向的缩放因子。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="019 Functions_03" src="https://codepen.io/AhCola/embed/abwzyZa?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/abwzyZa"> |
||||||
|
019 Functions_03</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### 平移 |
||||||
|
|
||||||
|
与旋转,缩放类似。使用`translateX()`、`translateY()`、`translateZ()`可以分别在x、y、z方向上平移元素,`translate3d()`可以在一个函数类定义x、y、z方向上平移的量。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="019 Functions_04" src="https://codepen.io/AhCola/embed/QWgwMdv?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/QWgwMdv"> |
||||||
|
019 Functions_04</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### 偏移 |
||||||
|
|
||||||
|
`skew()`函数可以使元素偏移,如果传递一个参数,它会将元素在x方向上偏移,如果传递两个参数,x和y方向都会发生偏移。可以使用`skewX()`和`skewY()`单独在某个方向上偏移。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
transform: skew(10deg); |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="019 Functions_05" src="https://codepen.io/AhCola/embed/gORbxRP?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/gORbxRP"> |
||||||
|
019 Functions_05</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
`translate`属性可以接受多个变换函数作为值,例如元素先向x方向平移`10px`,在向下平移`10px`,在旋转`10deg`。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
transform: translateX(10px) translateY(10px) rotateZ(80deg);; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,160 @@ |
|||||||
|
# 渐变 |
||||||
|
|
||||||
|
*通过css渐变,可以在不使用任何图片的情况下创建非常棒的效果。本节内容,一起看一下css中的各种渐变。* |
||||||
|
|
||||||
|
假设公司的UI递过来一份web设计稿让你完成。主页面的header是一段文字和一个按钮,背景是一个渐变色的背景图,你如何去完成这个header呢? |
||||||
|
|
||||||
|
![css渐变](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/134.jpg) |
||||||
|
|
||||||
|
如果你没有用过css渐变,你可能会想到用图片处理软件创建一个背景图,然后使用`background`属性设置header的背景图片来完成任务。但是css提供了`linear-gradient`,可以很方便的解决这个问题。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="020 Gradient_01" src="https://codepen.io/AhCola/embed/MWowwBd?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/MWowwBd"> |
||||||
|
020 Gradient_01</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
渐变本质上是一张图片,可以被用在任何可以使用图片的地方来代替图片,例如`background-image`。 |
||||||
|
|
||||||
|
css可以创建多种渐变,接下来我将详细介绍各种渐变。 |
||||||
|
|
||||||
|
## 一.线性渐变 |
||||||
|
|
||||||
|
`linear-gradient()`函数可以通过两个或者多个颜色生成一张图片。它接受多个参数,你可以将一些颜色传递给它,它会将这些颜色均匀的设置在背景的相应位置,然后进行均匀渐变,生成一张图片。下面的例子设置了`background: linear-gradient(red, orange, yellow, green, cyan, blue, purple);`。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="020 Gradient_02" src="https://codepen.io/AhCola/embed/JjJddQR?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/JjJddQR"> |
||||||
|
020 Gradient_02</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
默认的颜色渐变方向是从上至下的。你可以通过`to <direction>`更改默认的渐变方向。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
background: linear-gradient(to right, red, orange, yellow, green, cyan, blue, purple); |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="020 Gradient_03" src="https://codepen.io/AhCola/embed/OJgVyVo?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/OJgVyVo"> |
||||||
|
020 Gradient_03</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
通过`to right`指定渐变方向是从左至右的。指定两个方向可以将渐变方向改成对角线渐变。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
background: linear-gradient(to bottom right, red, orange, yellow, green, cyan, blue, purple); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
还可以通过角度和位置更改渐变的位置和方向。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
background: linear-gradient(45deg, black 30%, white); |
||||||
|
} |
||||||
|
``` |
||||||
|
`45deg`表示将渐变的方向旋转45度,从`black`颜色开始,一直到`30%`的位置开始慢慢渐变成`white`。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="020 Gradient_04" src="https://codepen.io/AhCola/embed/BaZNoQv?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/BaZNoQv"> |
||||||
|
020 Gradient_04</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
指定角度和渐变开始的位置也支持设置多种颜色。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
background: linear-gradient(45deg, darkred 20%, crimson, darkorange 60%, gold, bisque); |
||||||
|
} |
||||||
|
``` |
||||||
|
上面的代码表示渐变的方向是45度,颜色开始是`darkred`,在`20%`位置时渐变到`crimson`,再渐变到`darkorange`,然后以`darkorange`一直持续到`60%`的位置再开始渐变到`gold`,最后渐变到`bisque`。 |
||||||
|
|
||||||
|
## 二.径向渐变 |
||||||
|
|
||||||
|
**径向渐变**指的是从某一点向四周扩散渐变。使用`radial-gradient()`函数创建径向渐变图片。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
background: radial-gradient(white, black); |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="020 Gradient_05" src="https://codepen.io/AhCola/embed/MWowava?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/MWowava"> |
||||||
|
020 Gradient_05</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
和`linear-gradient`一样,可以指定多个渐变色和渐变位置。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
background: radial-gradient(darkred 20%, crimson, darkorange 60%, gold, bisque); |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="020 Gradient_06" src="https://codepen.io/AhCola/embed/mdwJeBG?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/mdwJeBG"> |
||||||
|
020 Gradient_06</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
## 三.旋转渐变(Conic gradient) |
||||||
|
|
||||||
|
旋转渐变有一个中心点,默认从上方开始,绕着中心点旋转渐变。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
background: conic-gradient(white, black); |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="020 Gradient_07" src="https://codepen.io/AhCola/embed/yLXNYqO?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/yLXNYqO"> |
||||||
|
020 Gradient_07</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
可以指定中心位置,和开始渐变的角度。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
background: conic-gradient(from 10deg at 20% 30%, white, black); |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="020 Gradient_08" src="https://codepen.io/AhCola/embed/NWgqGLK?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/NWgqGLK"> |
||||||
|
020 Gradient_08</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
和其他渐变用一样,可以指定渐变颜色位置、设置多个颜色。可以用这个绘制饼图。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="020 Gradient_09" src="https://codepen.io/AhCola/embed/jOwPbeb?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/jOwPbeb"> |
||||||
|
020 Gradient_09</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
## 四.重复和混合 |
||||||
|
|
||||||
|
每种渐变都有对应的重复类型。分别是`repeating-linear-gradient()`、`repeating-radial-gradient()`和`repeating-conic-gradient()`。它们和非重复渐变类似,接受的参数也相同,区别是它们可以重复模式去填充盒子。 |
||||||
|
|
||||||
|
如果你的渐变没有重复,那么可能是因为你没有设置颜色的区域长度。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
background: repeating-linear-gradient( |
||||||
|
45deg, |
||||||
|
red, |
||||||
|
red 30px, |
||||||
|
white 30px, |
||||||
|
white 60px |
||||||
|
); |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="020 Gradient_10" src="https://codepen.io/AhCola/embed/powJjGb?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/powJjGb"> |
||||||
|
020 Gradient_10</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
## 附:资源 |
||||||
|
|
||||||
|
- [Conic.css](https://www.conic.style/)-旋转渐变的一些模板参考 |
||||||
|
|
||||||
|
- [MDN渐变](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Images/Using_CSS_gradients)-mdn渐变教程 |
||||||
|
|
||||||
|
- [渐变生成器](https://www.colorzilla.com/gradient-editor/) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,197 @@ |
|||||||
|
# 动画 |
||||||
|
|
||||||
|
*动画是可以让你的元素动起来,使网页变得更加有趣的一种方式。本节内容带你看下如何使用CSS给元素添加动画效果。* |
||||||
|
|
||||||
|
|
||||||
|
## 一.帧(keyframe) |
||||||
|
|
||||||
|
帧是一副静止的画面,在大多数动画软件和CSS中,连续的帧组合在一起连续播放就形成了动画。 |
||||||
|
|
||||||
|
请看下面的例子,一个动态球。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="021 Animation_01" src="https://codepen.io/AhCola/embed/QWgbJjY?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/QWgbJjY"> |
||||||
|
021 Animation_01</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
整个动画在两种状态间变化,每轮变化时间为1秒。 |
||||||
|
|
||||||
|
![css动画](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/135.jpg) |
||||||
|
|
||||||
|
这个动画有两个关键控制点:两个状态的起始和终止位置。 |
||||||
|
|
||||||
|
![css动画](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/136.jpg) |
||||||
|
|
||||||
|
### `@keyframes` |
||||||
|
|
||||||
|
知道了什么是帧,有助于你理解`@keyframes`的工作原理。下面是一个拥有两种状态的帧规则。 |
||||||
|
```css |
||||||
|
@keyframes my-animation { |
||||||
|
from { |
||||||
|
transform: translateY(20px); |
||||||
|
} |
||||||
|
to { |
||||||
|
transform: translateY(0px); |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
使用`@keyframes`定义一个帧规则,帧规则的名称为`my-animation`,帧规则的名称是大小写敏感的,定义了帧规则后,可以向使用[函数](http://pengfeixc.com/tutorial/css/function)那样,使用帧规则,函数名即`my-animation`。 |
||||||
|
|
||||||
|
帧规则内的`from`和`to`定义了两种状态,`from`表示动画开始(0%)时的状态帧,`to`表示一轮动画结束(100%)时的状态帧。 |
||||||
|
|
||||||
|
也可以直接通过百分比的形式指定关键帧的位置,在动态球的例子中,帧规则`pulse`如下,它包含了两种状态,开始(0%)时,样式是透明的,在动画一半(50%)的时候,不透明度变成0.4,并且放大了1.4倍。 |
||||||
|
```css |
||||||
|
@keyframes pulse { |
||||||
|
0% { |
||||||
|
opacity: 0; |
||||||
|
} |
||||||
|
50% { |
||||||
|
transform: scale(1.4); |
||||||
|
opacity: 0.4; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
``` |
||||||
|
|
||||||
|
我们只需要定义关键位置时的帧,css会自动为我们生成连续的动画效果。 |
||||||
|
|
||||||
|
## 二.动画属性 |
||||||
|
|
||||||
|
定义帧规则之后,就可以通过动画属性使用定义的帧规则了。 |
||||||
|
|
||||||
|
### `animation-name` |
||||||
|
|
||||||
|
`animation-name`指定要使用的帧规则。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
animation-name: pulse; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### `animation-duration` |
||||||
|
|
||||||
|
`animation-duration`用于设置帧动画的周期,即动画播放一轮的所消耗的时间。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
animation-duration: 10s; |
||||||
|
} |
||||||
|
``` |
||||||
|
`animation-duration`默认值是0秒。0秒并不意味着动画没有播放,而是动画播放的速度太快了,你根本无法看到动画效果。`animation-duration`不能设置负值。 |
||||||
|
|
||||||
|
### `animation-timing-function` |
||||||
|
|
||||||
|
`animation-timing-function`属性定义CSS动画在每一动画周期中执行的节奏。对于关键帧动画来说,`animation-timing-function`作用于一个关键帧周期而非整个动画周期,即从关键帧开始开始,到关键帧结束结束。 |
||||||
|
|
||||||
|
`animation-timing-function`可以设置为这几个值:`linear`、`ease`、`ease-in`、 `ease-out`、`ease-in-out`。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="021 Animation_02" src="https://codepen.io/AhCola/embed/mdwJadv?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/mdwJadv"> |
||||||
|
021 Animation_02</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
- `ease`: 默认值。动画以低速开始,然后加快,在结束前变慢。 |
||||||
|
- `ease-in`: 动画以低速开始。 |
||||||
|
- `ease-out`: 动画以低速结束。 |
||||||
|
- `ease-in-out`: 动画以低速开始和结束,中间速度快。 |
||||||
|
|
||||||
|
还可以通过函数设置动画每个阶段的速度。 |
||||||
|
|
||||||
|
#### `cubic-bezier` |
||||||
|
|
||||||
|
`cubic-bezier`是三次贝塞尔曲线,主要是为`animation`生成速度的函数。它接受四个值,值范围为0-1,`cubic-bezier(x1, y1, x2, y2)`。 |
||||||
|
|
||||||
|
![cubic-bezier](https://cdn.jsdelivr.net/gh/pengfeiw/PengfeiBlog@1.0.0/image/137.jpg) |
||||||
|
|
||||||
|
- p0: 为默认值(0, 0) |
||||||
|
- p1: 需要设置的点(x1, y1) |
||||||
|
- p2: 需要设置的点(x2, y2) |
||||||
|
- p3: 为默认值(1, 1) |
||||||
|
|
||||||
|
通过这四个点,生成图中的三次贝塞尔曲线,以此设置动画的运动速度。 |
||||||
|
|
||||||
|
```css |
||||||
|
.ele { |
||||||
|
animation-timing-function: cubic-bezier(.42, 0, .58, 1); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
推荐一个生成`cubic-bezier`值的网站:[https://cubic-bezier.com/](https://cubic-bezier.com/)。 |
||||||
|
|
||||||
|
#### `steps` |
||||||
|
|
||||||
|
steps语法格式为`steps(number, position)`。`number`表示把动画分成多少段,position表示动画是从时间段的开头连续还是从末尾连续。支持`start`和`end`两个关键字。 |
||||||
|
- `start`: 表示直接开始。 |
||||||
|
- `end`: 默认值,表示戛然而止。 |
||||||
|
|
||||||
|
steps详细解释可以看[这篇文章](https://www.zhangxinxu.com/wordpress/2018/06/css3-animation-steps-step-start-end/)。 |
||||||
|
|
||||||
|
### `animation-iteration-count` |
||||||
|
|
||||||
|
`animation-iteration-count`表示动画执行的次数,默认值为1, 接受一个整数值,也可以指定`infinite`关键字表示重复执行。 |
||||||
|
```css |
||||||
|
.ele { |
||||||
|
animation-iteration-count: infinite; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### `animation-direction` |
||||||
|
|
||||||
|
`animation-direction`控制动画执行的方向。接受以下几个值。 |
||||||
|
|
||||||
|
- `normal`: 默认值,向前运动。 |
||||||
|
- `reverse`: 向后运动,与`normal`相反。 |
||||||
|
- `alternate`: 动画交替反向运行,反向运行时,动画按步后退。过程为前-后-前重复运动。 |
||||||
|
- `alternate-reverse`: 交替运行,与`alternate`相反。过程为后-前-后重复运动。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="021 Animation_03" src="https://codepen.io/AhCola/embed/dyRowqL?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/dyRowqL"> |
||||||
|
021 Animation_03</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `animation-delay` |
||||||
|
|
||||||
|
`animation-delay`将动画延迟执行。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
animation-delay: 5s; |
||||||
|
} |
||||||
|
``` |
||||||
|
上面的代码将动画延迟5s执行。 |
||||||
|
|
||||||
|
### `animation-play-state` |
||||||
|
|
||||||
|
表示动画是否暂停或者运行,默认值为`running`,设置`paused`可以控制动画暂停。例如鼠标悬浮时,动画暂停。 |
||||||
|
```css |
||||||
|
.my-element:hover { |
||||||
|
animation-play-state: paused; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
### `animation-fill-mode` |
||||||
|
|
||||||
|
控制动画执行完成后,元素所在的位置。接受`none | forwards | backwards | both`作为值。 |
||||||
|
- `none`: 不改变默认行为。 |
||||||
|
- `forwards`: 当动画完成后,保持最后一个属性值(在最后一个关键帧中定义)。 |
||||||
|
- `backwards`: 在 animation-delay 所指定的一段时间内,在动画显示之前,应用开始属性值(在第一个关键帧中定义)。 |
||||||
|
- `both`: 向前和向后填充模式都被应用。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="021 Animation_04" src="https://codepen.io/AhCola/embed/QWgbzog?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/QWgbzog"> |
||||||
|
021 Animation_04</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `animation`关键字 |
||||||
|
|
||||||
|
`animation`是以下属性按顺序简写的形式。 |
||||||
|
1. animation-name |
||||||
|
2. animation-duration |
||||||
|
3. animation-timing-function |
||||||
|
4. animation-delay |
||||||
|
5. animation-iteration-count |
||||||
|
6. animation-direction |
||||||
|
7. animation-fill-mode |
||||||
|
8. animation-play-state |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,138 @@ |
|||||||
|
# css filter属性详解 |
||||||
|
|
||||||
|
最近琢磨着把网站主题色更改一下,看到了一篇文章[Dark Mode in One Line of Code](https://davidwalsh.name/dark-mode-invert-filter),作者讲述了如何用一句代码将网站主题色更改成相反色,这样网站就可以拥有有白天模式和黑夜模式了。 |
||||||
|
```css |
||||||
|
html { |
||||||
|
filter: invert(1); |
||||||
|
} |
||||||
|
``` |
||||||
|
使用上面的代码,可以很方便的将页面颜色反转,达到黑夜模式的效果。但是我并不推荐以这种方式去给网站增加黑夜模式,因为这句代码会将页面中的图片的像素颜色也进行反转,所以效果并不是很好。 |
||||||
|
|
||||||
|
但是filter属性的确很强大,所以我就在这里介绍一下这个属性。 |
||||||
|
|
||||||
|
## 一.语法 |
||||||
|
|
||||||
|
[MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/filter)中是这样描述的: |
||||||
|
|
||||||
|
> The `filter` CSS property applies graphical effects like blur or color shift to an element. Filters are commonly used to adjust the rendering of images, backgrounds, and borders. |
||||||
|
|
||||||
|
翻译过来就是,`filter`属性可以为元素添加模糊或颜色偏移等图形效果。一般用来调整图片、背景和边框的渲染。 |
||||||
|
|
||||||
|
具体语法如下: |
||||||
|
```css |
||||||
|
filter: <filter-function> [<filter-function>]* | none |
||||||
|
``` |
||||||
|
filter函数有:`grayscale`、`blur`、`sepia`、`saturate`、`opacity`、`brightness`、`contrast`、`hue-rotate`和`invert`。大部分函数的参数范围为0-1数字之间,其中`blur`函数参数为任意数字后接`px`单位,`hue-rotate`函数参数为一个整数后接`deg`单位。 |
||||||
|
|
||||||
|
## 二.filter函数 |
||||||
|
|
||||||
|
### grayscale |
||||||
|
|
||||||
|
`grayscale`用于调整元素的灰度值。参数范围为0-1,0表示无效果,1表示灰度最大。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="css filter: grayscale" src="https://codepen.io/AhCola/embed/XWRxMew?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/XWRxMew"> |
||||||
|
css filter: grayscale</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
第一张图片`filter: grayscale(1)`。 |
||||||
|
|
||||||
|
### blur |
||||||
|
|
||||||
|
`blue`用于调整图片模糊度的。参数为大于0的数字,后接`px`单位。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="css filter: blur" src="https://codepen.io/AhCola/embed/BaRqWJm?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/BaRqWJm"> |
||||||
|
css filter: blur</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
第一张图片`filter: blur(5px)`。 |
||||||
|
|
||||||
|
### sepia |
||||||
|
|
||||||
|
`sepia`用于调整元素的褐色程度。参数范围为0-1。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="css filter: sepia" src="https://codepen.io/AhCola/embed/vYmVxRg?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/vYmVxRg"> |
||||||
|
css filter: sepia</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
第一张图片`filter: sepia(1)`。 |
||||||
|
|
||||||
|
### saturate |
||||||
|
|
||||||
|
调整元素的饱和度。参数范围为0-1。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="css filter: saturate" src="https://codepen.io/AhCola/embed/ExmdWLY?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/ExmdWLY"> |
||||||
|
css filter: saturate</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
第一张图片`filter: saturate(0)`,第二张图片`filter: saturate(1)`,饱和度为0与灰度值为1效果类似。 |
||||||
|
|
||||||
|
### opacity |
||||||
|
|
||||||
|
调整元素的透明度。参数范围为0-1,0表示完全透明,1表示完全不透明。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="css filter: opacity" src="https://codepen.io/AhCola/embed/eYWPvKa?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/eYWPvKa"> |
||||||
|
css filter: opacity</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
第一张图片`filter: opacity(0.2)`,第二张图片`filter: opacity(1)`。css也有一个[opacity](https://developer.mozilla.org/zh-CN/docs/Web/CSS/opacity)属性可以调整元素透明度,用法一样。 |
||||||
|
|
||||||
|
### brightness |
||||||
|
|
||||||
|
`brightness`用于调整元素的亮度。范围为0-1,0表示全黑,1表示最亮。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="css filter: brightness" src="https://codepen.io/AhCola/embed/MWmPpqR?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/MWmPpqR"> |
||||||
|
css filter: brightness</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
第一张图片`filter: brightness(0)`,显示为黑色。 |
||||||
|
|
||||||
|
### contrast |
||||||
|
|
||||||
|
调整元素的对比度。默认值为1,表示与原图一致,取值小于1时,对比度降低,取值大于1时表示对比度增大。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="css filter: contrast" src="https://codepen.io/AhCola/embed/qBmJrQZ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/qBmJrQZ"> |
||||||
|
css filter: contrast</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
图片一`filter: contrast(0.2)`,图片二`filter: contrast(3)`,图片三为默认值1。 |
||||||
|
|
||||||
|
### hue-rotate |
||||||
|
|
||||||
|
色相旋转,取值为角度值,单位为`deg`。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="css filter: hue-rotate" src="https://codepen.io/AhCola/embed/wvdYJRj?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/wvdYJRj"> |
||||||
|
css filter: hue-rotate</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
第一张图片`filter: hue-rotate(40deg)`。 |
||||||
|
|
||||||
|
### invert |
||||||
|
|
||||||
|
将元素的颜色反转。参数范围为0-1,默认值为0。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="css filter: invert" src="https://codepen.io/AhCola/embed/ExmdWJj?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/ExmdWJj"> |
||||||
|
css filter: invert</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
第一张图片`filter: invert(1)`。 |
||||||
|
|
||||||
|
|
||||||
|
(完) |
@ -0,0 +1,266 @@ |
|||||||
|
# 混合模式 |
||||||
|
|
||||||
|
*混合模式可以将多个图层混合在一起,创建混合的视觉效果。* |
||||||
|
|
||||||
|
混合模式,我在这之前从来没用过。开发一般的网页真的很少会用到混合模式,因为稍微复杂的图片或者页面,都是通过UI设计图片,然后直接添加到网页上,这样开发速度会更快。 |
||||||
|
|
||||||
|
但是为了教程的完整性,还是在这里做个介绍。 |
||||||
|
|
||||||
|
[Duotone](https://en.wikipedia.org/wiki/Duotone),中文是双色调的意思,一种很流行的设计风格,整个图片主要由两种颜色组成:一个是亮色,一个是暗色。使用css混合可以实现这种双色调风格。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="" src="https://codepen.io/AhCola/embed/oNwjEqg?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/oNwjEqg"> |
||||||
|
</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
使用混合模式、fiter属性和伪元素,可以很方便将双色调风格应用于图片上。 |
||||||
|
|
||||||
|
## 一.混合模式(Blend Model) |
||||||
|
|
||||||
|
设计软件,例如photoshop,会经常用到混合模式,它们使用图层功能,将多种颜色混合在一起。可以通过控制颜色混合的方式,创建非常有趣的视觉效果。 |
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_02" src="https://codepen.io/AhCola/embed/powjaZZ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/powjaZZ"> |
||||||
|
023 Blending_Model_02</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
上面使用了`mix-blend-mode`将混合效果应用于整个元素,还可以使用`background-blend-mode`仅使元素的背景色混合。 |
||||||
|
|
||||||
|
如果一个元素拥有多个背景图,可以使用`background-blend-mode`使背景图彼此混合。 |
||||||
|
```css |
||||||
|
.demo { |
||||||
|
max-width: 400px; |
||||||
|
height: 400px; |
||||||
|
position: relative; |
||||||
|
background: url(https://source.unsplash.com/YJOuS1GZbDQ/600x400), |
||||||
|
url(https://source.unsplash.com/V7oLFRVqeHM/600x400), |
||||||
|
url(https://source.unsplash.com/_wWjQr1JZ1k/600X400); |
||||||
|
background-size: cover; |
||||||
|
background-blend-mode: overlay; |
||||||
|
} |
||||||
|
``` |
||||||
|
混合模式分为两类:可分离的和不可分离的。分离的混合模式将RGB单独考虑,不可分离的混合模式,统一考虑所有颜色组成。 |
||||||
|
|
||||||
|
## 二.可分离的混合模式 |
||||||
|
|
||||||
|
### `normal` |
||||||
|
|
||||||
|
`normal`是混合模式的默认值。不会改变元素的混合效果。 |
||||||
|
|
||||||
|
### `multiply` |
||||||
|
|
||||||
|
`multiply`混合模式就像是将多个透明图层叠加在一起。白色像素将会显示为透明色,而黑色像素将会显示为黑色。白色和黑色之间的颜色的像素将会乘以它的亮度值。这意味着亮的颜色会越亮,而暗的颜色会变暗,`multiply`一般会生成一个偏暗的效果。 |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_03" src="https://codepen.io/AhCola/embed/xxrwYBx?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/xxrwYBx"> |
||||||
|
023 Blending_Model_03</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `screen` |
||||||
|
|
||||||
|
`screen`往往会创建与`multiply`相反的偏亮的效果。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: screen; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_04" src="https://codepen.io/AhCola/embed/LYLpQvp?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/LYLpQvp"> |
||||||
|
023 Blending_Model_04</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `overlay` |
||||||
|
|
||||||
|
`overlay`介于`multiply`和`screen`之间,它组合了`multiply`和`screen`效果,暗色变暗,亮色变亮,介于暗亮之间的颜色,例如50%的灰色将不会受影响。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: overlay; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_05" src="https://codepen.io/AhCola/embed/jOwbZRp?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/jOwbZRp"> |
||||||
|
023 Blending_Model_05</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `darken ` |
||||||
|
|
||||||
|
`darken`在混合两种颜色的时,会分别比较两个颜色的RGB分量,取RGB值比较暗的(小值),生成新的RGB。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: darken; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_06" src="https://codepen.io/AhCola/embed/YzQyebp?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/YzQyebp"> |
||||||
|
023 Blending_Model_06</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `lighten ` |
||||||
|
|
||||||
|
`lighten`与`darken`类似,不过比较时,分别取RGB中较量的分量,生成新的RGB。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: lighten; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_07" src="https://codepen.io/AhCola/embed/powjamQ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/powjamQ"> |
||||||
|
023 Blending_Model_07</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `color-dodge` |
||||||
|
|
||||||
|
`color-dodge`会使背景色变亮,衬托前景色。 |
||||||
|
|
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: color-dodge; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_08" src="https://codepen.io/AhCola/embed/LYLpQKG?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/LYLpQKG"> |
||||||
|
023 Blending_Model_08</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `color-burn` |
||||||
|
|
||||||
|
`color-burn`会增加对比度,形成更饱和的中间色,减少高光。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: color-burn; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_08" src="https://codepen.io/AhCola/embed/NWgGyZM?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/NWgGyZM"> |
||||||
|
023 Blending_Model_08</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `hard-light` |
||||||
|
|
||||||
|
`hard-light`会创建一个相反的效果。这个模式要么会形成`multiply`的效果,要么形成`screen`效果,当像素亮度低于50% gray时,使用multiply效果,亮度大于50% gray时,使用screen效果。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: hard-light; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_09" src="https://codepen.io/AhCola/embed/ZEybrgZ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/ZEybrgZ"> |
||||||
|
023 Blending_Model_09</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `soft-light` |
||||||
|
|
||||||
|
`soft-light`是`overlay`的柔和版本,效果差不多,但是亮与暗的反差减小。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: soft-light; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_10" src="https://codepen.io/AhCola/embed/WNOQzeK?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/WNOQzeK"> |
||||||
|
023 Blending_Model_10</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `difference` |
||||||
|
|
||||||
|
`difference`混合两种颜色时,使用的是差值法,如果两个元素的RGB完全相同,差值为0,最后形成的颜色就是黑色。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: difference; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_11" src="https://codepen.io/AhCola/embed/RwgWMwV?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/RwgWMwV"> |
||||||
|
023 Blending_Model_11</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `exclusion ` |
||||||
|
|
||||||
|
`exclusion `与`difference`非常像。但是当两个像素相同时,它会生成50%的gray,而不是黑色,这样会生成一个相对柔和的结果。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: exclusion; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_12" src="https://codepen.io/AhCola/embed/MWoaVWx?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/MWoaVWx"> |
||||||
|
023 Blending_Model_12</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
## 三.不可分离的混合模式 |
||||||
|
|
||||||
|
你可以认为这种混合模式与HSL颜色结构类似。 |
||||||
|
|
||||||
|
### `hue` |
||||||
|
|
||||||
|
`hue`将源色的色度值和背景色的饱和度和亮度值结合,形成新的颜色。 |
||||||
|
|
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: hue; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_13" src="https://codepen.io/AhCola/embed/zYzvWGY?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/zYzvWGY"> |
||||||
|
023 Blending_Model_13</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `saturation ` |
||||||
|
|
||||||
|
`saturation`将源色的饱和度值和背景色的色度值和亮度值结合,形成新的颜色。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: saturation; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_14" src="https://codepen.io/AhCola/embed/OJgyvVQ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/OJgyvVQ"> |
||||||
|
023 Blending_Model_14</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `color` |
||||||
|
|
||||||
|
`color`将源色的饱和度和色度值与背景色的亮度混合形成新的颜色。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: color; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_15" src="https://codepen.io/AhCola/embed/BaZoror?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/BaZoror"> |
||||||
|
023 Blending_Model_15</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
### `Luminosity` |
||||||
|
|
||||||
|
`Luminosity`与`color`相反,将原色的亮度值与背景色的饱和度和色度混合。 |
||||||
|
```css |
||||||
|
.my-element { |
||||||
|
mix-blend-mode: luminosity; |
||||||
|
} |
||||||
|
``` |
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="023 Blending_Model_16" src="https://codepen.io/AhCola/embed/oNwjqbz?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> |
||||||
|
See the Pen <a href="https://codepen.io/AhCola/pen/oNwjqbz"> |
||||||
|
023 Blending_Model_16</a> by Pengfei Wang (<a href="https://codepen.io/AhCola">@AhCola</a>) |
||||||
|
on <a href="https://codepen.io">CodePen</a>. |
||||||
|
</iframe> |
||||||
|
|
||||||
|
## 四.`isolation` |
||||||
|
|
||||||
|
设置`isolation: isolate;`可以创建一个新的栈空间,这可以防止它与背景图层混合。但是这个对`background-blend-mode`无效。 |
||||||
|
|
||||||
|
(完) |
Loading…
Reference in new issue