理解CSS
tips:全文共7100多个字,建议先收藏噢~
先在这里放一个网址,可以通过这个网址去查关于HTML、CSS、JS、HTTP的相关知识,知识准确度很高,而且很多都有中文版的,方便大家使用。
网址:developer.mozilla.org/zh-CN/
本文内容包含:
为什么学习css
1996年苹果官网:
2023年苹果官网:
通过以上两张图能够发现,现在的页面具有以下特点:
- 更丰富的交互行为和视觉效果
- 能够承载和展现更多的信息量
- 更精准的传递信息
css发展史
- CSS 1 :始于1966年。
- CSS 2 :诞生于1998年,添加定位,Z-index,media 属性。
- CSS 2.1:诞生于2004~2011年,目前使用最广泛的版本(IE支持)
- CSS 3:1999年开始起草,把CSS模块化,独立升级各功能。
基础知识
CSS:Cascading Style Sheet,层叠样式表。
Cascading规则
cascading层叠规则:
我们一般写的样式都归类在作者样式表,作者样式表根据书写位置又分为三类:行内式、内嵌式、外部链接式,这三类样式的优先级要根据选择器的优先级确定。
<!-- html代码 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
#title {
color: red;
}
</style>
<link rel="stylesheet" href="./test.css" type="text/css">
<body>
<h1 id="title" style="color: green;">title title title</h1>
</body>
</html>
/* css样式 */
h1 {
color: blue;
font-size: 48px;
}
选择器
内联样式(写在标签内部的)1000,id选择器100,类和伪类10,元素选择器1,通配选择器0.当选择器中包含多种选择器时,需要将各种选择器的优先级相加然后再比较,但是多个相同级的选择器相加的结果不会超过上一个级别的优先级。(选择越详细精确,权重越高,优先级越高)
对于@import的样式,根据@import的顺序
对于link和style标签的样式,根据在document中的顺序决定
基础选择器:
*{ }:通配符选择器。选择所有的元素E{ }:元素选择器。其中 E 为任何一个元素,如html、body、p、div等。.class{ }:类选择器。定义时为class="classname",class值可以有多个,用空格隔开。#id{ }:id选择器。定义时为id="idname",相同 id 只能有一个。s1, s2, s3...sn{ }:群组选择器。一次性选择 多个选择器 所对应的元素。s1s2s3...sn{ }:交集选择器。如选择 class 值为 hello 的 div 元素:div.hello{ }
关系选择器:
E F{ }:后代选择器。选择 E 元素的一个或多个和 F 相同的后代元素。E>F{ }:子选择器。选择 E 元素的子元素 F。E+F{ }:相邻兄弟选择器。选择紧挨着 E 元素的后一个兄弟 F 元素,如果 F 元素不是 E 元素的后一个兄弟元素,则选择不成功。E~F{ }:兄弟选择器。选择 E 元素后面的所有 F 兄弟元素。-
<div class="父元素"> <span class="子元素 元素1"></span> <span class="子元素 元素2 元素1的兄弟元素"></span> <span class="子元素 元素3 元素1的兄弟元素"></span> </div>
特性选择器:
E[att]:选择具有 att 特性的 E 元素,不考虑特性的值。如选择具有class属性的div元素div[class]。E[att="val"]:选择具有 att 特性且特性值等于 val 的 E 元素。如选择具有class属性为且 class 值为 name 的 div 元素div[class="name"]。E[att~="val"]:选择具有 att 特性且特性值为 用空格分隔的单词,其中一个单词为 val 的 E 元素(如<p class="my val">xdy</p>)E[att|="val"]:选择具有 att 特性且特性值为 用连接符分隔的字符串,并以 val 开头的 E 元素(如<h1 lang="en">hello<h1>或者<p lang="en-us">hello</p>都能被*[lang|="en"]选择,即选择特性 lang 的值为“en”或以“en-”开头的元素)E[att^="val"]:选择具有 att 特性且特性值 以 val 开头的 E 元素。E[att$="val"]:选择具有 att 特性且特性值为 以 val 结尾的字符串的 E 元素。E[att*="val"]:选择具体 att 特性且特性值为 包含 val 的字符串的 E 元素。- ......
伪元素选择器(用::符号。一般会创建一个新的元素。所以是 伪的):
E::first-letter:设置元素内容第一个字符的样式(仅作用于块元素,一般用于制作首字下沉的效果)E::before:设置在元素显示前发生的内容(一般将它和CSS的content属性一起使用,且所添加的内容无法选中)E::after:设置在元素显示后发生的内容(一般将它和CSS的content属性一起使用,同before,可解决高度塌陷问题)- ......
伪类选择器:(用:符号。表示选择处于某一种特殊状态的元素)
E:nth-child(n):(n 表示第 n 个元素,从 0 开始的)(even 表示偶数位置的元素)(odd 表示奇数位置的元素)选择父元素的第几个子元素且该元素为 E。-child是在所有子元素中找匹配的元素,而-of-type 是在同类型中找匹配的元素E:not(F):用于剔除含 F 属性的元素。- ......
开发小提示:
选择器尽量少用 id;
尽量不要用 !important;
自己的样式加在引用库样式的后面。
隐藏福利~ 关注gong zhong hao【安酱xx】,输入【js高级学习笔记】获取3万多字的js高级笔记噢~,输入【html+css】获取html+css学习笔记(这个是早期记录的笔记,有点混乱~)
继承
值和单位
盒模型
外边距(margin): 可正可负可auto
- 提供4个数据:(如margin:20px 20% 0.2em 20px;)将依次作用于上,右,下,左。(顺时针)
- 提供3个数据:将依次作用于上,左右,下
- 提供2个数据:将依次作用于上下,左右
- 提供1个数据:将依次作用于上下左右
margin负值最终减少的是外界可感知的宽高。
不提倡使用负外边距,因为这会增加代码复杂度。
内边距(padding): 不可为负,其余同上。
由盒模型的特性能够实现一些展现形式:
<!-- 三角形 -->
<div class="triangle-bottom"></div>
.triangle-bottom{
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid red;
}
<!-- 固定比例矩形,也可以使用新特性aspect-ratio:https://developer.mozilla.org/zh-CN/docs/Web/CSS/aspect-ratio -->
<div class="ratio-box"></div>
.ratio-box{
/* 新特性写法 */
/* aspect-ratio: 4 / 3;
background-color: greenyellow; */
background-color: cadetblue;
width: 100%;
height: 0;
padding: 0;
/* 是父元素宽度的75% */
padding-bottom: 75%;
}
<!-- 水平居中 -->
<div class="wrap">
<div class="h-center"></div>
</div>
.wrap{
width: 100%;
height: 100%;
border: 1px dashed grey;
}
.h-center{
width: 100px;
height: 50px;
background-color: navajowhite;
/* 使用auto将左右2侧的剩余空间均分 */
margin: 10px auto;
}
<!-- 渐变边框,这块有点疑问 -->
<div class="awesome-border"></div>
.awesome-border{
width: 150px;
height: 100px;
border: 8px solid transparent;
border-radius: 12px;
background-clip: padding-box,border-box;
background-origin: padding-box,border-box;
background-image: linear-gradient(to right,#fff,#fff),linear-gradient(135deg,#e941ab,#a557ef);
}
布局和定位
常规流中的任意盒子都只会参与一种格式化上下文。
BFC
外边距塌陷或外边距重叠问题:
IFC
内联格式化上下文:
实现单行元素居中对齐常用方式:
- 将
line-height和height设置为相同的高度即可 - 使用
flex布局的align-items:center即可
flex布局
flex布局学习参考地址:www.ruanyifeng.com/blog/2015/0…
flex布局实例地址:www.ruanyifeng.com/blog/2015/0…
开启了 flex 布局的元素叫 flex container;flex container 里面的直接子元素叫 flex item。
flex item 的布局将受 flex container 属性的设置来进行控制和布局;flex item 不再严格区分块级元素和行内元素;flex item 默认情况下是包裹内容的,但是可以设置宽度和高度。
display: flex:flex container 以 block-level 形式存在,即块元素。
display: inline-flex:flex container 以 inline-level 形式存在,即行内元素。flex 模型示意图:
flex-container 父元素属性
flex-direction:该属性决定主轴的方向,有 4 种取值:row(默认值)、row-reverse、column、column-reverse。
flex-wrap:决定元素单行显示还是多行显示。有 3 种取值:nowrap(默认值)、wrap(单行显示)、wrap-reverse(修改了交叉轴,即从下到上排列)。如果一行显示不下,那么其宽度或者高度将会被压缩。也就是设置的宽度与其显示的真正宽度没有必然关系。
flex-flow:是 flex-direction 和 flex-wrap 的简写属性。任何顺序,都是可省略的。
justify-content:该属性决定了 flex-item 在 main axis 上的对齐方式。 有以下常见可选值:
align-items:该属性决定了 flex-item 在 cross axis 上的对齐方式。 有以下常见可选值:
基准线是 flex-item 中的文本底部的水平线。
align-content:space-evenly 有兼容性问题。 在 flex container 设置高度后有剩余空间才可能会设置该属性,但是一般开发中都不会设置盒子的高度,而是由内容撑开。(多行)
flex-item 子元素属性
order:决定 flex-items 的显示顺序。(使用 css 来决定显示的顺序)值为任意整数(正整数,负整数,0),默认值为 0;顺序按照值从小到大依次排。
align-self:单独设置某一个 flex-item 在 cross axis 上的排布方式。有 6 种取值:auto(默认值)、stretch、flex-start、flex-end、center、baseline。
flex-grow:决定 了 flex items 如何扩展或拉伸或成长。值为任意非负数字(正整数、正小数,0),默认值为 0 。(设置小数有不一样的效果)
注意:当 flex container 在 main axis 上有剩余空间时,flex-grow 属性才会有效。 flex items 扩展后的最终 size 不能超过 max-width 或者 max-height 。
flex-shrink:决定了 flex items 如何缩小。 值为任意非负数字(正整数、正小数,0),默认值为 1 。注意:当 flex items 在 main axis 方向上超过了 flex container 的 size ,flex-shrink 才会生效。 flex items 缩小后的最终 size 不能小于 min-width 或者 min-height
flex-basis:用来设置 flex items 在 mian axis 方向上的 base size(基本尺寸)。 值:auto(默认值),具体的宽度数值。注意:如果设置了 flex-basis 之后,一个内容在设置的宽度中不能全部显示,则会被拉伸。最终显示的大小会被如下顺序因素影响(优先级从高到低):
- max-width、max-height、min-width、min-height。
- flex-basis
- width、height
- 内容本身的 size
flex:是 flex-grow 、flex-basis 和 flex-shrink 的缩写属性。 值:none | auto | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] (该语法可通过将鼠标悬浮在属性上进行查看)
浏览器可快捷查看各个属性的显示样式:
查看属性的具体效果:
grid布局
2017年推出的布局方式,可以定义由行和列组成二维布局,然后将元素放置到网格中。元素可以只占其中一个单元格,也可以占据多行或多列。
通过 grid-template-columns 和 grid-template-rows 属性来定义网格中的列和行。如现在创建了一个网格,包含了三个 200 像素宽的列轨道。子元素将在网格上每个网格单元中展开。
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
display: grid;
grid-template-columns: 200px 200px 200px;
}
轨道可以使用任何长度单位进行定义。网格还引入了一个另外的长度单位来帮助我们创建灵活的网格轨道。新的fr单位代表网格容器中可用空间的一等份。
.wrapper {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
}
grid-template-areas CSS 属性是网格区域 grid areas 在 CSS 中的特定命名。
学习更多建议查看以下 MDN 学习地址。
MDN 学习地址:developer.mozilla.org/zh-CN/docs/…
grid和flex布局的使用策略
使用建议:
position定位
为了我们可以在文档流的基础上,让元素移动,做出更多灵活的改变。当position属性的取值非static的时候,可以使用top, right, bottom, left对其进行定位。
层叠上下文
层叠上下文:The Stacking Context。是对HTML元素的三维构想,将元素沿着垂直屏幕的虚构的 Z 轴排开。
浏览器渲染部分过程示意图(英文):www.chromium.org/developers/…
形成条件
文档中的层叠上下文由满足以下任意一个条件的元素形成:
- 文档根元素(
<html>); - css3之前
opacity属性值小于1的元素(参见 the specification for opacity);mix-blend-mode属性值不为normal的元素;- 以下任意属性值不为
none的元素: isolation属性值为isolate的元素;will-change值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素(参考这篇文章);contain属性值为layout、paint或包含它们其中之一的合成值(比如contain: strict、contain: content)的元素。
在层叠上下文中,子元素同样也按照上面解释的规则进行层叠。重要的是,其子级层叠上下文的 z-index 值只在父级中才有意义。子级层叠上下文被自动视为父级层叠上下文的一个独立单元。
总结:
- 层叠上下文可以包含在其他层叠上下文中,并且一起创建一个层叠上下文的层级。
- 每个层叠上下文都完全独立于它的兄弟元素:当处理层叠时只考虑子元素。
- 每个层叠上下文都是自包含的:当一个元素的内容发生层叠后,该元素将被作为整体在父级层叠上下文中按顺序进行层叠。
层叠顺序
层叠顺序不仅指不同的层叠上下文的顺序,同一个层叠上下文内,元素间也有顺序:
z-index 只在同一个层叠上下文内比较
子元素的z-index无法超越父元素的z-index显示顺序
编写 z-index 的建议:
变形、过渡、动画
transform 变形
在线试一试: codepen.io/yao-mo/pen/…
transition 过渡
通过指定某些元素属性从一种起始状态,在-段时间内以某种变化节奏,过渡到终止状态。
语法:transition: <property> <duration> <timing-function> <delay>
animation 动画
animation 属性参考:developer.mozilla.org/zh-CN/docs/…
css 动画样式参考:animate.style/
transform、transition、animation性能
重绘(repaint):是指一个元素外观属性的变化触发浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。
回流(reflow):当渲染树中的一部分(或全部)因为元素的规模尺寸、布局、隐藏等改变需要重新构建,这就是回流。每个页面至少需要一次回流,就是在页面第一次加载的时候。
重绘和回流的关系:在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程称为重绘。
所以,回流必定会引发重绘,但重绘不一定会引发回流
硬件加速详情:www.chromium.org/developers/…
动画性能相关深入了解:fed.taobao.org/blog/taofed…
响应式设计
响应式设计原则
- 优先选用流式布局,如百分比、flex、 grid等
- 使用响应式图片,匹配尺寸,节省带宽
- 使用媒体查询为不同的设备类型做适配
- 给移动端设备设置简单、统一的视口
- 使用相对长度,em、rem、vw 做为长度度量
媒体查询
媒体查询允许某些样式只在页面满足特定条件时才生效。我们可以将媒体类型(如screen、print) 以及媒体特性(如视口宽度、屏幕比例、设备方向:横向或纵向)做为约束条件。
使用媒体查询的一些Tips:
- 媒体查询同样遵循cascading层叠覆盖原则,min- 和max-选择一个
- 由于设备的多样化逐渐不可枚举,断点的选择尽量根据内容选择,而不是屏幕大小
- 由于断点的增加会增加样式处理的复杂度,所以尽量减少断点
媒体查询学习参考:developer.mozilla.org/zh-CN/docs/…
设备像素
设备像素(物理像素) :显示器上绘制的最小单位,显示屏通过控制每个像素点的颜色,使屏幕显示出不同的图像。
设备像素和设备相关,屏幕从工厂出来那天起,它上面的物理像素点就固定不变了。
CSS像素
CSS像素也叫参考像素。CSS像素(reference pixel) 其实是一个视角单位。规范给出的定义是,1css像素是从一臂之遥看解析度为96DPI (即1英寸96点)的设备输出时,1点(即1/96英寸)的视角。
通常认为常人臂长为28英寸,那么视线与水平线的夹角是:(1/96)in / (28in* 2 * PI/ 360deg) = 0.0213度
存在意义:保证在不同设备上的阅读体验是相对一致的。
viewport
布局视口(viewport)是页面中html元素(根元素)的包含块,默认情况下,window.document.documentElement.clientWidth 就是viewport的宽度。在移动设备中,默认的布局视口由于历史兼容pc屏幕的原因,并不符合需求,我们经常需要用<meta>标签对viewport进行设定,来完成移动端设备的适配。
移动端 viewport 的 meta 标签中的属性:
- width
- height
- initial-scale
- minimum-scale
- maximum-scale
- user-scalable:是否允许用户缩放
initial-scale在未设定时,如果width设定了,那么它会自动设置放缩值:initial-scale =屏幕宽度(例子中是390) / 980 ≈ 0.398。相比scale=1的时候,缩小了0.398倍
<meta name="viewport" content="width=device-width, initial-scale=1.0">
相对长度
em
rem:根据根元素的字体大小确定。通过伪类:root或者html选择器选定。由于是根元素的font-size,所以不会像 em 那样出现多重嵌套问题,减少了复杂性,同时作为一个相对单位,可以进行适配放缩,可以用来做响应式布局.
vw 和 vh:vw:视窗宽度的1%。vh:视窗高度的1%。同样,vw 也可以作为响应式布局的基准单位。由于vw天然是视口宽度的1%,所以不需要js动态配置。和rem方案类似,方案设定可以如下:
移动端页面适配方案参考:www.w3cplus.com/css/vw-for-…
CSS生态相关
因为目前CSS的可编程性较差,不可维护性较高,代码污染啊等等问题催生出一系列的处理器。
常见样式处理流程
语言增强-CSS预处理器
预处理器如何提高研发效率?
- 自定义变量:提高可复用性
- 嵌套、作用域:避免全局污染、结构层次清晰、减少复杂组合选择器
- mixins、继承:提高可复用性、可维护性
- 操作符、条件或循环语句、自定义函数:提高可编程能力、增加灵活性
SCSS、less、stylus简单对比:
语言增强-CSS后处理器
cssnano:cssnano.co/
stylelint:github.com/stylelint/s…
autoprefixer:github.com/postcss/aut…
postcss-custom-properties:github.com/csstools/po…
postcss-custom-media:github.com/csstools/po…
postcss-nested:github.com/postcss/pos…
doiuse:github.com/anandthakke…
postcss plugins:postcss.org/docs/postcs…
postcss 机制浅析
AST抽象语法树格式化网址:astexplorer.net/
工程架构-CSS模块化
CSS Module就是为了解决全局污染问题出现的方案,解决CSS全局污染,本质上是保证样式集合对应的选择器是唯一的,从这个角度看,主流的单纯针对于防止全局污染的方案大概有:
css-loader:github.com/webpack-con…
postcss-module:github.com/webpack-con…
css-modules:github.com/css-modules…
工程架构-CSS in JS
将应用的CSS样式写在JavaScript文件里面,利用js动态生成css。
- inline-style:代表radium(已弃用)
- unique classname:代表styled-component
css in js playground(styled-component例子):www.cssinjsplayground.com/?activeModu…
工程架构-styled component机制浅析
css in js 优缺点
工程架构-CSS原子化
原子化CSS是一种CSS的架构方式,它倾向于小巧且用途单一的class,并以视觉效果进行命名。
现有的库或框架:
tailwind:tailwindui.com/
windicss:cn.windicss.org/
tachyons:tachyons.io/
unocss:github.com/unocss/unoc…
Tailwind基本使用:
CSS原子化优缺点
Facebook重构拥抱 atomic css:sebastienlorber.com/atomic-css-…
总结
资源网址
知识点与某节关联性较大,则该节也会将网址贴出。这里做一个简单总结(部分地址都是MDN中的,就不重复贴出,直接在网站内搜索即可)。
- MDN:developer.mozilla.org/zh-CN/
- CSS值和单位的规范:www.w3.org/TR/css-valu…
- 视觉格式化模型(盒模型):developer.mozilla.org/zh-CN/docs/…
- margin auto 的更多表现:blog.csdn.net/linshizhan/…
- css3 display 属性:www.w3.org/TR/css-disp…
- 格式化上下文简介:developer.mozilla.org/zh-CN/docs/…
- 浏览器渲染部分过程示意图(英文):www.chromium.org/developers/…
- 层叠上下文介绍:developer.mozilla.org/zh-CN/docs/…
- css 动画样式参考:animate.style/
- 硬件加速详情:www.chromium.org/developers/…
- 动画性能相关深入了解:fed.taobao.org/blog/taofed…
- css像素学习参考:www.w3.org/TR/css-valu…
- 移动端页面适配方案参考:www.w3cplus.com/css/vw-for-…
- AST抽象语法树格式化网址:astexplorer.net/