(二)CSS专题 | 青训营笔记

227 阅读8分钟

“这是我参与「第五届青训营」伴学笔记创作活动的第 2 天”

主要内容

  1. 什么是CSS?
  2. 如何使用CSS?
  3. CSS的工作原理和求值过程
  4. CSS的选择器Selector
  5. CSS里的颜色与文字样式
  6. 层叠与继承
  7. 盒模型——组成、外边距塌陷、content-box&border-box、overflow
  8. 布局——常规流(IFC、BFC、Table、Flex、Grid)、浮动、绝对定位

1 走进前端技术栈 - CSS

1.1 CSS是什么?

  • Cascading Style Sheets
  • 用来定义页面元素的样式
    • 设置字体和颜色
    • 添加位置和大小
    • 添加动画效果

1.2 在页面中使用CSS

<!-- 外链(推荐——内容与样式分离) -->
<link rel="stylesheet" href="/assets/style.css">
<!-- 嵌入 -->
<style>
  li { margin: 0; list-style: none; }
  p { margin: 1em 0; }
</style>
<!-- 内联 -->
<p style="margin:1em 0">Example Content</p>

1.3 CSS是如何工作的?

flowchart LR
id1(加载HTML) --> id2(解析HTML)
id2(解析HTML) --> id3(加载CSS)
id3(加载CSS) --> id4(解析CSS)
id2(解析HTML) --> id5(创建DOM树)
id5(创建DOM树) --> id6(展示页面)
id4(解析CSS) -- 添加样式到DOM节点形成渲染树 --> id5(创建DOM树)

1.4 调试CSS

  • 右键 -> 检查
  • 快捷键
    • Ctrl + Shift + I (Windows)
    • Cmd + Opt + I (Mac)

1.5 CSS求值过程

image.png

2 选择器

选择器Selector {
  [选择器Property: 属性值Value] => 声明Declaration
}
h1 {
  color: white;
  font-size: 14px;
}

2.1 通配选择器

对页面中所有元素生效。

* {
  color: red;
  font-size: 20px;
}

2.2 标签选择器

h1 { color: orange; }
p { color: gray; font-size: 20px; }

2.3 id选择器

id是一个唯一的值。

#logo {
    font-size: 60px;
    font-weight: 200;
}

2.4 类选择器

对同一类型的元素设置样式,可以出现多次。

.done {
  color: gray;
  text-decoration: line-through;
}

