CSS基础

184 阅读36分钟

一、CSS的介绍

层叠样式表Cascading Style Sheets,是一种用来表现HTML(标准通用标记语言的一个应用)XML(标准通用标记语言的一个子集)等文件样式的语言。主要用来设计网页的样式,美化网页,静态或动态的修饰网页元素的样式

1.CSS的引入

行内样式(内联样式)

<h1 style="color:red;"></h1>

直接在HTML标签中的样式

  • 优先级最高(但没有!important高),可以覆盖同一元素的同一样式属性的值
  • 作为标签的属性存在
  • 代码量大,分离度低,较高维护成本,冗余度高

内嵌样式

<style>
    h1 {
        color: red;
    }
</style>

通过<style>标签在HTML文件中使用

  • 读取速度相较于两种导入比较快,同步
  • HTML文件的<head>标签中的<style>标签中

link导入

<link rel="stylesheet" type="text/css" href="mystyle.css">

通过<link>标签的href属性进行导入,也写在HTML文件中的<head>标签中

  • 外部单独创建一个CSS样式表
  • 异步加载,且等到同步任务完成后,再去渲染加载回来的外部样式文件

@import导入

@import url(images/style.css);
  • <style>标签内,或CSS文件中,使用@import url('文件路径')来引入
  • 异步加载,且等到同步任务完成后,再去渲染加载回来的外部样式文件
  • @import语句要放在css顶部,或者说style标签中的顶部

2.CSS文件的字符集

@charset用于定义样式表使用的字符集。必须是样式表中的第一个元素(即在第一行)。若有多个@charset声明,则也只有第一个会被使用。且无法在HTML元素或HTML页面的<style>元素内使用

@charset "UTF-8";

3.CSS的语法

css_01.png

  • 选择器指向需要设置样式的HTML元素
  • 声明都包含一个CSS属性和一个值,以冒号分隔
  • 声明块包含一条或多条用分号分隔的声明,且用{}花括号包裹
p {
    color: red;
    font-size: 14px;
}
  • pCSS中的选择器,指向要设置样式的HTML元素<p>
  • colorfont-size是属性,red14px是属性值
  • color: red;font-size: 14px;是声明
  • {}包裹的是声明块

4.注释

注释用于解释代码

/* 这是一条单行注释 */

/*
    这是一条多行注释
    多行
*/

二、CSS三大特性

1.层叠性

层叠性的出现是为了解决样式冲突,若出现样式冲突(指一个标签指定了相同样式属性的情况),以书写顺序在后的生效

h1 {
    color: red;
    color: blue;
}

最后这个h1呈现的颜色是蓝色

当样式出现冲突,且后面的样式将前面的样式覆盖的情况,这就是CSS的层叠性

2.继承性

继承性是指书写CSS样式表时,子标签会继承父标签的某些样式,在父标签中设置某些样式后,在子标签中就会生效

  • 继承特性可以简化代码,降低CSS样式的复杂性
  • 但若大量使用继承样式,会在判断样式来源时产生误判断

可继承的样式

字体,文本属性等,例如:字体、字号、字体颜色、字间距、行高、宽度

不可继承的样式

边框、边距、背景、定位、高度、浮动等

存在默认继承行为的属性,都是那些不会影响到页面布局的属性

对于其他默认不继承的属性,可通过属性值来控制继承行为

  • inherit:继承父元素对应属性的属性值
  • initial:应用该属性的默认值,比如color的默认值是#000
  • unset:若属性是默认可以继承的,则取inherit的效果,反之则取initial

3.优先级

定义CSS样式时,经常会出现多个规则应用在同一元素上,所以就会出现优先级

注:选择器相同,则执行层叠性。选择器不同,则按优先级

元素权重相同可叠加,但永远不会进一位

元素贡献值
继承、*0, 0, 0, 0
单个标签0, 0, 0, 1
类选择器、伪类/伪元素选择器、属性选择器0, 0, 1, 0
ID选择器0, 1, 0, 0
行内样式1, 0, 0, 0
!important无穷大
max-widthmax-height覆盖widthheight大于无穷大
min-widthmin-height大于max-widthmax-height

权重由高到底排序:min-width/min-height > max-width/max-height > !important > 行内样式 > ID选择器 > 类选择器、属性选择器、伪类/伪元素选择器 > 标签选择器 > 通用符*选择器 > 继承样式

!important

在按原则上没有max-width/max-heightmin-width/min-height的出现时,!important的权重是最高的,所以要谨慎使用!important

  • 一定要优先考虑使用样式规则的优先级来解决问题,而不是直接使用!important
  • 只有在需要覆盖全站的CSS中使用!important
  • 不在插件中使用!important
  • 不在全局CSS代码中使用!important

三、盒模型

在CSS中任何元素都可以看成是一个盒子,而一个盒子是有四个部分组成:内容content、内边距padding、边框border和外边距margin

css_02_01.png

盒模型有两种:标准盒模型和IE盒模型。分别有W3CIExplore制定的标准

.box {
    width: 200px;
    height: 200px;
    padding: 20px;
    border: 1px solid #000;
    margin: 20px;
}

标准盒模型

css_02.png

标准盒模型的实际尺寸:内容(设置的宽/高) + 内边距 + 边框

.box元素的内容宽度为200px,而实际的宽度则为width + padding-left + padding-right + border-left-width + border-right-width = 242px

IE盒模型

css_03.png

IE盒模型的实际尺寸:内容(设置的宽/高 + 内边距 + 边框)

.box元素实际尺寸为200px,而内容的真实宽度则为width - padding-left -padding-right - border-left-width - border-right-width = 158px

box-sizing

可通过CSS3中的属性box-sizing,指定盒子使用标准盒模型规则还是IE盒模型规则

