这是我参与「第四届青训营 」笔记创作活动的第二天
CSS是什么?
Cascading Style Sheets
层叠样式表
选择器 属性名 属性值(后两个合起来为声明)
选择器就是选中html的某个标签(元素),为其定义样式
css由这一条条的样式规则组成
在页面引入css的三种方式
推荐第一种,内容和样式的分离,功能上的分工
开发范式上:组件式的开发
做到关注点分离
css是怎么应用到样式里面的?
每个dom树节点解析出它的css样式,得到渲染树(每个节点位置在哪里,其中每个属性的样式),最后渲染成完整的页面。
html与css有单独解析的过程,通过dom树把解析出的css附加到dom树上。
选择器
通配选择器
(*为选择所有)
* { color: red; font-size: 20px; }标签选择器
a {}
类选择器
.done{}
id选择器
注:id为唯一值
#logo {}
属性选择器
[disabled]{}
input[type="password"]
a[href^="el"] {}
选中href属性值以el为开头的元素
a[href$=".jpg"] {}
选中href属性值以.jpg为结尾的元素
伪类
(不基于标签和属性定位元素)
状态性伪类
某个元素只有在处于某种状态才会被选中
我们可以用伪类选择器选择不同链接所处的状态,给不同状态下的链接定义样式。
链接的四种状态:
link 默认样式
active 鼠标按下去那刻的样式
focus 聚焦状态(按下去之后的状态)
若冒号前面没有,则默认给所有标签的这个状态定义样式
结构性伪类
根据dom节点在dom树出现的位置来决定是否选中该元素
可以通过元素在父级节点的相对位置来选中节点
li:first-child li父级的第一个节点
还有更复杂的:可以通过父级/同级的某个类型的标签指定,可以写表达式指定是基数/偶数/3的倍数的标签去赋予样式。
组合
可以通过组合的方式把标签放在一块:
选择器组
颜色
怎么去排文本的样式(——格式化文本),颜色是一方面
两种表示方法:
RGB表示
rgb(red,green,blue)数值0~255
#8fac87每两位数值以十六进制的形式展示,换算十进制也是0~255
(255,255,255)白色
(0,0,0)黑色
HSL表示
hsl(hue,saturation,lightness)
例:hsl(0,100%,50%)
调用关键字
例:blue,black,white...
alpha 透明度
在css实际上是不透明度(0~1),0为完全透明,1为完全覆盖
#ff000080
rgba(255,0,0,0.5)
hsla(0,100%,50%,0.5)
新一点的浏览器不要求写rgba,写rgb然后传四位参数也可以
字体
font-family
'字体族'的概念,要放多个,因为你的网页可能会被不同设备访问,不同设备可以安装拥有的字体是不一样的。
h1 {
font-family: Optima, Georgia, serif;
}
serif和sans-serif通用字体族,不是具体的某种字体,它是一类字体
css支持五类通用字体族:(只是一种风格/分类,一定要在定义的font-family最后加上其中一种通用字体族)
使用建议
~英文字体放在中文字体前面,避免出现中英文字体没有区分开的情况。
~字体列表最后写上通用字体族
Web Fonts
如果希望字体严格按照样式展示,可以把字体文件放在服务器上,指定字体的名字和字体所在的url,浏览器会先从url下载文件,然后再用这个字体格式进行渲染。可能会带来性能上的开销。
如果是中文,用的时候对原本的字体文件进行裁切,用不到的字的字体丢掉。
属性:
font-size
关键字:small,medium,large
长度:px,em
百分数:相当于父元素字体的大小
*em 是相对的单位,上面例子中:
section h2 {
font-size: 2em;
}
与下面的同义
section h2 {
font-size: 40px;//2em*前面20px得到
}
同理font-size: 80%;即20*80%px
这是相对的font-size
font-style: italic设置斜体
font-style: normal;非斜体
font-weight: 100重,字的粗细(100~900,400-normal,700-bold)
并不是所有字体都设置了这么多字重
h1 {
font-size: 30px;
line-height: 45px;
}
p {
font-size: 20px;
line-height: 1.6;//相对行高,20*1.6px,推荐
}
line-height行高,两行文字基准线的距离,默认的1.1~1.2非常不适合阅读
font综合各种字体属性
text-align对齐(left,center,right,justify)
justify实际上是将每个单词的间距进行拉伸,以达到两端对齐的效果。(相当于word的分散)
letter-spacing间距(px)
word-spacing间距(px)
text-indent首行缩进(px)
text-decoration(none,underline,line-through,overline)
white-space(normal,nowrap,pre,pre-wrap,pre-line)
空白符处理:
默认情况下,多个连续的空白/换行符会被合并成一个。
调试css
选择器的特异度
选择器的特殊程度越高,优先级越高
122>022
例一:样式覆盖
继承
p标签继承父节点font-size属性
css里,和文字相关的都是可以继承的。跟盒模型相关的属性都是不可继承的(比如height、宽度),但可以通过inherit显式继承。
* {
box-sizing: inherit;
}
// 所有元素box-sizing属性值都从父级继承,好处是可以通过一个容器就改变容器内所有元素的box-sizing属性值。
html {
box-sizing: border-box;
}
.some-widget {
box-sizing: content-box;
}
初始值
从元素父级一层一层往上找没找到属性值
当元素不可继承,而又没设置属性,就会用到初始值
transparent透明的
css求和过程
(html与css如何结合)
下面这个流程实际上是找到页面上每一个元素的每一个css属性值。(遍历)
filter中的css media-query(了解)这一阶段是匹配,得到所有的匹配值也就是Declare Values声明值。最终决定用哪个呢?
cascading瀑布,一层一层往下找,优先级,选出最终获胜的一个值
cascaded value层叠值(唯一)
Specified Value指定值(唯一)
计算值:不是所有的相对值都做计算,比如60%,计算时不会去做一个转换,而会在formating再去做进一步转换。(关键字inherit,百分百60%)
constraining另一个作用是在设置最大宽度为400px而计算出来的是500px时,使实际值为400px
完整流程图:
计算值
浏览器拿到css后,可以马上算出来或者转换出来的相对值。
单纯通过html和css就能计算出的值。
比如:
此标签设置了1.2em,父级设置20px,计算20*1.2px为当前标签font-size。
img的相对地址+当前页面url->绝对地址
使用值
需要把渲染规则拿到渲染环境里,得到浏览器宽度是多少才能进一步转换得到的值。需要实际布局才能决定的值放在formatting阶段去计算。
不能单纯通过html和css就能计算出的值。
例子:百分比
子元素继承的是父元素的计算值!
实践:容器font-size1.2em,h1设置为100px,看h1行高
不是100*1.2px,而是根据父级的计算值,父级的行高计算出来后给子级继承
布局
三种布局方式:
常规流/文档流(normal flow):块级、行级规则
浮动:图文混排。把图片设置为浮动,做成文字环绕图片的效果
绝对定位:完全脱离常规文档流进行绝对定位。盖在常规流上面,可以任意改变元素的位置,而不会对常规流造成什么影响。
会有嵌套,相当于给元素内创建一个新的流
display:flow-root(流的源头)
盒模型
内容、内边距、边框、外边距
content内容
auto由浏览器根据其他属性决定,是怎么决定的?
如果容器高度为auto,需要依赖内容高度确定,内容是百分数是不行的。
height如果为百分数,要确定容器(父级)能不能确定一个确切的高度,或者容器一层一层写了很多高度有继承。
padding内边距
(px / 百分数-相对容器的宽度)
一个值:上下左右
两个值:上下 左右
四个值:上 右 下 左(顺时针)
border边框
指定容器边框样式(none/solid/dashed/dotted)、粗细、颜色。
三种属性: border-width border-style border-color
四个方向: border-left border-right border-top border-bottom
可以灵活组合
border: 1px solid #ccc;
border-left: 1px solid #ccc;
border-right: 2px dotted red;
border-width: 1px 2px 3px 4px;
border-style: solid;
border-color: green blue;
border-left-width: 3px;
border-top-color: #f00;
当把容器元素宽度和高度设置为0(默认内容的宽高),可以用来画三角形(设置透明、颜色、粗细)
margin外边距
指定元素四个方向的外边距
取值:长度、百分数、auto
百分数相对容器的宽度。
使用margin:auto居中
margin-left: auto;
margin-right: auto;
上面代码中,浏览器会取容器宽度减去元素宽度后的平均值。
margin collapse边距坍塌/合并/折叠(垂直方向上)
.a {
background: lightblue;
height: 100px;
margin-bottom: 100px;
}
.b {
background: coral;
height: 100px;
margin-top: 100px;
}
a与b的距离不是200px而是100px,取两者最大边距,而不是简单相加。方便文字排版。但有些时候不需要边距坍塌,这种情况是有办法解决的。
border-box
对比前面的content-box,指定width:100%结果不同。
实际项目中用border-box多一些。
* {
box-sizing: border-box;
}
// 指定使用border-box,默认是content-box
overflow
控制溢出
三个值:visible(默认),hidden,scroll(有滚动条),auto(超出了的滚动,没超出的就默认)
常规流
五种排版上下文里面,参与一种规则。
块级vs行级
行级的宽度和高度是由内容决定的。
行级排版上下文(IFC)
-
Inline Formatting Context (IFC)
-
只包含行级盒子的容器会创建一个IFC
-
例子:span标签,里面全是文字。
-
IFC 内的排版规则
- 盒子在一行内水平摆放
- 一行放不下时,换行显示
- text-align 决定一行内盒子的水平对齐
- vertical-align 决定一个盒子在行内的垂直对齐
- 避开浮动(float)元素*
<div>
This is a paragraph of text with long word Honorificabilitudinitatibus. Here is an image
<img src="https://assets.codepen.io/59477/cat.png" alt="cat">
And <em>Inline Block</em>
</div>
<style>
div {
width: 10em;
//overflow-wrap: break-word;
background: #411;//褐色
}
em {
display: inline-block;
width: 3em;
background: #33c;//蓝色
}
</style>
div是块级元素,但div里面全是行级元素,符合行级排版上下文
所以遵循像文字式从左到右摆放,一行显示不下时换行。但里面的inline-block元素、图片、一个英文单词不能被拆成两行。
overflow-wrap: break-word;使一个单词超出容器范围时换行。
块级排版上下文(BFC)
-
Block Formatting Context (BFC)
-
某些容器会创建一个BFC:
- 根元素,即html标签
- 浮动、绝对定位、inline-block
- Flex子项和Grid子项
- overflow 值不是 visible 的块盒(overflow:hidden;)
- display: flow-root;
-
BFC 内的排版规则:
- 盒子从上到下摆放
- 垂直 margin 合并
- BFC 内盒子的 margin 不会与外面的合并 (如果不想要两个盒子的margin合并,可以把两个盒子分散到不同的BFC里面,一种方式是把一个个元素嵌套在div,然后把div设置成
display: flow-root;或overflow:hidden;,这样两个元素就分属于不同的BFC,两个不同的BFC不会重叠) - BFC 不会和浮动元素重叠*(清除浮动时用的技巧)
在常规流里,一个盒子内子集的盒子只能都是块级或者都是行级,块级从上到下摆放,行级从左到右一行一行摆放。但如果一个盒子打个比方是div,里面既有块级又有行级,那么浏览器怎么处理呢?
下面例子中,div是块级的,而文字是行级的,块级和行级盒子同属于一个父级,这时浏览器会创建两个匿名的块级盒子把文字包起来。匿名盒子:不是在html写的,在dom树也看不到,只有在排版时在css排版以前(?)有这样的元素存在,包裹着这两段文字。
行级元素的特性:以行为基本单位做排版。(留意第一行和第三行的红色边框) 但为什么会是一行?span是行级元素标签。一个span为一行,可以把div改为em然后把span内容复制多几行,看看效果就明白了。
<span>
This is a text and
<div>block</div>
and other text.
</span>
<style>
span {
line-height: 3;
border: 2px solid red;
background: coral;
}
div {
line-height: 1.5;
background: lime;
}
</style>
表格布局
FlexBox
在一个容器里面,有很多子元素,可以通过flex box的属性去控制里面的子元素。
-
一种新的排版上下文
-
它可以控制子级盒子的:
- 摆放的流向 ( → ← ↑ ↓ )
- 摆放顺序
- 盒子宽度和高度
- 水平和垂直方向的对齐
- 是否允许折行(换行)
.container {
display: flex;
}
让container创建一个flex布局上下文,里面的子元素行为受容器内的flex属性控制。
flex默认流向为从左到右。每个元素宽度默认由它内部内容决定。
属性:
flex-direction:摆放的流向 ( row→ row-reverse← column↓ column-reverse↑ )
对齐(主轴方向上)
justify :
对齐(侧轴方向上)
align-items(默认值stretch,里面所有元素高度和容器高度相同)
baseline 所有子元素的基线对齐
align-self
align-items是设置在上下文/容器里面的,也可以针对某个特定的元素设置一个不同的样式。
order通过css控制页面摆放顺序,从小到大排列。
- Flexibility
- 可以设置子项的弹性:当容器有剩余空间时,会伸展;容器空间不够时,会收缩。
flex-grow有剩余空间时的伸展能力flex-shrink容器空间不足时收缩的能力flex-basis没有伸展或收缩时的基础长度
flex-grow: 2;
flex-shrink: 0;
flex-grow
如果一个元素值为2,另一个值为1,那么按照2:1分配剩余空间
flex-shrink
值为0时不能压缩,剩余完全没有定义flex-shrink值的元素因为宽度相同所以压缩后仍然宽度相同。
flex综合属性,代表着子属性(flex-grow,flex-shrink,flex-basis)的集合
| FLEX | 看文档查一下就好* |
|---|---|
| flex: 1 | flex-grow: 1;flex-shrink: 1;flex-basis: auto; |
| flex: 100px | flex-basis: 100px |
| flex: 2 1 | flex-grow: 2; flex-shrink: 1 |
| flex: 1 100px | flex-grow: 1; flex-basis: 100px |
| flex: 2 0 100px | flex-grow: 2; flex-shrink: 0; flex-basis: 100px |
| flex: auto | flex: 1 1 auto |
| flex: none | flex: 0 0 auto |
flex- wrap:设置子元素的是否自动换行(在空间不够的情况下)和排列方向
Grid布局
display: grid
- display: grid 使元素生成一个块级的 Grid 容器
- 使用 grid-template 相关属性将容器划分为网格(二维)
- 设置每一个子项占哪些行/列
grid-template-columns: 100px 1fr 1fr;
grid-template-rows: 100px 1fr
1fr,fraction一份,这里是把剩余的都占满
grid-template-columns: 30% 30% auto;
grid-template-rows: 100px auto
auto也是把剩余的占满
划分网格后,把子元素放在格子里,通过网格线grid line指定
通过区域的线标识区域。
两种写法:
.a {
grid-row-start: 1;
grid-column-start: 1;
grid-row-end: 3;
grid-column-end: 3;
}
.a {
grid-area: 1/1/3/3;
}
如果指定中有重叠,排版也会重叠。
可以通过浏览器开发者工具检查,在display: grid;打开baseline
grid是最强大的布局。
浮动
实现文字环绕效果。
float:left;这么给图片靠左放置后,
p标签位置不受影响,只不过里面的行级元素会绕开图片。
其他浮动、清除浮动可以通过flex box、grid实现
绝对定位
position属性
| 属性值 | 含义 | 备注 |
|---|---|---|
| static | 默认值,非定位元素 | 静态,参与常规流里面的布局 |
| relative | 相对自身原本位置偏移,不脱离文档流 | 1+ 在常规流里面布局 2+ 相对于自己本应该在的位置进行偏移 3+ 使用top、bottom、left、right设置偏移长度 4+ 流内其他元素当它没有偏移一样布局 |
| absolute | 绝对定位,相对非static祖先元素定位 | 1+ 脱离常规流 2+ 相对于最近的非static祖先定位 3+ 使用top、bottom、left、right设置相对于祖先容器的位置 4+ 不会对流内元素布局造成影响,即当这个元素不存在 |
| fixed | 相对于视口绝对定位 | 1+ 脱离常规流 2+ 总是相对于窗口进行定位 3+ |
| sticky | 看mdn文档 粘性定位 这个元素原本不在顶部,、滚动到顶部时让这个元素吸附在顶部不动。 |
学习 CSS 的几点建议
- 充分利用 MDN 和 W3C CSS 规范
- 保持好奇心,善用览器的开发者工具
- 持续学习,CSS 新特性还在不断出现