学习目标
- 掌握CSS的基本概念和应用
- 精通CSS选择符-众多高级选择器技术的核心
- 选择器的权重和优先级
- 选择器的命名
- 定位和层叠上下文
- CSS绘制高级技巧
- CSS机制At-rule
- CSS工作原理和性能优化
CSS 的基本概念
CSS 是一种描述 HTML 文档样式的语言。
CSS 描述应该如何显示 HTML 元素。
css 实例
body {
background-color: lightblue;
}
h1 {
color: white;
text-align: center;
}
p {
font-family: verdana;
font-size: 20px;
}
CSS 选择器
基本选择器
选择器 | 例子 | 例子描述 |
---|---|---|
.class | .intro | 选择 class=“intro” 的所有元素。 |
.class1.class2 | .name1.name2 | 选择 class 属性中同时有 name1 和 name2 的所有元素。 |
.class1 .class2 | .name1 .name2 | 选择作为类名 name1 元素后代的所有类名 name2 元素。 |
#id | #firstname | 选择 id=“firstname” 的元素。 |
* | * | 选择所有元素。 |
element | p | 选择所有 元素。 |
element.class | p.intro | 选择 class=“intro” 的所有 元素。 |
属性选择器
选择器 | 例子 | 例子描述 |
---|---|---|
[attr] | 用于选取带有指定属性的元素。 | |
[attribute=value] | 用于选取带有指定属性和值的元素。 |
层次选择器
选择器 | 例子 | 例子描述 |
---|---|---|
element element | div p | 选择
元素内的所有
元素。 |
element>element | div > p | 选择父元素是
的所有
元素。 |
element+element | div + p | 选择紧跟
元素的首个
元素。 |
element1~element2 | p ~ ul | 选择前面有 元素的每个
|
伪类选择器
选择器 | 例子 | 例子秒速 |
---|---|---|
:link | a:link | 选择所有未访问过的链接。 |
:visited | a:visited | 选择所有已访问的链接。 |
:active | a:active | 选择活动链接。 |
:hover | a:hover | 悬浮 |
:focus | input:focus | 选择匹配的E元素,而且匹配元素获取焦点 |
伪元素选择器
选择器 | 例子 | 例子描述 |
---|---|---|
::after | p::after | 在每个 的内容之后插入内容。 |
::before | p::before | 在每个 的内容之前插入内容。 |
<!DOCTYPE html>
<html>
<head>
<style>
p::after
{
content:"- 结束 ";
}
p::before
{
content:"- 开始 ";
}
</style>
</head>
<body>
<p>我是唐老鸭。</p>
</body>
</html>
选择器的权重和优先级
CSS三大特性: 继承性、优先级和层叠性;
优先级的等级:
- 0级(0):通配选择器(*)、选择符(+、>、~、空格、||)
- 1级(1):元素、关系、伪元素
- 2级(10):类选择器、属性选择器、伪类
- 3级(100):ID选择器
- 4级(1000):style内联选择器
- 5级(10000):!important
优先级的计算规则:
权重顺序 !important>行内样式>id选择器>类选择器>标签选择器>通配符>继承>浏览器默认 - 选择器权重:
- !important 优先级最高
- 元素属性 优先级高
- 相同权重 后写的生效
当几个类型写在一起时,只需要将它们相加,如下面两个例子,相加之后权重分别未101和110
选择器的命名
骆驼命名法
第一个字母要小写,后面的词的第一个字母就要用大写,例如: studentInfo、navMenuRedButton
帕斯卡命名法
这种命名法同样也是大小写字母混编而成,和骆驼命名法很像,但和骆驼命名法有一点区别,就是所有单词的首字母都要大写,当然也包括第一个单词;例如: StudentInfo、NavMenuRedButton
匈牙利命名法
在名称前面加上一个或多个小写字母作为前缀,来让名称更加好认,更容易理解,例如: head_navigation、
red_navMenuButton;
页面模块的常用命名:
头:header | 导航:nav | 菜单:menu | 友情链接:friendlink |
---|---|---|---|
页面外围包裹:wrapper | 子导航:subnav | 子菜单:submenu | 下载:download |
页面主体:main | 广告:banner | 侧栏:sidebar | 小技巧:tips |
内容:content | 标志:logo | 栏目:column | 滚动:scroll |
页脚:footer | 搜索:search | 热点:hot | 上一个:prev |
版权:copyright | 登录条:loginbar | 新闻:news | 下一个:next |
BEM命名法
BEM的意思就是块(block)、元素(element)、修饰符(modifier),是由Yandex团队提出的一种前端命名方法论。这种巧妙的命名方法让你的CSS类对其他开发者来说更加透明而且更有意义。BEM命名约定更加严格,而且包含更多的信息,它们用于一个团队开发一个耗时的大项目。
- BEM:块(block)、元素(element)、修饰符(modifier)
- block 代表了更高级别的抽象或组件。
- block__element 代表.block的后代,用于形成一个完整的.block的整体。
- block–modifier代表.block的不同状态或不同版本,用于修饰。
air-table{} /* 块 */
air-table__footer{} /* 元素 */
air-table--full{} /* 修饰符 */
// vue组件下使用
<template>
// wrapper主要用于sass嵌套,以免父(子)组件里的css冲突
<div class="air-table(组件名)-wrapper">
<el-table class="air-table"></el-table>
<div class="air-table__footer air-table__footer--full">
<button class="air-table__footer--prev">上</button>
<button class="air-table__footer--next">下</button>
</div>
</div>
</template>
<style lang="scss" scoped>
.air-table(组件名)-wrapper {
.air-table {}
.air-table__footer {
.air-table__footer—prev {}
.air-table__footer—bext {}
&.air-table__footer--full {}
}
}
</style>
定位和层叠上下文
position 属性规定应用于元素的定位方法的类型(static、relative、fixed、absolute 或 sticky)
元素其实是使用 top、bottom、left 和 right 属性定位的。但是,除非首先设置了 position 属性,否则这些属性将不起作用。根据不同的 position 值,它们的工作方式也不同。
HTML 元素默认情况下的定位方式为 static(静态)。
静态定位的元素不受 top、bottom、left 和 right 属性的影响。
position: static
的元素不会以任何特殊方式定位;它始终根据页面的正常流进行定位:
这个 div 元素设置了 position: static;
这是所用的 CSS:
实例
div.static {
position: static;
border: 3px solid #73AD21;
}
position: relative
position: relative; 的元素相对于其正常位置进行定位。
设置相对定位的元素的 top、right、bottom 和 left 属性将导致其偏离其正常位置进行调整。不会对其余内容进行调整来适应元素留下的任何空间。
这个div 元素设置了 position: relative;
这是所用的 CSS:
div.relative {
position: relative;
left: 30px;
border: 3px solid #73AD21;
}
position: fixed
position: fixed; 的元素是相对于视口定位的,这意味着即使滚动页面,它也始终位于同一位置。 top、right、bottom 和 left 属性用于定位此元素。
固定定位的元素不会在页面中通常应放置的位置上留出空隙。
请注意页面右下角的这个固定元素。这是所用的 CSS:
实例
div.fixed {
position: fixed;
bottom: 0;
right: 0;
width: 300px;
border: 3px solid #73AD21;
}
position: absolute
position: absolute; 的元素相对于最近的定位祖先元素进行定位(而不是相对于视口定位,如 fixed)。
然而,如果绝对定位的元素没有祖先,它将使用文档主体(body),并随页面滚动一起移动。
注意:“被定位的”元素是其位置除 static 以外的任何元素。
这是所用的 CSS:
div.relative {
position: relative;
width: 400px;
height: 200px;
border: 3px solid #73AD21;
}
div.absolute {
position: absolute;
top: 80px;
right: 0;
width: 200px;
height: 100px;
border: 3px solid #73AD21;
}
position: sticky;
position: sticky; 的元素根据用户的滚动位置进行定位。
粘性元素根据滚动位置在相对(relative)和固定(fixed)之间切换。起先它会被相对定位,直到在视口中遇到给定的偏移位置为止 - 然后将其“粘贴”在适当的位置(比如 position:fixed)。
实例
div.sticky {
position: -webkit-sticky; /* Safari */
position: sticky;
top: 0;
background-color: green;
border: 2px solid #4CAF50;
}
**注意:**Internet Explorer、Edge 15 以及更早的版本不支持粘性定位。 Safari 需要 -webkit- 前缀(请参见下面的实例)。您还必须至少指定 top、right、bottom 或 left 之一,以便粘性定位起作用。
重叠元素
在对元素进行定位时,它们可以与其他元素重叠。
z-index 属性指定元素的堆栈顺序(哪个元素应放置在其他元素的前面或后面)。
元素可以设置正或负的堆叠顺序:
<!DOCTYPE html>
<html>
<head>
<style>
img {
position: absolute;
left: 0px;
top: 0px;
z-index: -1;
}
</style>
</head>
<body>
<h1>这是标题</h1>
<img src="/demo.png" width="188" height="267" />
<p>由于图像的 z-index 为 -1,它将被置于文本之后。</p>
</body>
</html>
CSS绘制高级技巧
颜色线性渐变
CSS linear-gradient()
函数用于创建一个表示两种或多种颜色线性渐变的图片
参数:
第一个参数:指定渐变方向,可以用“角度”的关键词或“英文”来表示:to/top、bottom、left、right
第一个参数省略时,默认为“180deg”,等同于“to bottom”。
第二个和第三个参数,表示颜色的起始点和结束点,可以有多个颜色值。
// 1、线性渐变默认是从上到下
.box{
background:linear-gradient(red,green);
background:-webkit-linear-gradient(red,green);
}
// 2、从一个方向到另一个方向(to/left 、right 、bottom、top)
background:linear-gradient(to left,red,green);
background:-webkit-linear-gradient(to left,red,green);
// 3、对角的,两个方向可以进行组合,比如下面的就是从左上角到右下角
background:linear-gradient(to left top,red,green);
background:-webkit-linear-gradient(to left top,red,green);
// 4、还可以是角度
background:linear-gradient(90deg,red,green);
background:-webkit-linear-gradient(90deg,red,green);
border-radius
允许你设置元素的外边框圆角。
.box {
height: 100px;
width: 100px;
border: solid 10px;
/* 弯曲成一个D的样子' */
border-radius: 10px 40px 40px 10px;
}
box-shadow
属性用于在元素的框架上添加阴影效果。你可以在同一个元素上设置多个阴影效果,并用逗号将他们分隔开。该属性可设置的值包括阴影的X轴偏移量、Y轴偏移量、模糊半径、扩散半径和颜色。
<style>
.box {
height: 100px;
width: 100px;
box-shadow: 10px 5px 5px red;
}
</style>
text-shadow
为文字添加阴影。可以为文字与 text-decorations
添加多个阴影,阴影值之间用逗号隔开。每个阴影值由元素在X和Y方向的偏移量、模糊半径和颜色值组成。
.box {
height: 100px;
width: 100px;
text-shadow: 10px 10px 2px pink;
}
Filter
filter
CSS属性将模糊或颜色偏移等图形效果应用于元素。滤镜通常用于调整图像,背景和边框的渲染。
.box {
height: 100px;
width: 100px;
filter: blur(5px);
}
clip-path
属性使用裁剪方式创建元素的可显示区域。区域内的部分显示,区域外的隐藏
作用:
- 对容器进行裁剪
- 常见几何图形
- 自定义路径
// 圆形circle(半径at圆心坐标)
.circle{
width:100px;
height:100px;
background:#0cc;
-webkit-clip-path:circle(50% at 50% 50%);
}
// 椭圆形ellipse(长、短轴半径at圆心坐标)
.ellipse{
width:100px;
height:100px;
background:#aaa;
-webkit-clip-path:ellipse(25% 50% at 50% 50%);
}
// 内置矩形inset (上右下左的边距round上右下左圆角)
.inset{
width:100px;
height:100px;
background:#99f;
-webkit-clip-path:inset(10px 20px 30px 10px round 20px 5px 50px 0);
}
// 正三角形
.triangle{
width:100px;
height:87px;
background:#c00;
-webkit-clip-path:polygon(0% 100%, 50% 0%,100% 100%);
}
// 正方形
.square{
width:100px;
height:100px;
background:#069;
-webkit-clip-path:polygon(0% 0%, 0% 100%,100% 100%,100% 0%);
}
CSS机制At-rule
https://css-tricks.com/the-at-rules-of-css/
https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule
大家可能在CSS中见到过字符@然后加一些关键字的用法,这种用法就称之为AT规则,在CSS中,种类还是很多的,这里总结列举下:
@charset、@import、、@font-face、@keyframes、@media、@supports
@charset
定义字符集。⽤于提示CSS文件使用的字符编码方式,它如果被使用,必须出现在最前面。这个规则只在给出语法解析阶段前使用,并不影响页面上的展示效果;
某些软件,例如Dreamweaver新建CSS文件时候,自动会带有下面所示代码,但实际开发时候,作用不大,因为meta中已经有所设置 (),会覆盖,所以我都是直接删掉的。
@charset "utf-8";
@import
导入其他CSS样式文件。除了@charset规则不会被引入,@import可以引⼊另⼀个文件的全部内容。
实际上线时候,不建议使用,多请求,阻塞加载之类。但本地开发可以使用,用做CSS模块化开发,然后使用一些(如grunt)工具进行压缩并合并。但是呢,相比less, sass等还是有不足,就是@import语句只能在CSS文件顶部,使得文件的前后关系控制,就不那么灵活。
@import 'index.css';
@import url('index.css');
@font-face
自定义字体用的。IE6也支持
@font-face {
font-family: 'MyWebFont';
src: url('myfont.woff2') format('woff2'),
url('myfont.woff') format('woff');
}
@keyframes
用来声明CSS3 animation动画关键帧
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@media
媒介查询
@media all and (min-width: 1280px) {
/* 宽度大于1280 */
}
@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 2dppx) {
/* Retina屏幕. */
}
@media print {
/* 打印 */
}
@supports
是否支持某CSS属性声明的AT规则,浏览器对其支持性越来越好了
/* 检查是否支持CSS声明 */
@supports (display: flex) {
.module { display: flex; }
}
/* 检查多个条件 */
@supports (display: flex) and (-webkit-appearance: checkbox) {
.module { display: flex; }
}
预处理器作用和原理
CSS预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。
通俗的说,“CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供项目使用。CSS 预处理器为 CSS 增加一些编程的特性,无需考虑浏览器的兼容性问题”,例如你可以在 CSS 中使用变量、简单的逻辑程序、函数(如右侧代码编辑器中就使用了变量$color)等等在编程语言中的一些基本特性,可以让你的 CSS 更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。
CSS预处理器语言,比如说有:
LESS实战
安装
在 Node.js 环境中使用 Less :
npm install -g less
运行
lessc index.less index.css
语法
变量
@width: 10px;
@height: @width + 10px;
#header {
width: @width;
height: @height;
}
编译为
#header {
width: 10px;
height: 20px;
}
混合
混合(Mixin)是一种将一组属性从一个规则集包含(或混入)到另一个规则集的方法。假设我们定义了一个类(class)如下:
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
如果我们希望在其它规则集中使用这些属性呢?没问题,我们只需像下面这样输入所需属性的类(class)名称即可,如下所示:
#menu a {
color: #111;
.bordered();
}
.post a {
color: red;
.bordered();
}
嵌套
Less 提供了使用嵌套(nesting)代替层叠或与层叠结合使用的能力。假设我们有以下 CSS 代码:
#header {
color: black;
}
#header .navigation {
font-size: 12px;
}
#header .logo {
width: 300px;
}
用 Less 语言我们可以这样书写代码:
#header {
color: black;
.navigation {
font-size: 12px;
}
.logo {
width: 300px;
}
}
用 Less 书写的代码更加简洁,并且模仿了 HTML 的组织结构。
你还可以使用此方法将伪选择器(pseudo-selectors)与混合(mixins)一同使用。下面是一个经典的 clearfix 技巧,重写为一个混合(mixin) (&
表示当前选择器的父级):
.clearfix {
display: block;
zoom: 1;
&:after {
content: " ";
display: block;
font-size: 0;
height: 0;
clear: both;
visibility: hidden;
}
}
导入
“导入”的工作方式和你预期的一样。你可以导入一个 .less
文件,此文件中的所有变量就可以全部使用了。如果导入的文件是 .less
扩展名,则可以将扩展名省略掉:
@import "library"; // library.less
@import "typo.css";
注释
块注释和行注释都可以使用:
/* 一个块注释
* style comment! */
@var: red;
// 这一行被注释掉了!
@var: white;
运算
算术运算符 +
、-
、*
、/
可以对任何数字、颜色或变量进行运算。如果可能的话,算术运算符在加、减或比较之前会进行单位换算。计算的结果以最左侧操作数的单位类型为准。如果单位换算无效或失去意义,则忽略单位。无效的单位换算例如:px 到 cm 或 rad 到 % 的转换。
// 所有操作数被转换成相同的单位
@conversion-1: 5cm + 10mm; // 结果是 6cm
@conversion-2: 2 - 3cm - 5mm; // 结果是 -1.5cm
// conversion is impossible
@incompatible-units: 2 + 5px - 3cm; // 结果是 4px
// example with variables
@base: 5%;
@filler: @base * 2; // 结果是 10%
@other: @base + @filler; // 结果是 15%
乘法和除法不作转换。因为这两种运算在大多数情况下都没有意义,一个长度乘以一个长度就得到一个区域,而 CSS 是不支持指定区域的。Less 将按数字的原样进行操作,并将为计算结果指定明确的单位类型
@base: 2cm * 3mm; // 结果是 6cm
你还可以对颜色进行算术运算:
@color: #224488 / 2; //结果是 #112244
background-color: #112244 + #111; // 结果是 #223355
函数
Less 内置了多种函数用于转换颜色、处理字符串、算术运算等。这些函数在Less 函数手册中有详细介绍。
函数的用法非常简单。下面这个例子将介绍如何利用 percentage 函数将 0.5 转换为 50%,将颜色饱和度增加 5%,以及颜色亮度降低 25% 并且色相值增加 8 等用法
@base: #f04615;
@width: 0.5;
.class {
width: percentage(@width); // returns `50%`
color: saturate(@base, 5%);
background-color: spin(lighten(@base, 25%), 8);
}
命名空间和访问符
有时,出于组织结构或仅仅是为了提供一些封装的目的,你希望对混合(mixins)进行分组。你可以用 Less 更直观地实现这一需求。假设你希望将一些混合(mixins)和变量置于 #bundle
之下,为了以后方便重用或分发:
#bundle() {
.button {
display: block;
border: 1px solid black;
background-color: grey;
&:hover {
background-color: white;
}
}
.tab { ... }
.citation { ... }
}
现在,如果我们希望把 .button
类混合到 #header a
中,我们可以这样做:
#header a {
color: orange;
#bundle.button(); // 还可以书写为 #bundle > .button 形式
}
映射
从 Less 3.5 版本开始,你还可以将混合(mixins)和规则集(rulesets)作为一组值的映射(map)使用。
#colors() {
primary: blue;
secondary: green;
}
.button {
color: #colors[primary];
border: 1px solid #colors[secondary];
}
输出符合预期:
.button {
color: blue;
border: 1px solid green;
}
作用域
Less 中的作用域与 CSS 中的作用域非常类似。首先在本地查找变量和混合(mixins),如果找不到,则从“父”级作用域继承。
@var: red;
#page {
@var: white;
#header {
color: @var; // white
}
}
与 CSS 自定义属性一样,混合(mixin)和变量的定义不必在引用之前事先定义。因此,下面的 Less 代码示例和上面的代码示例是相同的:
@var: red;
#page {
#header {
color: @var; // white
}
@var: white;
}
注释
块注释和行注释都可以使用:
/* 一个块注释
* style comment! */
@var: red;
// 这一行被注释掉了!
@var: white;
CSS工作原理和性能优化
BFC的原理和功能
BFC 即 Block Formatting Contexts (块级格式化上下文),它属于定位方案中的普通流。
具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。
触发BFC条件
只要元素满足下面任一条件即可触发 BFC 特性:
- body 根元素
- 浮动元素:float 除 none 以外的值
- 绝对定位元素:position (absolute、fixed)
- display 为 inline-block、table-cells、flex
- overflow 除了 visible 以外的值 (hidden、auto、scroll)
BFC特性和应用
- BFC 可以包含浮动的元素(清除浮动)
- 同一个 BFC 下外边距会发生折叠
- BFC 可以阻止元素被浮动元素覆盖
IFC的原理和功能
存在块级格式化上下文BFC,则对应存在内联格式化上下文IFC、网格格式化上下文GFC、自适应格式化上下文FFC,这些都可以统称为格式化上下文。
IFC的含义:
- IFC(inline Formatting Context)叫做“内联格式化上下”
- 内部的元素从包含块的顶部开始,从左至右(默认)排列成一行形成的一个矩形盒子叫做line box;
IFC的作用: - 水平居中:当一个块要在环境中水平居中时候,设置其为inline-block则会在外层产生IFC,通过text-align:center则可以使其水平居中。
- 垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。
CSS 优化技巧
- 减少 后代选择器 的使用 ,例如
.div p {
// ...
}
为什么后代选择器为什么会更消耗性能呢?
因为浏览器首先会找到所有 p
标签,然后再向上查找包含 class
为 div
标签。这样一来如果代码中有很多 p
标签,无疑是会做很多重复工作的。
2. 使用具体的 class
来定义CSS
浏览器会从右到左解析 CSS 选择器
.box div p a {
// ...
}
浏览器会对上面的例子做如下的步骤处理:
1、首先找到页面所有的a元素
2、然后向上找到被p元素包裹的a元素
3、再向上查找到一直到 .box
的元素
从上面的步骤我们可以看出,越靠右的选择器越具有唯一性,浏览器解析 CSS 属性的效率就越高。
所以一定换成使用具体的 class 编写 CSS 代码,可以有效的提升性能。
3. 避免重排和重绘
修改某些 CSS 属性会导致整个页面布局的重绘( repaint )/重排( reflow )。
重排会导致浏览器重新计算整个文档,重新构建渲染树,这一过程会降低浏览器的渲染速度。如下所示,有很多操作会触发重排,我们应该避免频繁触发这些操作。
1、改变font-size和font-family
2、改变元素的内外边距
3、通过JS改变CSS类
4、通过JS获取DOM元素的位置相关属性(如width/height/left等)
5、CSS伪类激活
6、滚动滚动条或者改变窗口大小
另外, 当元素的外观(如color,background,visibility等属性)发生改变时,会触发重绘。在网站的使用过程中,重绘是无法避免的。不过,浏览器对此做了优化,它会将多次的重排、重绘操作合并为一次执行。不过我们仍需要避免不必要的重绘。
4. 内联首屏关键CSS(Critical CSS)
将CSS直接内联到HTML文档中能使CSS更快速地下载。而使用外部CSS文件时,需要在HTML文档下载完成后才知道所要引用的CSS文件,然后才下载它们。所以说,内联CSS能够使浏览器开始页面渲染的时间提前,但是 这种方式并不适用于内联较大的CSS文件。
5. 文件压缩
文件的大小会直接影响浏览器的加载速度,这一点在网络较差时表现地尤为明显。相信大家都早已习惯对CSS进行压缩,现在的构建工具,如webpack、gulp/grunt、rollup等也都支持CSS压缩功能。压缩后的文件能够明显减小,可以大大降低了浏览器的加载时间。
6. 不要使用@import
首先,使用@import引入CSS会影响浏览器的并行下载,其次,多个@import会导致下载顺序紊乱
7. 删除无用的css