box-sizing: content-box(标准盒模型) | border-box(IE盒模型);

四、选择器

1.基础选择器

  • 标签选择器:h1
  • 类选择器:.box,可有多个类名
  • id选择器:#box,id名有且只有一个
  • 通配符选择器:*,选取页面中的所有元素(常用于标签默认样式的清除)
<h1>123</h1>
<div class="box head">456</div>
<div id="box">789</div>
* {
    color: pink;
}
h1 {
    color: red;
}
.box {
    color: blue;
}
.head {
    font-size: 24px;
}
#box {
    color: orange;
}

2.属性选择器

属性选择器可单独使用,也可跟其他基础选择器一起使用

  • [attr]:指定属性的元素
  • [attr = val]:属性等于指定值的元素
  • [attr *= val]:属性包含指定值的元素
  • [attr ^= val]:属性以指定值开头的元素
  • [attr $= val]:属性以指定值结尾的元素
  • [attr ~= val]:属性包含指定值(完整单词)的元素
  • [attr |= val]:属性以指定值(完整单词)开头的元素
<div class="box" name="1name1">1</div>
<div class="box" name="2name2">2</div>
<div class="box" name="3name3">3</div>
<div class="box" name="4name4">4</div>
<div class="box" name="5name5">5</div>
<div class="box" name="6name6">6</div>
<div class="box" name="7name7">7</div>
<div class="box" name="8name8">8</div>
.box[name] {
    color: red;
}

.box[name = '1name1'] {
    color: blue;
}

.box[name *= "2"] {
    color: orange;
}

.box[name ^= "3"] {
    color: pink;
}

.box[name $= "4"] {
    color: skyblue;
}

.box[name ~= "5"] { /* 不生效 */
    color: yellowgreen;
}

.box[name ~= "6name6"] { /* 生效 */
    color: yellowgreen;
}

.box[name |= "7"] { /* 不生效 */
    color: antiquewhite;
}

.box[name |= "8name8"] { /* 生效 */
    color: antiquewhite;
}

css_04.png

[attr ~= val][attr |= val]

[title ~= "flower"] {}

该属性选择器可匹配title="flower"title="summer flower"title="flower new"。但不匹配title="my-flower"title="flowers"

[class |= "top"] {}

值必须是完整或单独的单词,比如class="top"class="top-text",但class="top_text"不匹配,因为使用下划线,就会被当成是一个整体

3.组合选择器

  • 相邻兄弟选择器:A + B

  • 普通兄弟选择器:A ~ B

  • 子选择器:A > B

  • 后代选择器:A B

    选中的都是B元素

  • 并集选择器:A, B

<div class="main">
    <div class="box1">1</div>
    <div class="box2">2</div>
    <div class="box3">3</div>
    <div class="box4">4</div>
    <div class="box5">5</div>
    <div class="box6">6</div>
    <div class="box7">7</div>
</div>
.box1 + .box2 {
    color: red;
}

.box1 + .box3 { /* 不生效 */
    color: blue;
}

.box1 ~ .box3 {
    color: pink;
}

.main > .box4 {
    color: orange;
}

.main .box5 {
    color: skyblue;
}

.box6, 
.box7 {
    color: blueviolet;
}

css_05.png

4.伪类/伪元素选择器

4.1、伪类选择器

条件伪类

  • :lang():基于元素语言来匹配页面元素
  • :dir():匹配特定文字书写方向的元素
  • :has():匹配包含指定元素的元素
  • :is():匹配指定选择器列表里的元素
  • :not(selector):选择每个非selector的元素,例:not(p),选择非p标签的元素

行为伪类

  • :active:鼠标激活的元素
  • :hover:鼠标悬浮的元素

状态伪类

  • :target:当前锚点的元素
  • :link:未访问的链接元素
  • :visited:已访问的链接元素
  • :focus:输入聚焦的表单元素
  • :required:输入必填的表单元素
  • :valid:输入合法的表单元素
  • :invalid:输入非法的表单元素
  • :in-range:输入范围以内的表单元素
  • :out-of-range:输入范围以外的表单元素
  • :checked:选项选中的表单元素
  • :optional:选项可选的表单元素
  • :enabled:可用的表单元素
  • :disabled:禁用的表单元素
  • :read-only:只读的表单元素
  • :read-write:可读可写的表单元素
  • :blank:输入为空的表单元素
  • :current():浏览中的元素
  • :past():已浏览的元素
  • :future():未浏览的元素

结构伪类(重点)

  • :root:文档的根元素
  • :empty:无子元素的元素
  • :nth-child(n):该元素的父元素的第n个子元素,顺序
  • :nth-last-child(n):该元素的父元素的第n个子元素,逆序
  • :first-child:该元素的父元素的第一个子元素,且为该元素
  • :last-child:该元素的父元素的最后一个子元素,且为该元素
  • :only-child:该元素的父元素中有且只有一个元素,且为该元素
  • :nth-of-type(n):该元素的父元素中的第n个该元素,顺序
  • :nth-last-of-type(n):该元素的父元素中的第n个该元素,逆序
  • :first-of-type:该元素的父元素中的第一个该元素
  • :last-of-type:该元素的父元素中的最后一个该元素
  • :only-of-type:该元素的父元素中只有一个该元素,该父元素可有多个元素,但不能有多个该元素

a标签的伪类

  • :link:为访问的链接元素
  • :visited:已访问的链接元素
  • :hover:鼠标悬停元素
  • :active:已选择的链接

注:a:hover必须在CSS定义中的a:linka:visited之后,才能生效。a:active必须在a:hover之后。

