02理解CSS | 青训营笔记

174 阅读9分钟

这是我参与「第四届青训营 」笔记创作活动的的第2天 建议对照PPT阅读

PPT: slides.com/fe-fairy/cs…

了解 CSS

CSS 是什么?

CSS: Cascading Style Sheet (层叠样式表)

用来定义页面元素的样式

  • 设置字体和颜色
  • 设置位置和大小
  • 添加动画效果

CSS是如何工作的?

加载HTML -> 解析HTML

↓ -> 创建DOM树 -> 展示页面

| -> 加载CSS -> 解析CSS -> 添加样式到DOM节点

注意: 创建DOM树和加载CSS是并行的

选择器

通配, 标签, id, 类选择器比较熟悉, 不再记录

属性选择器

 [disabled] {
     background: #eee;
     color: #999;
 }

标签和属性选择器直接组合使用

 input[type="password"] {
     border-color: red;
     color: red;
 }

伪类选择器 (pseudo-classes)

不基于标签和属性定位元素

状态伪类
 a:link {} /* 未访问的链接 */
 a:visited {} /* 已访问的链接 */
 a:hover {} /* 鼠标在链接上 */
 a:active {} /* 点击链接, 正在跳转时 */
 :focus {} /* 获得焦点 */
结构性伪类
 li:first-child { /* li的第一个子元素 */
   color: coral
 }
 ​
 li:last-child { /* li的最后一个子元素 */
   border-bottom: none;
 }
 ​
 input.error { /* 选中类为error的input */
     border-color: red;
 }

组合

名称语法说明示例
直接组合AB满足A同时满足Binput:focus
后代组合A B选中B, 如果B是A的子孙nav a
亲子组合A > B选中B, 如果B是A的子元素section > p
兄弟选择器A ~ B选中B, 如果B在A后且和A同级h2 ~ p
相邻选择器A + B选中B, 如果B紧跟在A后面h2 + p

颜色

RGB

RGB色彩就是常说的光学三原色,R代表Red(红色),G代表Green(绿色),B代表Blue(蓝色)

HSL

HSL是一种将RGB色彩模型中的点在圆柱坐标系中的表示法

H (Hue 色相)

S (Saturation 饱和度)

L (Lightness 亮度)

alpha 透明度

0(透完透明) ~ 1(完全不透明)

字体

font-famliy

 h1 {
     font-family: Optima, Georgia, serif;
 }
 body {
     font-family: Helvetica, sans-serif;
 }

为什么指定多个?

为了兼容. 浏览器会从左往右, 直到可用字体为止.

注意: 上面两个font-family最后的serif, sans-serif不是某一种字体, 而是字体族 (一类字体的集合)

通用字体族有:

  • Serif 衬线体 (包括了 Georigia, 宋体)
  • Sans-Serif 无衬线体 (包括了 Arial, Helvetica, 黑体, 微软雅黑)
  • Gursive 手写体 (包括了 Caflisch, 楷体)
  • Fantasy (包括了 Comic Sans MS. Papyrus, Zapfino)
  • Monospace 等宽字体 (包括了 Consolas, Courier, 中文字体)

使用建议:

  1. 字体列表最后写上通用字体族 (起到兜底作用, 加强兼容)
  2. 英文字体放在中文字体前面 (注意: 微软雅黑中也有英文字体)