2.5 属性选择器

  • 案例一:对具有disabled属性的元素设置样式
    <label>用户名:</label>
    <input value="zhao" disabled />
    
    <label>密码:</label>
    <input value="123456" type="password" />
    
    <style>
      [disabled] {
        background: #eee;
        color: #999;
      }
    </style>
    
  • 案例二:对标签为input且属性type="password"的元素设置样式
    input[type="password"] {
      border-color: red;
      color: red;
    }
    
  • 案例三:对属性匹配规则,而非严格等于某个值
    a[href^="#"] { color: #f54767; } /* 以#开头 */
    a[href$=".jpg"] { color: deepskyblue; } /* 以.jpg结尾 */
    

2.6 伪类(pseudo-classes)

2.6.1 状态伪类

<a href="http://example.com">
  example.com
</a>

<label>
  用户名:
  <input type="text">
</label>

<style>
a:link { color: black; } /* 未访问的链接 */

a:visited { color: gray; } /* 已访问的链接 */

a:hover { color: orange; } /* 鼠标悬停的链接 */

a:active { color: red; } /* 鼠标按下后的链接 */

:focus { outline: 2px solid orange; } /* 对input输入框和链接a均生效 */
</style>

2.6.2 结构性伪类

根据元素在DOM树中的位置。

<ol>
  <li>阿凡达</li>
  <li>泰坦尼克号</li>
  <li>星球大战:原力觉醒</li>
  <li>复仇者联盟 3</li>
  <li>侏罗纪世界</li>
</ol>

<style>
li {
  list-style-position: inside;
  border-bottom: 1px solid;
  padding: 0.5em
}
li:first-child { color: coral }
li:last-child { border-bottom: none; }
</style>

2.7 组合(Combinations)

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

2.8 选择器组

用逗号隔开,样式对所列选择器均生效

body, h1, h2, ul, ol, li {
  margin: 0;
  padding: 0;
}

[type="checkbox"], [type="radio"] {
  box-sizing: border-box;
  padding: 0;
}

3 样式

3.1 颜色

3.2 字体

font: style weight size/height family

3.2.1 font-family

  • 通用字体族 image.png
  • Web Fonts
    • 对字体包进行裁切,只留下用到的字符,保证字体文件相对较小
    <style>
      @font-face {
        font-family: "Megrim";
        src: url(https://fonts.gstatic.com/s/megrim/v11/46kulbz5WjvLqJZVam_hVUdI1w.woff2) format('woff2');
      }
       @font-face {
        font-family: f1;
        src: url("//s2.ssl.qhimg.com/static/ff00cb8151eeecd2.woff2") format("woff2");
      }
    
      h1 { font-family: Megrim, Cursive; }
      p { font-family: f1, serif; }
    </style>
    
  • 使用建议
    • 字体列表最后写上通用字体族
    • 英文字体放在中文字体前面

3.2.2 font-size

  • 关键字:small, medium, large
  • 长度:px, em
    • em:相对单位
  • 百分数:相对父元素字体大小

3.2.3 font-style

  • normal
  • italic(斜体)

3.2.4 font-weight

  • 取值:100200、……、900
  • 关键字:normalbold

3.2.5 line-height

  • 长度
  • 倍数 image.png

3.2.6 其他文本样式

  • text-align
    • 左对齐:left
    • 右对齐:right
    • 居中对齐:center
    • 两端对齐:justify
  • spacing
    • 字符间距:letter-spacing
    • 单词间距:word-spacing
  • text-indent(首行缩进)
  • text-decoration(文字修饰)
    • 无(默认):none
    • 下划线:underline
    • 删除线:line-through
    • 上划线:overline
  • white-space
    • 默认行为:normal
      • 通常HTML里多个换行/空白符会被合并成一个
    • 强制不换行:nowrap
    • 保留所有的空格和换行:pre
      • 和原始代码中文本一致
    • 保留空格,一行内显示不全时自动换行:pre-wrap
    • 合并空格,保留空行:pre-line

4 优先级 —— 哪条规则生效?

4.1 选择器的特异度(Specificity)

  • #id > .class((伪)类) > E(标签)

4.2 继承

某些属性会自动继承父元素的计算值,除非显式指定一个值。一般文字相关的属性(例如颜色、字体大小)可继承,但盒模型相关的属性(例如宽度)不可继承。

<p>This is a <em>test</em> of <strong>inherit</strong></p>

<style>
  body { font-size: 20px; }
  p { color: blue; }
  em { color: red; }
</style>
  • 显式继承
    * { box-sizing: inherit; }
    html { box-sizing: border-box; }
    .some-widget { box-sizing: content-box; }
    
  • 初始值
    • CSS中每个属性都有一个初始值
      • background初始值:transparent
      • margin-left初始值:0
    • 可以使用initial关键字显式重置为初始值
      • background-color: initial

5 布局Layout

  • 确定内容大小和位置的算法
  • 依据元素、容器、兄弟节点和内容等信息来计算
  • 相关技术:
    • 常规流
      • 行级
      • 块级
      • 表格布局
      • FlexBox
      • Grid布局
    • 浮动
    • 绝对定位

5.1 宽和高(content-box)

image.png

5.1.1 width

  • 指定content box宽度
  • 取值为长度、百分数、auto
  • auto由浏览器根据其他属性确定
  • 百分数相对容器的content box宽度

5.1.2 height

  • 指定content box高度
  • 取值为长度、百分数、auto
  • auto取值由内容计算得来
  • 百分数相对容器的content box高度
  • 容器有指定的高度时,百分数才生效

5.2 边距

image.png

5.2.1 内边距padding

  • 百分数相对于容器宽度

image.png

5.2.2 边框border

  • 三种属性border: 1px solid #ccc
    • border-width
    • border-stylesolid, dotted, dashed
    • border-color
  • 四个方向
    • border-top
    • border-right
    • border-bottom
    • border-left

5.2.3 外边距margin

  • 百分数相对于容器宽度
  • 使用margin: auto水平居中
    <div></div>
    
    <style>
      div {
        width: 200px;
        height: 200px;
        background: coral;
        margin-left: auto;
        margin-right: auto;
      }
    </style>
    
  • 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>
    

5.2.4 box-sizing: border-box(更常用)

image.png

5.2.5 overflow

用于控制溢出的内容。

  • visible:默认展示
  • hidden:隐藏溢出部分
  • scroll:生成滚动条
  • auto:仅在溢出时滚动 看到ppt第23页了

5.3 块级(block)vs行级(inline)

  • 块级block
    • 不和其他盒子并列摆放
    • 适用所有的盒模型属性
    • bodyarticledivmainsectionh1~h6pulli
  • 行级inline
    • 和其他行级盒子一起放在一行或拆开成多行
    • 盒模型中的widthheight不适用
    • spanemstrongcitecode
  • inline-block
    • 本身是行级,可以放在行盒中
    • 可以设置宽高
    • 作为一个整体不会被拆散成多行
  • none排版时完全被忽略

5.4 常规流Normal Flow

常规流中的盒子,在某种排版上下文中参与布局

5.4.1 行级排版上下文(IFC, Inline Formatting Context)

  • 只包含行级盒子的容器
  • IFC内的排版规则:
    • 盒子在一行内水平摆放
    • 一行放不下时,换行显示
    • text-align决定一行内盒子的水平对齐
    • vertical-align绝对一个盒子在行内的垂直对齐
    • 避开浮动float元素*

5.4.2 块级排版上下文(BFC)

  • 某些容器会创建一个BFC
    • 根元素
    • 浮动、绝对定位、inline-block
    • Flex子项和Grid子项
    • overflow值不是visible的块盒
    • display: flow-root;
  • BFC内的排版规则:
    • 盒子从上到下摆放
    • 垂直margin合并
    • BFC内的盒子的margin不会与外面的合并
    • BFC不会和浮动元素重叠

5.4.3 Flex Box

  • 一种新的排版上下文
  • 它可以控制子级盒子的:
    • 摆放流向
    • 摆放顺序
    • 盒子宽高
    • 水平和垂直方向的对齐
    • 是否允许拆行
  • flex-direction
    • 自左向右row -> 主轴方向
    • 自右向左row-reverse
    • 自上而下column -> 侧轴方向
    • 自下而上column-reverse
  • justify-content image.png
  • align-items image.png
  • align-self:给某个元素设置特殊的对齐 image.png
  • order image.png

Flexibility

  • 可以设置子项的弹性:当容器有剩余空间时,会伸展;容器空间不够时,会收缩。
  • flex-grow有剩余空间时的伸展能力(剩余的空间按照规定的比例再分配)
  • flex-shrink容器空间不足时收缩的能力(0:刚性、不收缩)
  • 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 |

5.4.4 Grid布局

  • Flex是单一维度的布局模式,Grid是二维布局
  • display: grid使元素生成一个块级的Grid容器
  • 使用grid-template相关属性将容器划分为网格
  • 设置每一个子项占哪些行/列

CodePen - 青训营/CSS/grid-template (cdpn.io)(fr = fraction)

网格线Grid Line

在页面中是看不出来的,可以使用浏览器的开发者工具来检查。 image.png

网格区域Grid Area

  • 借助网格线划分出的区域
/* 两种等价的表示形式 */
.a {
  grid-row-start: 1;
  grid-column-start: 1;
  grid-row-end: 3;
  grid-column-end: 3;
}
.a {
  grid-area: 1/1/3/3;
}

5.3 float浮动

可以实现图片的文字环绕效果。在Flex Box和Grid之前主要使用float来实现布局效果,现在可以不用过多关注清除浮动等概念。

  • float: left;
  • float: right;

5.4 position属性

  • static:默认值,非定位元素
  • relative:相对定位
    • 相对自身原本应该在的位置偏移
    • 不脱离文档流
    • 对其它元素无影响
  • absolute:绝对定位
    • 相对最近的非static祖先元素定位
    • 脱离常规流
    • 不对流内元素布局造成影响
  • fixed:相对视口绝对定位
  • 通过topbottomleftright属性设置偏移长度。