4.2、伪元素选择器

  • ::before:在元素前插入内容
  • ::after:在元素后插入内容
  • ::placeholder:选中input元素的提示内容placeholder
  • ::first-letter:选中元素的首个字符
  • ::first-line:选中元素的首行
  • ::selection:选中用户已选取的元素(鼠标拖动选中)

4.3、伪元素和伪类的区别

伪元素:在内容元素的前后插入额外的元素或样式,但是这些元素实际上并不在文档中生成。它们只会在外部显示可见,但不会在文档的源代码中找到它们,因此,称为伪元素

伪类:将特殊的效果添加到特定选择器上,它是已有元素上添加类别的,不会产生新的元素

五、文档流

CSS中,会把内容按照从左到右、从上到下的顺序进行排列显示。正常情况下会把页面分割成一行一行的显示,而每行又可能由多列组成。所以在视觉上看就是从上到下、从左到右,而这就是CSS中的流式布局,又称为文档流。文档流能够自适应所在的容器,它的特性:

  • 块级元素默认会占满整行,所以多个块级盒子之间是从上到下排列的
  • 内联元素默认会在一行里一列一列的排布,当一行放不下,就会自动换行到下一行

脱离文档流

脱离文档流指节点脱离正常文档流后,在正常文档流中的其他节点将忽略该节点并填补其原先空间,文档一旦脱流,计算其父节点高度时不会将其高度纳入,脱流几点不占据空间

浮动定位可以让元素脱离文档流

  • 使用浮动float将元素脱离文档流,移动到容器左/右侧边界或者是另一个浮动元素旁边,该浮动元素之前占用的空间将被别的元素填补,另外浮动之后所占用的区域不会和别的元素之间发生重叠
  • 使用绝对定位position: absolute;或者固定定位position: fixed;也会使得元素脱离文档流,且空出来的位置将自动被后续节点填补

1.回流与重绘

1.1、回流

Render Tree渲染树中部分或全部元素的尺寸、布局、隐藏等改变而需要重新构建,这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一个加载的时候,这时候是一定会发生回流的,因为要构建render tree。在回流的时候,浏览器会使浏览器中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会 重新绘制受影响的部分到屏幕中,该过程称为重绘(repaint)

回流就是计算元素在设备内的确切位置和大小并且重新绘制

回流的代价要远大于重绘,且回流必然会造成重绘,而重绘不一定会造成回流

会导致回流的操作

  • 页面首次渲染(无法避免且开销最大的一次)
  • 浏览器窗口大小发生改变(resize事件)
  • 元素尺寸或位置发生改变(边距、宽高、边框)
  • 元素内容变化(文字数量或图片大小等)
  • 元素字体大小变化(font-size)
  • 添加或删除可见的DOM元素
  • 激活CSS伪类(如:hover)
  • 查询某些属性或调用某些方法

常导致回流的属性和方法

widthheightmarginpaddingdisplayborder-widthborderpositionoverflowfont-sizevertical-alignclientWdithclientHeightclientTopclientLeftoffsetWidthoffsetHeightoffsetTopoffsetLeftscrollWidthscrollHeightscrollTopscrollLeftscrollIntoView()scrollTo()getComputedStyle()getBoundingClientRect()scrollIntoViewIfNeeded()

获取属性或调用方法导致回流

因为以上属性和方法都需要范湖最新的布局信息,因此浏览器不得不触发回流重绘来返回正确的值

1.2、重绘

Render Tree渲染树中元素需要更新样式,但这些样式属性只是改变元素的外观、风格,而不会影响布局,这就称为重绘(repaint)

重绘就是将渲染树节点转换为屏幕上的实际像素,不涉及重新布局阶段的位置与大小计算

常导致重绘的属性

colorborder-styleborder-radiusvisibilitytext-decorationbackgroundbackground-imagebackground-positionbackground-repeatbackground-sizeoutlineoutline-coloroutline-styleoutline-widthbox-shadow

1.3、浏览器对于回流重绘的优化机制

由于每次回流都会造成额外的性能消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化回流的过程,浏览器会将修改操作放入队列里,直到过了一段时间或者操作达到了一个阈值,才会进行批量修改并清空队列

但在获取布局信息的时候,会强制刷新队列

clientWidthclientHeightclientTopclientLeftoffsetWidthoffsetHeightoffsetTopoffsetLeftscrollWidthscrollHeightscrollTopscrollLeftwidthheightgetComputedStyle()getBoundingClientRect()

以上属性和方法都需要返回最新的布局信息,因此浏览器不得不清空队列,触发回流重绘来返回正确的值。因此,我们在修改样式的时候,最好避免使用上面列出的属性,他们都会刷新渲染队列

1.4、如何避免

CSS

  • 避免使用table布局
  • 尽可能在DOM树的末端改变class
  • 避免设置多层内联样式
  • 将动画效果应用到position属性为absolutefixed的元素上
  • 避免使用CSS表达式(如:calc())

JavaScript

  • 避免频繁操作样式,一次性重写style属性,或者将样式列表定义为class并一次性更改class属性
  • 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档
  • 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来
  • 使用display: none,上面我们说到了 (display: none) 将元素从渲染树中完全移除,元素既不可见,也不是布局的组成部分,之后在该DOM上的操作不会触发回流与重绘,操作完之后再将display属性改为显示,只会触发这一次回流与重绘
  • 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流

合并对DOM样式的修改,采用css class来修改

const el = document.querySelector('.box');
el.style.margin = '5px';
el.style.borderRadius = '12px';
el.style.boxShadow = '1px 3px 4px #ccc';

使用css class

// css
.update{
  margin: 5px;
  border-dadius: 12px;
  box-shadow: 1px 3px 4px #ccc
}

const el = document.querySelector('.box');
el.classList.add('update');

批量处理

documentFragment创建dom文档片段