学到的新技术 - 使用Web Fonts ⭐

 /* 导入Web Fonts */
 @font-face {
     font-family: "Megrim"; /* 定义文件名称 */
     src:        url(https://fonts.gstatic.com/s/megrim/v11/46kulbz5WjvLqJZVam_hVUdI1w.woff2) /* 指定文件路径 */
     format('woff2'); /* 声明字体文件的格式 */
 }
 ​
 /* 使用Web Fonts */
 h1 {
     font-family: Megrim; /* 使用Web Fonts */
 }

font-size

其值可以是

  • 关键字

    • small, medium, large
  • 长度

    • 单位可以是px或em
  • 百分数

    • 相对于父元素字体大小

font

font: style weight size/height family

font: size family

 h1 {
   /* 斜体 粗细 大小/行高 字体族 */
   font: bold 14px/1.7 Helvetica, sans-serif;
 }
  
 p {
   font: 14px serif;
 }

font-weight

如果不同weight没区别, 可能是因为字体不支持

line-height

text-align

spacing 间距

  • letter-spacing 字母间距
  • word-spacing 单词间距

text-indent 缩进

text-decoration

white-space

通过这个属性可用控制空白符怎么显示

调试 CSS

右键点击页面,选择「检查」

使用 快捷键

  •  Ctrl+Shift+I (Windows) ⭐
    
  •  Cmd+Opt+I (Mac)
    

深入CSS ⭐

PPT: slides.com/fe-fairy/cs…

哪条规则生效

 <article>
   <h1 class="title">拉森火山国家公园</h1>
 </article>
  
 <style>
   .title {
     color: blue;
   }
   
   article h1 {
     color: red;
   }
 </style>

多个选择器选择到同一元素, 如果指定的样式不冲突则都生效, 如果冲突则取决于选择器的特异度(Specificity), 也可以理解为权重, 越特殊的选择器权重越高, 越有决定权

继承

某些元素会自动继承其父元素的指定值, 除非显示指定一个值

一般和文字相关的可继承, 和盒模型相关的不可继承

(注意继承到的是指定值, 可在下文CSS求值过程中体会什么是计算值)

显示继承

对于不可继承的样式, 可以采用显示继承, 如

  • {

box-sizing: inherit;

}

初始化

CSS中, 每个属性都有一个初始值, 如

background-color的初始值为transparent

margin-left的初始值为0

可以使用initial关键字显示重置为初始值, 如

background-color: initial

CSS求值过程 ⭐ (有意思)

  1. filtering:

    根据DOM树和样式规则用以下条件进行筛选 (选择器匹配, 属性有效, 符合当前media等)得到 声明值

    声明值 (Declared Values): 一个元素的某属性可能有0到多个声明值

  2. cascading:

    按照来源, !important, 选择器特异性, 书写顺序等选出一个属性值, 即层叠值

    层叠值 (Cascaded Value): 在层叠(cascading)过程中, 赢得优先级比赛的那个值

  3. defaulting:

    当层叠值为空的时候, 使用继承或初始值

    指定值(Specified Value): 经过cascading和defaulting之后, 保证指定值一定不为空

  4. resolving:

    将一些相对值或者关键字转化成绝对值, 比如em转为px, 相对路径转化为绝对路径

    这个过程中, 得到的是计算值 (Computed Value)

  5. formatting:

    将计算值进一步转化, 比如关键字, 百分比等都转化为绝对值

    得到使用值 (Used Value)

  6. constraining:

    将小数像素值转化为整数, 得到实际值

布局 ⭐⭐

是什么

确定内容的大小和位置的算法

相关技术

  • 常规流 (行级, 块级, 表格布局, FlexBox, Grid布局)
  • 浮动
  • 绝对定位

相关属性

width
  • 指定 content box 宽度
  • 取值为长度、百分数
  • auto 由浏览器根据其它属性确定
  • 百分数相对于容器的 content box 宽度
height
  • 指定 content box 高度
  • 取值为长度、百分数、auto
  • auto 取值由内容计算得来
  • 百分数相对于容器的 content box 高度
  • 容器有指定的高度时,百分数才生效 ⭐ (不然会循环依赖)
padding
  • 指定元素四个方向的内边距
  • 百分数相对于容器宽度 ⭐
border
  • 指定容器边框样式、粗细和颜色

  • 三种属性

    • border-width
    • border-style
    • border-color
  • 四个方向

    • border-top
    • boder-right
    • border-bottom
    • border-left

⭐利用边框可以获得三角形

margin
  • 指定元素四个方向的外边距
  • 取值可以是长度、百分数、auto
  • 百分数相对于容器宽度

⭐使用 margin:auto 水平居中

margin collapse 现象
 <div class="a"></div>
 <div class="b"></div>
 ​
 <style>
   .a {
     background: lightblue;
     height: 100px;
     margin-bottom: 100px;
   }
 ​
   .b {
     background: coral;
     height: 100px;
     margin-top: 100px;
   }
 </style>

两个div的margin之和是100而不是200, 因为融合了 (融合后的结果为二者较大的那个)

box-sizing: border-box

如果指定了border-box, 则指定的宽高是包含border, padding的

如果不指定, 则默认为

项目中可以, * { box-sizing: border-box }

overflow ⭐
  • visible 超出盒子的文本仍显示
  • hidden 超出盒子的文本不显示
  • scrool 文本超出盒子会显示滚轮

块级 vs. 行级

  • Block Level Box (CSS概念)

不和其他盒子并列摆放

使用所有的盒模型属性

  • Inline Level Boex

和其它行级盒子可以放在一行或拆开成多行

盒模型中的width, height不适应


  • 块级元素 (HTML概念)

生成块级元素

display: block

  • 行级元素

生成行级盒子, 分散在多个行级盒子中

display

常规流 Normal Flow

行级排版上下文 (IFC)

Inline Formatting Context (IFC)

只包含行级盒子的容器会创建一个IFC

⭐IFC 内的排版规则

  • 盒子在一行内水平摆放
  • 一行放不下时,换行显示
  • text-align 决定一行内盒子的水平对齐
  • vertical-align 决定一个盒子在行内的垂直对齐
  • 避开浮动(float)元素*
块级排版上下文 (BFC)
  • Block Formatting Context (BFC)

  • 某些容器会创建一个BFC

    • 根元素
    • 浮动、绝对定位、inline-block
    • Flex子项和Grid子项
    • overflow 值不是 visible 的块盒
    • display: flow-root;

⭐BFC 内的排版规则

  • 盒子从上到下摆放
  • 垂直 margin 合并
  • BFC 内盒子的 margin 不会与外面的合并
  • BFC 不会和浮动元素重叠
Flex Box (用的最多)

一种新的排版上下文

它可以控制子级盒子的:

  • 摆放的流向 ( → ← ↑ ↓ )

flex-direction

  • 摆放顺序

order 属性 设置或检索弹性盒模型对象的子元素出现的順序

注意:如果元素不是弹性盒对象的元素,则 order 属性不起作用

  • 盒子宽度和高度
  • 水平和垂直方向的对齐

主轴的对齐 justify-content (默认值为flex-start)

副轴的对齐 align-items (默认值为stretch)

align-self 属性定义flex子项单独在副轴方向上的对齐方式

  • 是否允许折行
Flexibility

可以设置子项的弹性:当容器有剩余空间时,会伸展;容器空间不够时,会收缩。

  • flex-grow 有剩余空间时的伸展能力
  • flex-shrink 容器空间不足时收缩的能力
  • flex-basis 没有伸展或收缩时的基础长度
缩写 flex
 flex: 1         
 flex-grow: 1
 ​
 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
Grid布局 (强大)

Flex理解为一维的布局, Grid理解为二维的布局

  • display: grid 使元素生成一个块级的 Grid 容器
  • 使用 grid-template 相关属性将容器划分为网格
 grid-template-columns: 100px 100px 200px;
 grid-template-rows: 100px 100px
 grid-template-columns: 30% 30% auto;
 grid-template-rows: 100px auto
 grid-template-columns: 100px 1fr 1fr;
 grid-template-rows: 100px 1fr
  • 设置每一个子项占哪些行/列
 .a {
   grid-row-start: 1;
   grid-column-start: 1;
   grid-row-end: 3;
   grid-column-end: 3;
 }
 .a {
   grid-area: 2/2/4/4;
 }
 .b {
   grid-area: 1/1/3/3;
 }

单位fr: 一份

如 grid-template-columns: 100px 1fr 1fr; 中fr等于减去100px再除以二

float 浮动

在有Flex和Grid布局之后, float一般只在图文情况下用, 不再用于实现左右布局等

position ⭐

static

默认值, 非定位元素

relative

相对于自身原本位置偏移, 不脱离文档流

  • 在常规流里面布局 (即常规流中其他元素当它在原来该在的位置布局)
  • 相对于自己本应该在的位置进行偏移
  • 使用top, left, bottom, right设置偏移长度
  • 流内其他元素当它没有偏移一样布局
absolute

绝对定位, 相对于非static祖先定位

  • 脱离常规流 (即常规流中其他元素当它不存在)
  • 相对于最近的非static祖先定位
  • 不会对流内元素布局造成影响
fixed

相对于视口定位

sticky

粘性定位的元素是依赖于用户的滚动,在 position:relativeposition:fixed 定位之间切换

当页面滚动未超出目标区域时, 未relative, 超出时, 未fixed

学习CSS的几点建议

  • 充分利用MDN和W3C CSS规范
  • 保持好奇心, 善用浏览器的开发者工具
  • 持续学习, CSS新特性还在不断出现