掌握CSS3 核心
学习目标
- 掌握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 | 在每个
的内容之前插入内容。 |
<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组件下使用 // wrapper主要用于sass嵌套,以免父(子)组件里的css冲突 .air-table(组件名)-wrapper { .air-table {} .air-table__footer { .air-table__footer—prev {} .air-table__footer—bext {} &.air-table__footer--full {} }}
定位和层叠上下文
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 属性指定元素的堆栈顺序(哪个元素应放置在其他元素的前面或后面)。
元素可以设置正或负的堆叠顺序:
<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预处理器语言,比如说有:
- Sass(SCSS)
- LESS
- Stylus
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; //结果是 #112244background-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