const el = document.querySelector('.box');
const fruits = ['front', 'nanjiu', 'study', 'code'];
const fragment = document.createDocumentFragment();
fruits.forEach(item => {
  const li = document.createElement('li');
  li.innerHTML = item;
  fragment.appendChild(li);
});
el.appendChild(fragment);

克隆节点

const el = document.querySelector('.box');
const fruits = ['front', 'nanjiu', 'study', 'code'];
const cloneEl = el.cloneNode(true);
fruits.forEach(item => {
  const li = document.createElement('li');
  li.innerHTML = item;
  cloneEl.appendChild(li);
});
el.parentElement.replaceChild(cloneEl,el);

2.层叠顺序

css_37.png

  • 背景和边框:建立当前层叠上下文元素的背景和边框
  • 负值的z-index:当前层叠上下文中,z-index属性值为负值的定位元素
  • 块级盒子:文档流内非行内级非定位后代元素
  • 浮动盒子:非定位浮动元素
  • 行内盒子:文档流内行内非定位后代元素
  • z-index = 0:层叠级数为0的定位元素
  • 正值的z-indexz-index属性值为正值的定位元素

六、格式化上下文

格式化上下文Formatting Context是页面中的一块渲染区域,规定了渲染区域内部的子元素是如何排版以及相互作用的

  • BFC(Block Formatting Context)块级格式化上下文
  • IFC(Inlinr Formatting Context)行内格式化上下文
  • FFC(Flex Formatting Context)弹性格式化上下文
  • GFC(Grid Formatting Context)网格格式化上下文

1.BFC块级格式化上下文

块级格式化上下文,是一个独立的渲染区域,只有块级盒子参与,规定了内部的块级盒子如何布局,且这个区域与外部毫不相干

css_06.png

BFC渲染规则

  • 内部的盒子会在垂直方向,一个接一个的放置
  • 盒子垂直方向的距离由margin决定,属于同一个BFC的两个相邻盒子的margin会发生重叠
  • 每个元素的margin的左边,与包含块border的左边相接触(对于从左往右的格式化,则相反),即使存在浮动也是一样
  • BFC的区域不会与float盒子重叠
  • BFC在页面上是一个隔离的独立容器,容器里面的子元素不会影响到外面的元素
  • 计算BFC的高度时,浮动元素也参与计算

如何创建BFC

  • 根元素:<html>
  • 非溢出的可见元素:overflow不为visible
  • 设置浮动:float属性不为none
  • 设置定位:positionabsolutefixed
  • 定义成块级的非块级元素:display: inline-block / table-cell / table-caption / flex / inline-flex / grid / inline-grid

1.1、BFC应用场景

自适应两栏布局

BFC的区域不会和浮动区域重叠,把侧边栏固定宽度且左浮动,而右侧内容触发BFC,使右侧宽度自适应剩余宽度

<div class="main">
    <div class="left"></div>
    <div class="right"></div>
</div>
.main {
    background-color: pink;
    border: 1px solid red;
}

.left {
    float: left;
    width: 100px;
    height: 100px;
    background-color: blue;
}


.right {
    height: 100px;
    overflow: auto;
    background-color: skyblue;
}

清楚内部浮动

浮动造成的问题就是父元素高度塌陷,所以清除浮动就是为了让父元素的高度恢复正常,而BFC清除浮动的原理就是:计算BFC的高度时,浮动元素也参与计算。即只需要触发父元素的BFC即可

.parent {
    overflow: hidden;
}

防止垂直margin合并

BFC渲染原理:同一BFC下的垂直margin会发生合并。所以,若要方式两个元素不发生垂直margin合并,把两个元素放在不同BFC即可

<div class="main">
    <div class="left"></div>
    <div class="head">
        <div class="right"></div>
    </div>
</div>
.main {
    background-color: pink;
    border: 1px solid red;
}

.left {
    width: 100px;
    height: 100px;
    background-color: blue;
    margin: 20px;
}

.head {
    overflow: hidden;
}


.right {
    width: 100px;
    height: 100px;
    background-color: skyblue;
    margin: 20px;
}

css_07.png

2.IFC行内格式化上下文

IFC行内格式化上下文,块级元素中仅包含内联级别元素,当IFC中有块级元素插入时,会产生两个匿名块将父元素分割开来,产生两个IFC

css_08.png

IFC渲染规则

  • 子元素在水平方向上一个接一个排列,在垂直方向上将以容器顶部开始向下排列
  • 元素无法声明宽高,其中marginpadding在水平方向有效在垂直方向无效
  • 元素在垂直方向以不同形式对齐
  • 能把在一行上的框都完全包含进去的一个矩形区域,被称为改行的线盒line box。线盒的宽度是由包含块containing box和与其中的浮动来决定
  • IFC中的line box一般左右边紧贴其包含块,但float元素会优先排列
  • IFC中的line box高度由line-height计算规则来确定,同个IFC下的多个line box高度可能会不同
  • 当内联级盒子的总宽度少于包含它们的line box时,其水平渲染规则由text-align属性值来决定
  • 当一个内联盒子超过父元素的宽度时,它会被分割成多个盒子,这些盒子分布在多个line box中。若子元素未设置强制换行的情况下,line box将不可被分割,将会溢出父元素

IFC应用场景

  • 水平居中:当一个块在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中

七、消除浏览器默认样式

移动端

