TIP
虽然此前已经无数次尝试接触前端项目,却从未认真学习 CSS 等前端知识,导致连个样式都不会添加,因此最近下定决心(但愿)抽空系统地学习下前端的知识~
# CSS 基础
# 选择器
- 元素选择器 用元素名标记,如
p
- class 选择器 用
.<class>
来标记,如.cat
- id 选择器 用
#<id>
来标记,如#cat
(优先级更高) - 属性选择器 用
[<attr>=‘<value>’]
来标记,如[name=‘cat’]
# 文本
- 颜色
color
- 名称方式,如
red
- 十六进制,如
#FF0000
- 十六进制缩写,如
#F00
- rgb(rgba),如
rgb(255, 0, 0)
以及rgba(255, 0, 0, 1)
- hsl(hsla),如
hsl(0, 100, 50)
以及rgba(0, 100, 50, 1)
- 名称方式,如
- 字体
font-family
- 字体大小
font-size
# 图片
- 大小(
width
和height
)- 绝对单位
- 英寸
in
- 毫米
mm
- 英寸
- 相对单位
- 像素
px
- 百分比
%
- 元素
- 相对于设置了大小的父级元素
em
- 相对于根元素
rem
- 相对于设置了大小的父级元素
- 视窗
- 视窗宽度
vw
- 视窗高度
vh
- 视窗宽高中较小值
vmin
- 视窗宽高中较大值
vmmax
- 视窗宽度
- 像素
- 绝对单位
# 边框
基本用法
.thin-red-border {
border-color: red;
border-width: 5px;
border-style: solid;
}
2
3
4
5
加个圆角 border-radius: 15px
,进一步,设置值为 50%
的话,就是个圆咯~
# 盒模型
- 内容
content
- 内边距
padding
也即边框到内容之间填充的距离 - 边框
border
- 外边距
margin
也即边框到相邻元素或者父容器之间的距离,还可以设置为负值以达到灵活的定位效果~
(内/外)边距的设置
分别设置
div { margin-top: 10px; margin-right: 20px; margin-bottom: 30px; margin-left: 40px; }
1
2
3
4
5
6按照顺时针设置
写 1 个自然四周都一样
写 4 个将会按顺时针(上右下左)来分配
div { margin: 10px 20px 30px 40px; }
1
2
3写 2 个分别表示上下和左右
写 3 个分别表示上、左右、下
# 样式优先级
- important 声明
- 内联样式
- ID 选择器
- Class 选择器
- 继承样式
# 变量
.theme {
/* 该类的元素才可以使用,为了保证变量全局有效,
常在 :root 下创建全局变量 */
--accent-color: #3eaf7c;
}
.logo {
background-color: var(--accent-color);
}
2
3
4
5
6
7
8
# 应用视觉设计
文本对齐方式
text-align
宽度高度调整
width
和height
文本修饰
- 加粗
strong
- 下划线
u
(underline) - 强调
em
(emphasis) - 删除线
s
(strikethrough)
- 加粗
水平线
hr
元素阴影
box-shadow
offset-x
水平偏移量offset-y
竖直偏移量blur-radius
模糊半径spread-radius
延伸半径- 颜色
透明度
opactiy
悬停伪类
:hover
定位
position
,具体类型如下- 相对定位
relative
,相对于该元素原本的位置,其占位空间并不会变 - 绝对定位
absolute
,相对于最近的已定位父级元素,元素从文档流移除,不再占位 - 固定定位
fixed
,不随文档流滚动 - 粘性定位
sticky
,未超过阈值为relative
,当超过阈值后,转变为fixed
它们都使用额外的属性
top
等四属性描述位置- 相对定位
浮动
float
,值为left
或right
,此时内容不再是沿着文档流自上而下排列,而是优先自左向右(或反之)排列,最后不要忘记在容器上加上清除浮动,以免对外部元素造成影响线性渐变
linear-gradient()
background: linear-gradient(方向, 颜色 1, 颜色 2, 颜色 3, ...);
,如background: linear-gradient(90deg, red, yellow, rgb(204, 204, 255));
repeating-linear-gradient()
变换
transform
- 放缩
transform: scale(2);
即可放大两倍 - 倾斜
transform: skewX(-32deg)
即沿 x 轴翻转 -32 度
- 放缩
:before
和:after
伪类,记得要设置content
属性,即便为空字符串动画(在元素上设置
animation-name
等属性,并设定各个关键帧)#anim { animation-name: colorful; animation-duration: 3s; animation-iteration-count: infinite; animation-timing-function: cubic-bezier(0, 0, 0.58, 1); } @keyframes colorful { 0% { background-color: blue; } 100% { background-color: yellow; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 响应式设计
# 媒体查询
img {
width: 100px;
}
@media (min-width: 500px) {
img {
width: 300px;
}
}
@media (min-width: 300px) {
img {
width: 200px;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 自适应大小
img {
max-width: 100%;
display: block;
height: auto;
}
2
3
4
5
# 使用相对视窗大小单位(vw
等)
img {
width: 80vw;
}
2
3
# 弹性盒子布局
# 容器属性
想要使用弹性布局很简单,只需要修改 display
属性即可
#box-container {
display: flex;
}
2
3
当然,我们是将一个容器设为了一个弹性盒子,这样其中的各个元素就能乖乖按照我们的设计来啦
但是布局必然需要方向,这只需要设定 flex-direction
即可,比如 row
和 column
,如果想反着来,就加个 reverse
#box-container {
display: flex;
flex-direction: column-reverse;
}
2
3
4
但是各个元素要如何排列?居中还是分开在两端呢?
#box-container {
display: flex;
justify-content: center;
}
2
3
4
还有其余可选值
flex-start
都挤在开始那一侧flex-end
与上面相反space-between
分散排列,中间留空隙,两侧不留space-around
两侧也留空隙
另外,与排列方向的垂直方向也没有指定具体的方式
#box-container {
display: flex;
align-items: center;
}
2
3
4
此外还有
flex-start
flex-end
stretch
充满baseline
基线对齐
当然每个元素也可以单独设置该属性,属性名为
align-self
,可选值同上
如果所有元素都挤在一行并不利于响应式变换,如果当屏幕变小时可以自动换行就好了
#box-container {
display: flex;
flex-wrap: wrap;
}
2
3
4
另外,默认值是 nowrap
不换行,此外还可以使用 wrap-reverse
反序排列换行
# 子元素属性
至今为止都是设定的容器元素的属性,这样子元素的“个性”还没有彰显,那么子元素有什么特性呢?比如在容器收缩的时候,可以设定两者各自的收缩比,反之在容器拉伸时,可以设定两者各自的生长比,另外还可以设定在伸缩之前的初始大小
#box-container {
display: flex;
}
#box-1 {
flex-grow: 2;
flex-shrink: 2;
flex-basis: 150px;
}
#box-2 {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 150px;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
还可以将这三个属性简写在一起
#box-container {
display: flex;
}
#box-1 {
flex: 2 2 150px;
}
#box-2 {
flex: 1 1 150px;
}
2
3
4
5
6
7
8
9
10
11
此外,我们还可以通过 order
属性自由地调整各个元素的顺序
#box-container {
display: flex;
}
#box-1 {
order: 2;
}
#box-2 {
order: 1;
}
2
3
4
5
6
7
8
9
10
11
# 网格布局
# 容器属性
与弹性盒子布局一样,只需要将容器的 display
属性修改即可启用该布局模式
#grid-container {
display: grid;
}
2
3
而一个网格,应当明确其行数、列数以及行宽、列宽
#grid-container {
display: grid;
grid-template-rows: auto 50px 10% 2fr 1fr;
grid-template-columns: 50px 50px;
}
2
3
4
5
这将创建 5 行 2 列的网格容器,两列都是 50px,而五行分别占据
- auto 自动等于其内容的高度
- 50px
- 10% 容器高度
- 剩余高度的 2/3
- 剩余高度的 1/3
此外还可以通过 minmax
函数来限制项目的大小
#grid-container {
display: grid;
grid-template-columns: 100px minmax(50px, 200px);
}
2
3
4
这样第二列的宽度就被限制在 50px
和 200px
之间了
如果要创建的列数太多,也可以通过 repeat
函数来解决
#grid-container {
display: grid;
grid-template-columns: repeat(2, 1fr 50px) 20px;
/* 等同于下面这个 */
grid-template-columns: 1fr 50px 1fr 50px 20px;
}
2
3
4
5
6
如果不想明确指定行数或者列数以达到弹性布局的效果,也是可以的
#grid-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
}
2
3
4
但是这样在容器的大小大于各网格项之和时,会在一端持续放入空行或空列,只需稍稍调整就可以解决该问题
#grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));
}
2
3
4
另外,各个各自之间的间距也应当明确指定
#grid-container {
display: grid;
grid-template-rows: repeat(3, 20px);
grid-template-columns: repeat(3, 20px);
grid-row-gap: 5px;
grid-column-gap: 10px;
}
2
3
4
5
6
7
当然也可以一起指定
#grid-container {
display: grid;
grid-template-rows: repeat(3, 20px);
grid-template-columns: repeat(3, 20px);
grid-gap: 5px 10px;
}
2
3
4
5
6
另外,指定全部元素的对齐方式也很简单
#grid-container {
display: grid;
grid-template-rows: repeat(4, 20px);
grid-template-columns: repeat(4, 20px);
justify-items: center;
align-items: center;
}
2
3
4
5
6
7
当然元素也可以分别指定,使用属性
justify-self
和align-self
# 子元素属性
当然,各个元素的个性我们还没有提
如果一个元素比较蛮横,想要占据两个或者更多格子呢?
#grid-container {
display: grid;
grid-template-rows: repeat(3, 20px);
grid-template-columns: repeat(3, 20px);
}
#item5 {
grid-row: 2 / 4;
grid-column: 2 / 4;
}
2
3
4
5
6
7
8
9
10
这样 item5 就顺利占据了 (2, 2)-(4, 4)
这个 2 * 2 的大格子
此外,我们还可以对格子的各个区域进行命名,然后为各个元素分配自己占据的区域
#grid-container {
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
grid-template-areas:
"header header header"
"advert content content"
"footer footer footer";
}
#item1 {
grid-area: header;
}
2
3
4
5
6
7
8
9
10
11
12
13
这样 item1 就成功占据了上面三个格子
我们还可以利用这个特性结合媒体查询创建响应式布局
#grid-container {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 50px auto 1fr auto;
grid-gap: 10px;
grid-template-areas:
"header"
"advert"
"content"
"footer";
}
@media (min-width: 300px) {
#grid-container {
grid-template-columns: auto 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"advert header"
"advert content"
"advert footer";
}
}
@media (min-width: 400px) {
#grid-container {
grid-template-areas:
"header header"
"advert content"
"footer footer";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
最后,grid 是可以嵌套的哦,一个格子也可以成为一个新的容器~
# Sass 预处理器
Sass 是一个 CSS 的预处理器,我们可以在 Sass 里写更加方便的语法(变量、嵌套以及逻辑语句),而 Sass 会帮助我们将这些语法编译为纯 CSS,以供浏览器渲染
# 变量
变量是各种 CSS 预处理器的核心,Sass 的变量使用 $
来标记,定义与使用都远比 CSS 内置的变量方便地多
$text-color: red;
.blog-post,
h2 {
color: $text-color;
}
2
3
4
5
6
# 嵌套
CSS 语法并不支持嵌套结构,这就使得大型项目 CSS 规则需要写很多重复的选择器,Sass 的嵌套语法可以极大简化代码
nav {
background-color: red;
}
nav ul {
list-style: none;
}
nav ul li {
display: inline-block;
}
2
3
4
5
6
7
8
9
10
11
上面的代码用 Sass 来改写只需要
nav {
background-color: red;
ul {
list-style: none;
li {
display: inline-block;
}
}
}
2
3
4
5
6
7
8
9
10
11
# Mixins
Mixin 类似于函数
div {
-webkit-box-shadow: 0px 0px 4px #fff;
-moz-box-shadow: 0px 0px 4px #fff;
-ms-box-shadow: 0px 0px 4px #fff;
box-shadow: 0px 0px 4px #fff;
}
2
3
4
5
6
上面的代码可以简单得替换为下面的代码,当然如果只使用这一次是看不出来优势的,但如果要反复调用其优势不言而喻
@mixin box-shadow($x, $y, $blur, $c) {
-webkit-box-shadow: $x, $y, $blur, $c;
-moz-box-shadow: $x, $y, $blur, $c;
-ms-box-shadow: $x, $y, $blur, $c;
box-shadow: $x, $y, $blur, $c;
}
div {
@include box-shadow(0px, 0px, 4px, #fff);
}
2
3
4
5
6
7
8
9
10
# if / else
简单的示例就可以知道怎么用啦
@mixin text-effect($val) {
@if $val == danger {
color: red;
} @else if $val == alert {
color: yellow;
} @else if $val == success {
color: green;
} @else {
color: black;
}
}
2
3
4
5
6
7
8
9
10
11
# for 循环
理解起来也很容易,注意在选择器中使用变量的方式
@for $i from 1 through 12 {
.col-#{$i} {
width: 100%/12 * $i;
}
}
2
3
4
5
除了 from through
还有 from to
,前者包含最后的数字,后者不包含
# each 循环
for 循环的劣势在于只能遍历数字,而 each 循环可以遍历一个列表
@each $color in blue, red, green {
.#{$color}-text {
color: $color;
}
}
2
3
4
5
也可以将列表单独设为一个变量
$colors: (
color1: blue,
color2: red,
color3: green,
);
@each $key, $color in $colors {
.#{$color}-text {
color: $color;
}
}
2
3
4
5
6
7
8
9
10
11
# while 循环
while 循环也即如我们熟知的那个 while 循环,如果不注意很容易写成死循环
$x: 1;
@while $x< 13 {
.col-#{$x} {
width: 100%/12 * $x;
}
$x: $x + 1;
}
2
3
4
5
6
7
# 样式扩展
如果有一个样式与已存在的某个样式基本相同,可以通过 extend
来复用已经写好的样式
.panel {
background-color: red;
height: 70px;
border: 2px solid green;
}
.big-panel {
@extend .panel;
width: 150px;
font-size: 2em;
}
2
3
4
5
6
7
8
9
10
11