* { -webkit-tap-highlight-color: transparent; outline: 0; margin: 0; padding: 0; vertical-align: baseline; }
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td { margin: 0; padding: 0; vertical-align: baseline; }
img { border: 0 none; vertical-align: top; }
i, em { font-style: normal; }
ol, ul { list-style: none; }
input, select, button, h1, h2, h3, h4, h5, h6 { font-size: 100%; font-family: inherit; }
table { border-collapse: collapse; border-spacing: 0; }
a { text-decoration: none; color: #666; }
body { margin: 0 auto; min-width: 320px; max-width: 640px; height: 100%; font-size: 14px; font-family: -apple-system,Helvetica,sans-serif; line-height: 1.5; color: #666; -webkit-text-size-adjust: 100% !important; text-size-adjust: 100% !important; }
input[type="text"], textarea { -webkit-appearance: none; -moz-appearance: none; appearance: none; }

PC端

html, body, div, h1, h2, h3, h4, h5, h6, p, dl, dt, dd, ol, ul, li, fieldset, form, label, input, legend, table, caption, tbody, tfoot, thead, tr, th, td, textarea, article, aside, audio, canvas, figure, footer, header, mark, menu, nav, section, time, video { margin: 0; padding: 0; }
h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: normal }
article, aside, dialog, figure, footer, header, hgroup, nav, section, blockquote { display: block; }
ul, ol { list-style: none; }
img { border: 0 none; vertical-align: top; }
blockquote, q { quotes: none; }
blockquote:before, blockquote:after, q:before, q:after { content: none; }
table { border-collapse: collapse; border-spacing: 0; }
strong, em, i { font-style: normal; font-weight: normal; }
ins { text-decoration: underline; }
del { text-decoration: line-through; }
mark { background: none; }
input::-ms-clear { display: none !important; }
body { font: 12px/1.5 \5FAE\8F6F\96C5\9ED1, \5B8B\4F53, "Hiragino Sans GB", STHeiti, "WenQuanYi Micro Hei", "Droid Sans Fallback", SimSun, sans-serif; background: #fff; }
a { text-decoration: none; color: #333; }
a:hover { text-decoration: underline; }

八、值和单位

CSS的声明是由属性和值组成的,而值的类型有很多种

  • 数值:长度值,用于指定如widthborder-widthfont-size等属性的值
  • 百分比:可以用于指定尺寸或长度,如取决于父元素的widthheight或默认的font-size
  • 颜色:用于指定background-colorcolor
  • 坐标位置:以屏幕的左上角为坐标原点定位元素的位置,如background-positiontoprightbottomleft
  • 函数:用于指定资源路径或背景图片的渐变,如url()linear-gradient()

1.单位

1.1、px

屏幕分辨率,指在屏幕的横纵方向上的像素点数量,例如分辨率1920 * 1080意味着水平方向有1920个像素点,垂直方向有1080个像素点。而px表示的就是CSS中的像素,是绝对的长度单位,也是最基础、最常用的单位,其他长度单位会自动被浏览器换算成px

1.2、em

emCSS中的相对长度单位中的一个

  • font-size中使用的是相对于父元素的font-size大小,比如父元素font-size: 16px;,当给子元素指定font-size: 2em;的时候,经过计算后它的字体大小为32px
  • 在其他属性中使用是相对于自身的字体大小,如widthheightpaddingmargin

每个浏览器默认会给HTML根元素<html>设置一个默认的font-size,而这个通常是16px,且em在计算的时候是会层层计算的

<div>
    <p></p>
</div>
div {
    font-size: 2em;
}
p {
    font-size: 2em;
}

由于根元素<html>的默认字体大小为16px,则<p>的字体大小为16 * 2 * 2 = 64px

1.3、rem

remem一样,也是一个相对长度单位,不过rem相对的是HTML的根元素<html>

rem是基于<html>font-size来计算的,所以通常用于自适应网站或移动端中

移动端根据当前页面的视口宽度自动计算根元素<html>font-size基准是多少

待改进

(function (doc, win) {
    var docEl = doc.documentElement,
        resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
        psdWidth = 750,  // 设计图宽度
        recalc = function () {
            var clientWidth = docEl.clientWidth;
            if ( !clientWidth ) return;
            if ( clientWidth >= 640 ) {
                docEl.style.fontSize = 200 * ( 640 / psdWidth ) + 'px';
            } else {
                docEl.style.fontSize = 200 * ( clientWidth / psdWidth ) + 'px';
            }
        };

    if ( !doc.addEventListener ) return;
    // 绑定事件的时候最好配合防抖函数
    win.addEventListener( resizeEvt, debounce(recalc, 1000), false );
    doc.addEventListener( 'DOMContentLoaded', recalc, false );

    function debounce(func, wait) {
        var timeout;
        return function () {
            var context = this;
            var args = arguments;
            clearTimeout(timeout)
            timeout = setTimeout(function(){
                func.apply(context, args)
            }, wait);
        }
    }
})(document, window);

1.4、vw/vh

vwvh分别是相对于屏幕视口宽度和高度而言的长度单位

  • 1vw = 视口宽度均分成100份中1份的长度
  • 1vh = 视口高度均分成100份中1份的长度

100vw = window.innerWidth

100vh = window.innerHeight

2.颜色值

颜色值的类型,可以分为颜色关键字transparent关键字currentColor关键字RGB[A]颜色HSL[A]颜色

2.1、颜色关键字

颜色关键字是不区分大小写的标识符,表示一个具体的颜色,如white(白)黑(black)

在声明的时候,若颜色关键字是错误的,则浏览器会忽略它

完整的色彩关键字列表

css_09.png

2.2、transparent关键字

transparent关键字表示一个完全透明的颜色,从技术来说,它是带有alpha通道为最小值0的黑色,是rgba(0,0,0,0)的简写

三角形

div {
    border-top-color: #ffc107;
    border-right-color: #00bcd4;
    border-bottom-color: #e26b6b;
    border-left-color: #cc7cda;
    border-width: 200px;
    border-style: solid;
}

css_10.png

示例

css_11.png

增大点击区域

在移动端的时候点击的按钮区域特别小,但是由于现实效果不好把它做大,所以通过透明的边框来增大按钮的点击区域

.btn {
    border: 5px solid transparent;
}

2.3、currentColor关键字

currentColor会取当前元素继承父级元素的文本颜色值或声明的文本颜色值,即color的值

.btn {
    color: red;
    border: 1px solid currentColor;
}

2.4、RGB[A]颜色

RGB[A]颜色是由R(red)G(green)B(blue)A(alpha)组成的色彩空间

有两种表现形式:十六进制符号函数符

十六进制符号

RGB中的每种颜色的值范围是00 ~ ff,值越大表示颜色越深。一个颜色正常是6个十六进制字符加上#,如红色#ff0000

RGB颜色需要加上不透明度,则需要加上alpha通道的值,范围也是00 ~ ff,如带不透明度为67%的红色#ff0000aa

使用十六进制符号表示颜色的时候,都是用2个十六进制表示一个颜色,若这2个字符相同,则可以缩减为1个,如红色#f00,带67%的红色#f00a

函数符

RGB用函数表示时,每个值的范围是0 ~ 255或者0% ~ 100%,如红色rgb(255,0,0)rgb(100%,0,0)

若需要使用函数来表示带不透明度的颜色值,值的范围是0 ~ 1以及其之间的小数或0% ~ 100%,如带67%不透明度的红色是rgba(255,0,0,0.67)rgba(100%,0%,0%,67%)

需要注意的是RGB这3个颜色值需要保持一致的写法,要么都是数字要么都是百分比,而不透明度的值可以不跟这三个颜色值一致。如rgb(100%,0,0)这个写法是无效的,而rgba(100%,0%,0%,0.67),且当不透明度的值为小数时,可以省略0,如rgba(255,0,0,0.67),可以写为rgba(255,0,0,.67),还有另外一种写法,把分隔逗号,改成空格,而RGBalpha之间的,该成/,如rgba(255 0 0 / .67)

2.5、HSL[A]颜色

HSL[A]颜色是由色相hue、饱和度saturation、亮度lightness、不透明度alpha组成的颜色体系

  • 色相H是色彩的基本属性,值范围是0 ~ 3600deg ~ 360deg0360为红色,120为绿色,240为蓝色
  • 饱和度S是指色彩的纯度,越高色彩越纯,低则逐渐变灰,取0 ~ 100%的数值,0%为灰色,100%为全色
  • 亮度L,取0 ~ 100%0%为暗,100%为亮
  • 不透明度A,取0 ~ 100%0 ~ 1及之间的小数

给一个按钮设置不透明度为67%红色

button {
    color: #ff0000aa;
    color: #f00a;
    color: rgba(255, 0, 0, 0.67);
    color: rgb(100% 0% 0% / 67%);
    color: hsla(0, 100%, 50%, 67%);
    color: hsl(0deg 100% 50% / 67%);
}

提示:在Chrome DevTools中可以按住shift + 鼠标左键点击颜色值前的色块切换颜色的表示方式

3.函数

  • calc():允许执行计算来确定CSS属性值
  • var():插入自定义属性的值
  • attr():获取所处元素的属性值
  • counter():设置计数器
  • min()、max():从表达式列表中选择最小或最大的值作为属性的值
  • rgb()、rgba()RGB[A]颜色值(上面有详细的说明)
  • hsl()、hsla()HSL[A]颜色值(上面有详细的说明)
  • cubic-bezier():定义三次贝塞尔曲线
  • linear-gradient():线性渐变
  • radial-gradient():径向渐变
  • conic-gradient():圆锥渐变
  • repeating-linear-gradient():重复线性渐变
  • repeating-radial-gradient():重复径向渐变
  • repeating-conic-gradient():重复圆锥渐变

3.1、calc()

.div {
    width: calc(100% - 100px);
}

.div {
    width: 100% - 100px; /* 报错 */
}

calc()函数用于动态计算长度值

  • 需注意,运算符前后都需保留一个空格,如width: calc(100% - 100px);
  • 任何长度值都可以使用calc()函数进行计算
  • calc()函数支持+-*/运算符
  • calc()函数使用标准的数字运算优先级规则

3.2、var()

var()用于插入自定义属性的值,而不是另一个属性的值的任何部分

/* 在根元素下创建自定义属性 */
:root {
  --main-bg-color: red; 
}

#div1 {
  background-color: var(--main-bg-color); 
}

#div2 {
  background-color: var(--main-bg-color);
}

3.3、attr()

attr()获取所处元素的属性值

<a href="https://www.baidu.com">百度一下</a>

a::after{
	content: "(" attr(href) ")"
}

渲染结果为百度一下(https://www.baidu.com)

3.4、counter()

counter():以字符串形式返回当前计数器的值

counter(countername, counterstyle);
  • countername:必须。计数器的名称(与counter-resetcounter-increment属性使用的名称相同)
  • counterstyle:可选的。计数器的样式(list-style-type属性值)
body {
  counter-reset: section;           /* 重置计数器成0 */
}
h3:before {
  counter-increment: section;      /* 增加计数器值 */
  content: "第" counter(section) ": "; /* 显示计数器 */
}
<h1>序号:</h1>
<h3>小明</h3>
<h3>小红</h3>
<h3>小兰</h3>

css_12.png

3.5、min()、max()

max():可以从一个逗号分隔的表达式列表中选择最大的值作为属性的值,接受一个或多个用逗号分隔的表达式作为参数,数值最大的表达式的值将会作为指定属性的值

min():可以从一个逗号分隔的表达式列表中选择最小的值作为属性的值,接受一个或多个用逗号分隔的表达式作为参数,数值最小的表达式的值将会作为指定属性的值

max()

max(value1, value2, ...)

/* 属性: max(expression [, expression]) */
/* 当相对单位vw、em在转换后的值,从中选择最大的值作为width的值 */
width: max(10vw, 4em, 80px);

min()

min(value1, value2, ...)

/* 属性: min(expression [, expression]) */
/* 当相对单位vw、em在转换后的值,从中选择最小的值作为width的值 */
width: min(1vw, 4em, 80px);

3.6、cubic-bezier()

定义一个贝塞尔曲线。它可以实现,ease-in等动画效果,cubic-bezier(.42, 0, 1, 1)的效果等同于ease-in

cubic-bezier功能演示

CSS3动画中easeease-inease-in-outease-out效果区别

css动画值描述
linear规定以相同速度开始至结束的过渡效果(匀速),等同于cubic-bezier(0, 0, 1, 1)
ease规定慢速开始,然后变快,然后慢速结束的过渡效果(相对于匀速,中间快,两头慢),等同于cubic-bezier(0.25, 0.1, 0.25, 1)
ease-in规定以慢速开始的过渡效果(相对于匀速,开始的时候慢,后面快),等同于cubic-bezier(0.42, 0, 1, 0)
ease-out规定以慢速结束的过渡效果(相对于匀速,开始时快,结束时慢),等同于cubic-bezier(0, 0, 0.58, 1)
ease-in-out规定以慢速开始和结束的过渡效果(先归于匀速,开始和结束都慢),等同于(cubic-bezier(0.42, 0, 0.58, 1))
cubic-bezier(n, n, n, n)cubic-bezier函数中定义自己的值,可能的值是0至1之间的数值

3.7、linear-gradient()

linear-gradient()用于创建线性渐变的图像

background-image: linear-gradient(direction, color percentage, color percentage,...);
  • direction:用角度指定渐变的方向(或角度值)
  • color percentage:渐变断点,该值包含一个颜色值,后跟一个可选的停止位置(百分比)

background-image: linear-gradient(to left, #d3959b, #bfe6ba);

to left设置渐变从右到左,相当于270deg

css_13.png

background-image: linear-gradient(to right, #d3959b, #bfe6ba);

to right设置渐变从左到右,相当于90deg

css_14.png

background-image: linear-gradient(to top, #d3959b, #bfe6ba);

to top设置渐变从下到上,相当于0deg

css_15.png

background-image: linear-gradient(to bottom, #d3959b, #bfe6ba);

to bottom设置渐变从上到下,相当于180deg

css_16.png

background-image: linear-gradient(to top right, #d3959b, #bfe6ba);

to right top = to top right从左下角到右上角,对角线角度

css_17.png

background-image: linear-gradient(45deg, #d3959b, #bfe6ba);

to top right有细微差别(背景为正方形的时候无差别)

css_18.png

background-image: linear-gradient(45deg, #d3959b 50%, #bfe6ba);

用百分比指定起始颜色的位置,默认值为0%

css_19.png

background-image: linear-gradient(to right, #feac5e, #c779d0, #4bc0c8);

css_20.png

background-image: linear-gradient(45deg, #feac5e, #c779d0, #4bc0c8);

css_21.png

background-image: linear-gradient(45deg, rgba(254, 172, 94, 0.5), rgba(199, 121, 208, 0.5), rgba(75, 192, 200, 0.5));

css_22.png

3.8、radial-gradient()

radial-gradient()用于创建径向渐变图像

background-image: radial-gradient([shape] [size] [at position], color percentage, ... color percentage);
  • shape:可选,确定圆的类型,ellipse(默认)指定椭圆形的径向渐变circle指定圆形的径向渐变
  • size:可选,定义渐变的大小,farthest-corner(默认)指定径向渐变的半径长度为从圆心到离圆心最远的角closest-side指定径向渐变的半径长度为从圆心到离圆心最近的边closest-corner指定径向渐变的半径长度为从圆心到离圆心最近的角farthest-side指定径向渐变的半径长度为从圆心到离圆心最远的边
  • at position:可选,定义渐变的位置,center(默认)设置中间为径向渐变圆心的纵坐标值top设置顶部为径向渐变圆心的纵坐标值bottom设置底部为径向渐变圆心的纵坐标值(leftrightcentertopbottom百分比),可有两个值
  • color percentage:渐变断点,该值包含一个颜色值,后跟一个可选的停止位置(百分比)

background-image: radial-gradient(red, yellow, green);

当元素为正方形时,形状就是圆形的渐变

css_23.png

background-image: radial-gradient(circle, red, yellow, green);

css_24.png

background-image: radial-gradient(red 5%, green 15%, blue 60%);

css_25.png

size

position的值为50% 50%时,则渐变的圆心在元素的中心点

background-image: radial-gradient(closest-side at 60% 55%, red, yellow, black);
background-image: radial-gradient(farthest-side at 60% 55%, red, yellow, black); 
background-image: radial-gradient(closest-corner at 60% 55%, red, yellow, black);

css_26.png

3.9、conic-gradient()

conic-gradient():函数用于创建一个圆锥渐变图像

background-image: conic-gradient([from angle] [at position,] color degree, color degree, ...);
  • from angle:可选,起始角度,默认值为0deg
  • at position:可选,中心位置,默认居中(leftrightcentertopbottom百分比),可有两个值
  • color degree:渐变断点,该值包含一个颜色值,后跟一个可选的停止位置(角度deg或百分比)

background-image: conic-gradient(red, orange, yellow, green, blue)

css_27.png

background-image: conic-gradient(red 45deg, yellow 90deg, green 210deg);

css_28.png

background-image: conic-gradient(from 90deg, red, yellow, green);

设置from 90deg起始角度

配合border-radius: 50%;

css_29.png

background-image: conic-gradient(from 90deg at 60% 45%, red, yellow, green);

设置起始角度from 90deg

指定中心点at 60% 45%

配合border-radius: 50%;

css_30.png

background-image: conic-gradient(red 0deg, red 90deg, yellow 90deg, yellow 180deg, green 180deg);

css_31.png

3.10、repeating-linear-gradient()

repeating-linear-gradient()函数用于创建重复的线性渐变图像

background: repeating-linear-gradient(angle | to side-or-corner, color-stop1, color-stop2, ...);
  • angle:定义渐变的角度方向,从0deg360deg,默认为180deg
  • to side-or-corner:指定线性渐变的起始位置。(leftrightcentertopbottom百分比),可有两个值
  • color-stop:渐变断点,该值包含一个颜色值,后跟一个可选的停止位置(百分比)

background-image: repeating-linear-gradient(45deg, red, blue 7%, green 10%);

css_32.png

background-image: repeating-linear-gradient(190deg, red, blue 7%, green 10%);

css_33.png

background-image: repeating-linear-gradient(90deg, red, blue 7%, green 10%);

css_34.png

3.11、repeating-radial-gradient()

repeating-radial-gradient():用于创建重复的径向渐变图像

background-image: repeating-radial-gradient([shape] [size] [at position], color percentage, ... color percentage);
  • shape:可选,确定圆的类型,ellipse(默认)指定椭圆形的径向渐变circle指定圆形的径向渐变
  • size:可选,定义渐变的大小,farthest-corner(默认)指定径向渐变的半径长度为从圆心到离圆心最远的角closest-side指定径向渐变的半径长度为从圆心到离圆心最近的边closest-corner指定径向渐变的半径长度为从圆心到离圆心最近的角farthest-side指定径向渐变的半径长度为从圆心到离圆心最远的边
  • at position:可选,定义渐变的位置,center(默认)设置中间为径向渐变圆心的纵坐标值top设置顶部为径向渐变圆心的纵坐标值bottom设置底部为径向渐变圆心的纵坐标值(leftrightcentertopbottom百分比),可有两个值
  • color percentage:渐变断点,该值包含一个颜色值,后跟一个可选的停止位置(百分比)

background-image: repeating-radial-gradient(red, yellow 10%, green 15%);

css_35.png

3.12、repeating-conic-gradient()

repeating-conic-gradient():创建重复的圆锥渐变

background-image: repeating-conic-gradient([from angle] [at position,] color degree, color degree, ...);
  • from angle:可选,起始角度,默认值为0deg
  • at position:可选,中心位置,默认居中(leftrightcentertopbottom百分比),可有两个值
  • color degree:渐变断点,该值包含一个颜色值,后跟一个可选的停止位置(角度deg或百分比)

background-image: repeating-conic-gradient(red 0deg 30deg, yellow 30deg 60deg, blue 60deg 90deg);

css_36.png

九、图片、图标

1.常见的图片格式及使用场景

  • GIF 动图

  • JPEG 有损色彩丰富,适合存储照片, 文件较大

  • PNG 无损,体积小,支持透明度

  • SVG 放大不失真,适合 logo icon

  • BMP 无损, 不压缩, 文件较大

  • WebP 谷歌新出的图片格式, 体积比 png 更小, 兼容性不好

2.精灵图CSS Sprites

精灵图CSS Sprites,将一个页面涉及到的所有图片都包含到一张大图中去,然后利用CSSbackground-imagebackground-repeatbackground-position属性的组合进行背景定位

优点

  • 利用精灵图能很好的减少网页的http请求,从而提高页面的性能
  • 精灵图能减少图片的字节,把多张图片合为一张后大小肯定会缩小

缺点

  • 在图片合并时,要把多张图片有序的、合理的合并成一张图片,还要留好足够的空间,防止板块内出现不必要的背景,在宽屏及高分辨率下的自适应页面,若背景不够宽,很容易出现背景断裂
  • 精灵图在维护的时候会比较麻烦,页面背景有少许改动就要修改这张合并的图片,若出现尺寸变化,还要进行代码上的位置重新调整

3.字体图标

阿里图标库为示例

创建项目

菜单中的【资源管理】 ==> 【我的项目】,点击右侧按钮【新建项目】

css_38.png

【新建项目】的创建表单

css_39.png

  • 项目名称:建议填写和开发项目相同的名称,好方便后续的区分查找
  • 项目描述:项目简单描述
  • FontClass前缀:定义字体图标样式的前缀,默认icon,可自行修改,看项目需求
  • Font Family:字体名称,默认是iconfont,可自行修改,看项目需求
  • 字体格式:选择字体文件生成哪几种格式,因为不同的浏览器可能兼容性不同,建议选择WOFF2WOFFTTF,若有彩色图标需求,则也要勾选
  • 所有者:默认为创建项目的人,当前页面不可修改,后期可通过【项目设置】进行修改
  • 操作者:在当前界面不可修改,后期可通过【项目成员】进行修改,可添加成员共用一个项目

css_40.png

加入购物车导入项目

css_41.png

右上角【购物车】按钮,购物车会显示当前购物车中有多少个图标,点击【添加至项目】点击相对应的项目,然后【确定】

css_42.png

下载并使用

css_43.png

文件内容为

css_44.png

将文件拷贝到项目中

在项目中引入iconfont.css文件

vue

// main.js入口文件中
import './font/iconfont.css';

一般使用<i><span>

iconfont就是之前的项目初始设置的字体名称

<i class="iconfont icon-add-circle"></i>
<i class="iconfont icon-arrow-up-circle"></i>

常规html文件

使用link标签引入即可

<link rel="stylesheet" href="./font/iconfont.css">